Skip to content

Commit 14add46

Browse files
committed
Use more accurate spans when proposing adding lifetime to item
1 parent 679dea4 commit 14add46

17 files changed

+62
-37
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,16 +2076,40 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
20762076
for param in params {
20772077
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) {
20782078
if snippet.starts_with('&') && !snippet.starts_with("&'") {
2079-
introduce_suggestion
2080-
.push((param.span, format!("&'a {}", &snippet[1..])));
2081-
} else if let Some(stripped) = snippet.strip_prefix("&'_ ") {
2082-
introduce_suggestion.push((param.span, format!("&'a {}", &stripped)));
2079+
let lo = param.span.lo() + BytePos(1);
2080+
let span = param.span.with_lo(lo).with_hi(lo);
2081+
introduce_suggestion.push((span, "'a ".to_string()));
2082+
} else if let Some(_) = snippet.strip_prefix("&'_ ") {
2083+
let lo = param.span.lo() + BytePos(1);
2084+
let hi = lo + BytePos(2);
2085+
let span = param.span.with_lo(lo).with_hi(hi);
2086+
introduce_suggestion.push((span, "'a".to_string()));
20832087
}
20842088
}
20852089
}
20862090
for ((span, _), sugg) in spans_with_counts.iter().copied().zip(suggs.iter()) {
2087-
if let Some(sugg) = sugg {
2088-
introduce_suggestion.push((span, sugg.to_string()));
2091+
match (sugg, self.tcx.sess.source_map().span_to_snippet(span)) {
2092+
(Some(sugg), Ok(snippet))
2093+
if snippet.starts_with('&')
2094+
&& !snippet.starts_with("&'")
2095+
&& sugg.starts_with("&") =>
2096+
{
2097+
let lo = span.lo() + BytePos(1);
2098+
let span = span.with_lo(lo).with_hi(lo);
2099+
introduce_suggestion.push((span, sugg[1..].to_string()));
2100+
}
2101+
(Some(sugg), Ok(snippet))
2102+
if snippet.starts_with("&'_ ") && sugg.starts_with("&") =>
2103+
{
2104+
let lo = span.lo() + BytePos(1);
2105+
let hi = lo + BytePos(2);
2106+
let span = span.with_lo(lo).with_hi(hi);
2107+
introduce_suggestion.push((span, sugg[1..].to_string()));
2108+
}
2109+
(Some(sugg), _) => {
2110+
introduce_suggestion.push((span, sugg.to_string()));
2111+
}
2112+
_ => {}
20892113
}
20902114
}
20912115
err.multipart_suggestion_with_style(
@@ -2159,7 +2183,8 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
21592183
for ((span, _), snippet) in spans_with_counts.iter().copied().zip(snippets.iter()) {
21602184
match snippet.as_deref() {
21612185
Some("") => spans_suggs.push((span, "'lifetime, ".to_string())),
2162-
Some("&") => spans_suggs.push((span, "&'lifetime ".to_string())),
2186+
Some("&") => spans_suggs
2187+
.push((span.with_lo(span.lo() + BytePos(1)), "'lifetime ".to_string())),
21632188
_ => {}
21642189
}
21652190
}

src/test/ui/error-codes/E0106.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ LL | type MyStr = &str;
5959
help: consider introducing a named lifetime parameter
6060
|
6161
LL | type MyStr<'a> = &'a str;
62-
| ++++ ~~~
62+
| ++++ ++
6363

6464
error: aborting due to 5 previous errors
6565

src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | type F<T1> = &[u8];
1515
help: consider introducing a named lifetime parameter
1616
|
1717
LL | type F<'a, T1> = &'a [u8];
18-
| +++ ~~~
18+
| +++ ++
1919

2020
error: aborting due to 2 previous errors
2121

src/test/ui/impl-header-lifetime-elision/assoc-type.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | type Output = &i32;
77
help: consider introducing a named lifetime parameter
88
|
99
LL | type Output<'a> = &'a i32;
10-
| ++++ ~~~
10+
| ++++ ++
1111

1212
error[E0106]: missing lifetime specifier
1313
--> $DIR/assoc-type.rs:16:20

src/test/ui/issues/issue-19707.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ LL | type Foo = fn(&u8, &u8) -> &u8;
99
help: consider making the type lifetime-generic with a new `'a` lifetime
1010
|
1111
LL | type Foo = for<'a> fn(&'a u8, &'a u8) -> &'a u8;
12-
| +++++++ ~~~~~~ ~~~~~~ ~~~
12+
| +++++++ ++ ++ ++
1313
help: consider introducing a named lifetime parameter
1414
|
1515
LL | type Foo<'a> = fn(&'a u8, &'a u8) -> &'a u8;
16-
| ++++ ~~~~~~ ~~~~~~ ~~~
16+
| ++++ ++ ++ ++
1717

1818
error[E0106]: missing lifetime specifier
1919
--> $DIR/issue-19707.rs:5:27
@@ -26,11 +26,11 @@ LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
2626
help: consider making the bound lifetime-generic with a new `'a` lifetime
2727
|
2828
LL | fn bar<F: for<'a> Fn(&'a u8, &'a u8) -> &'a u8>(f: &F) {}
29-
| +++++++ ~~~~~~ ~~~~~~ ~~~
29+
| +++++++ ++ ++ ++
3030
help: consider introducing a named lifetime parameter
3131
|
3232
LL | fn bar<'a, F: Fn(&'a u8, &'a u8) -> &'a u8>(f: &F) {}
33-
| +++ ~~~~~~ ~~~~~~ ~~~
33+
| +++ ++ ++ ++
3434

3535
error: aborting due to 2 previous errors
3636

src/test/ui/issues/issue-26638.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.ne
88
help: consider introducing a named lifetime parameter
99
|
1010
LL | fn parse_type<'a>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'a str { iter.next() }
11-
| ++++ ~~~
11+
| ++++ ++
1212

1313
error[E0106]: missing lifetime specifier
1414
--> $DIR/issue-26638.rs:4:40

src/test/ui/issues/issue-30255.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | fn f(a: &S, b: i32) -> &i32 {
88
help: consider introducing a named lifetime parameter
99
|
1010
LL | fn f<'a>(a: &'a S, b: i32) -> &'a i32 {
11-
| ++++ ~~~~~ ~~~
11+
| ++++ ++ ++
1212

1313
error[E0106]: missing lifetime specifier
1414
--> $DIR/issue-30255.rs:14:34
@@ -20,7 +20,7 @@ LL | fn g(a: &S, b: bool, c: &i32) -> &i32 {
2020
help: consider introducing a named lifetime parameter
2121
|
2222
LL | fn g<'a>(a: &'a S, b: bool, c: &'a i32) -> &'a i32 {
23-
| ++++ ~~~~~ ~~~~~~~ ~~~
23+
| ++++ ++ ++ ++
2424

2525
error[E0106]: missing lifetime specifier
2626
--> $DIR/issue-30255.rs:19:44
@@ -32,7 +32,7 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
3232
help: consider introducing a named lifetime parameter
3333
|
3434
LL | fn h<'a>(a: &'a bool, b: bool, c: &'a S, d: &'a i32) -> &'a i32 {
35-
| ++++ ~~~~~~~~ ~~~~~ ~~~~~~~ ~~~
35+
| ++++ ++ ++ ++ ++
3636

3737
error: aborting due to 3 previous errors
3838

src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | fn g(_x: &isize, _y: &isize) -> &isize {
2020
help: consider introducing a named lifetime parameter
2121
|
2222
LL | fn g<'a>(_x: &'a isize, _y: &'a isize) -> &'a isize {
23-
| ++++ ~~~~~~~~~ ~~~~~~~~~ ~~~
23+
| ++++ ++ ++ ++
2424

2525
error[E0106]: missing lifetime specifier
2626
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19
@@ -32,7 +32,7 @@ LL | fn h(_x: &Foo) -> &isize {
3232
help: consider introducing a named lifetime parameter
3333
|
3434
LL | fn h<'a>(_x: &'a Foo) -> &'a isize {
35-
| ++++ ~~~~~~~ ~~~
35+
| ++++ ++ ++
3636

3737
error[E0106]: missing lifetime specifier
3838
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20

src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 {
88
help: consider introducing a named lifetime parameter
99
|
1010
LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
11-
| ++++ ~~~~~~~ ~~~~~~~ ~~~
11+
| ++++ ++ ++ ++
1212

1313
error: aborting due to previous error
1414

src/test/ui/rfc1623-2.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
99
help: consider making the type lifetime-generic with a new `'a` lifetime
1010
|
1111
LL | static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 =
12-
| +++++++ ~~~~~~ ~~~~~~ ~~~
12+
| +++++++ ++ ++ ++
1313

1414
error[E0106]: missing lifetime specifier
1515
--> $DIR/rfc1623-2.rs:10:39
@@ -22,7 +22,7 @@ LL | &(non_elidable as fn(&u8, &u8) -> &u8);
2222
help: consider making the type lifetime-generic with a new `'a` lifetime
2323
|
2424
LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8);
25-
| +++++++ ~~~~~~ ~~~~~~ ~~~
25+
| +++++++ ++ ++ ++
2626

2727
error: aborting due to 2 previous errors
2828

0 commit comments

Comments
 (0)