@@ -2073,47 +2073,85 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
2073
2073
continue;
2074
2074
}
2075
2075
});
2076
- let span_unnamed_borrow = |span: Span| {
2077
- let lo = span.lo() + BytePos(1);
2078
- span.with_lo(lo).with_hi(lo)
2079
- };
2080
- let span_underscore_borrow = |span: Span| {
2081
- let lo = span.lo() + BytePos(1);
2082
- let hi = lo + BytePos(2);
2083
- span.with_lo(lo).with_hi(hi)
2084
- };
2085
- let unnamed_borrow =
2086
- |snippet: &str| snippet.starts_with('&') && !snippet.starts_with("&'");
2076
+
2077
+ struct Lifetime(Span, String);
2078
+ impl Lifetime {
2079
+ fn is_unnamed(&self) -> bool {
2080
+ self.1.starts_with('&') && !self.1.starts_with("&'")
2081
+ }
2082
+ fn is_underscore(&self) -> bool {
2083
+ self.1.starts_with("&'_ ")
2084
+ }
2085
+ fn is_named(&self) -> bool {
2086
+ self.1.starts_with("&'")
2087
+ }
2088
+ fn suggestion(&self, sugg: String) -> Option<(Span, String)> {
2089
+ Some(
2090
+ match (
2091
+ self.is_unnamed(),
2092
+ self.is_underscore(),
2093
+ self.is_named(),
2094
+ sugg.starts_with("&"),
2095
+ ) {
2096
+ (true, _, _, false) => (self.span_unnamed_borrow(), sugg),
2097
+ (true, _, _, true) => {
2098
+ (self.span_unnamed_borrow(), sugg[1..].to_string())
2099
+ }
2100
+ (_, true, _, false) => {
2101
+ (self.span_underscore_borrow(), sugg.trim().to_string())
2102
+ }
2103
+ (_, true, _, true) => {
2104
+ (self.span_underscore_borrow(), sugg[1..].trim().to_string())
2105
+ }
2106
+ (_, _, true, false) => {
2107
+ (self.span_named_borrow(), sugg.trim().to_string())
2108
+ }
2109
+ (_, _, true, true) => {
2110
+ (self.span_named_borrow(), sugg[1..].trim().to_string())
2111
+ }
2112
+ _ => return None,
2113
+ },
2114
+ )
2115
+ }
2116
+ fn span_unnamed_borrow(&self) -> Span {
2117
+ let lo = self.0.lo() + BytePos(1);
2118
+ self.0.with_lo(lo).with_hi(lo)
2119
+ }
2120
+ fn span_named_borrow(&self) -> Span {
2121
+ let lo = self.0.lo() + BytePos(1);
2122
+ self.0.with_lo(lo)
2123
+ }
2124
+ fn span_underscore_borrow(&self) -> Span {
2125
+ let lo = self.0.lo() + BytePos(1);
2126
+ let hi = lo + BytePos(2);
2127
+ self.0.with_lo(lo).with_hi(hi)
2128
+ }
2129
+ }
2130
+
2087
2131
for param in params {
2088
2132
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) {
2089
- if unnamed_borrow(&snippet) {
2090
- let span = span_unnamed_borrow(param.span);
2091
- introduce_suggestion.push((span, "'a ".to_string()));
2092
- } else if snippet.starts_with("&'_ ") {
2093
- let span = span_underscore_borrow(param.span);
2094
- introduce_suggestion.push((span, "'a".to_string()));
2133
+ if let Some((span, sugg)) =
2134
+ Lifetime(param.span, snippet).suggestion("'a ".to_string())
2135
+ {
2136
+ introduce_suggestion.push((span, sugg));
2095
2137
}
2096
2138
}
2097
2139
}
2098
2140
for (span, sugg) in spans_with_counts.iter().copied().zip(suggs.iter()).filter_map(
2099
- |((span, _), sugg)| match sugg {
2100
- Some(sugg) => Some((span, sugg)),
2141
+ |((span, _), sugg)| match & sugg {
2142
+ Some(sugg) => Some((span, sugg.to_string() )),
2101
2143
_ => None,
2102
2144
},
2103
2145
) {
2104
- match self.tcx.sess.source_map().span_to_snippet(span) {
2105
- Ok(snippet) if unnamed_borrow(&snippet) && sugg.starts_with("&") => {
2106
- let span = span_unnamed_borrow(span);
2107
- introduce_suggestion.push((span, sugg[1..].to_string()));
2108
- }
2109
- Ok(snippet) if snippet.starts_with("&'_ ") && sugg.starts_with("&") => {
2110
- let span = span_underscore_borrow(span);
2111
- introduce_suggestion.push((span, sugg[1..].to_string()));
2112
- }
2113
- _ => {
2114
- introduce_suggestion.push((span, sugg.to_string()));
2115
- }
2116
- }
2146
+ let (span, sugg) = self
2147
+ .tcx
2148
+ .sess
2149
+ .source_map()
2150
+ .span_to_snippet(span)
2151
+ .ok()
2152
+ .and_then(|snippet| Lifetime(span, snippet).suggestion(sugg.clone()))
2153
+ .unwrap_or((span, sugg));
2154
+ introduce_suggestion.push((span, sugg.to_string()));
2117
2155
}
2118
2156
err.multipart_suggestion_with_style(
2119
2157
&msg,
0 commit comments