Skip to content

Commit 98c61b6

Browse files
authored
Rollup merge of #92333 - compiler-errors:elided-lifetime-spans, r=cjgillot
Tighten span when suggesting lifetime on path This is kind of a hack. Really the issue here is that we want to suggest the segment's span if the path resolves to something defined outside of the macro, and the macro's span if it resolves to something defined within.. I'll look into seeing if we can do something like that. Fixes #92324 r? `@cjgillot`
2 parents 9aaa61b + e37d012 commit 98c61b6

File tree

5 files changed

+89
-7
lines changed

5 files changed

+89
-7
lines changed

compiler/rustc_ast_lowering/src/path.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
277277
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
278278
let elided_lifetime_span = if generic_args.span.is_empty() {
279279
// If there are no brackets, use the identifier span.
280-
path_span
280+
// HACK: we use find_ancestor_inside to properly suggest elided spans in paths
281+
// originating from macros, since the segment's span might be from a macro arg.
282+
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
281283
} else if generic_args.is_empty() {
282284
// If there are brackets, but not generic arguments, then use the opening bracket
283285
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))

compiler/rustc_resolve/src/late/diagnostics.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -2115,10 +2115,13 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
21152115
let spans_suggs: Vec<_> = formatters
21162116
.into_iter()
21172117
.zip(spans_with_counts.iter())
2118-
.filter_map(|(fmt, (span, _))| {
2119-
if let Some(formatter) = fmt { Some((formatter, span)) } else { None }
2118+
.filter_map(|(formatter, (span, _))| {
2119+
if let Some(formatter) = formatter {
2120+
Some((*span, formatter(name)))
2121+
} else {
2122+
None
2123+
}
21202124
})
2121-
.map(|(formatter, span)| (*span, formatter(name)))
21222125
.collect();
21232126
if spans_suggs.is_empty() {
21242127
// If all the spans come from macros, we cannot extract snippets and then
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![feature(generic_associated_types)]
2+
#![allow(unused)]
3+
4+
trait Trait<'a> {
5+
type Foo;
6+
7+
type Bar<'b>
8+
//~^ NOTE associated type defined here, with 1 lifetime parameter
9+
//~| NOTE
10+
where
11+
Self: 'b;
12+
}
13+
14+
struct Impl<'a>(&'a ());
15+
16+
impl<'a> Trait<'a> for Impl<'a> {
17+
type Foo = &'a ();
18+
type Bar<'b> = &'b ();
19+
}
20+
21+
type A<'a> = Impl<'a>;
22+
23+
type B<'a> = <A<'a> as Trait>::Foo;
24+
//~^ ERROR missing lifetime specifier
25+
//~| NOTE expected named lifetime parameter
26+
27+
type C<'a, 'b> = <A<'a> as Trait>::Bar;
28+
//~^ ERROR missing lifetime specifier
29+
//~| ERROR missing generics for associated type
30+
//~| NOTE expected named lifetime parameter
31+
//~| NOTE these named lifetimes are available to use
32+
//~| NOTE expected 1 lifetime argument
33+
34+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/missing-lifetime-in-alias.rs:23:24
3+
|
4+
LL | type B<'a> = <A<'a> as Trait>::Foo;
5+
| ^^^^^ expected named lifetime parameter
6+
|
7+
help: consider using the `'a` lifetime
8+
|
9+
LL | type B<'a> = <A<'a> as Trait<'a>>::Foo;
10+
| ~~~~~~~~~
11+
12+
error[E0106]: missing lifetime specifier
13+
--> $DIR/missing-lifetime-in-alias.rs:27:28
14+
|
15+
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
16+
| ^^^^^ expected named lifetime parameter
17+
|
18+
note: these named lifetimes are available to use
19+
--> $DIR/missing-lifetime-in-alias.rs:27:8
20+
|
21+
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
22+
| ^^ ^^
23+
24+
error[E0107]: missing generics for associated type `Trait::Bar`
25+
--> $DIR/missing-lifetime-in-alias.rs:27:36
26+
|
27+
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
28+
| ^^^ expected 1 lifetime argument
29+
|
30+
note: associated type defined here, with 1 lifetime parameter: `'b`
31+
--> $DIR/missing-lifetime-in-alias.rs:7:10
32+
|
33+
LL | type Bar<'b>
34+
| ^^^ --
35+
help: add missing lifetime argument
36+
|
37+
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar<'a>;
38+
| ~~~~~~~
39+
40+
error: aborting due to 3 previous errors
41+
42+
Some errors have detailed explanations: E0106, E0107.
43+
For more information about an error, try `rustc --explain E0106`.

src/test/ui/lint/reasons.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
warning: hidden lifetime parameters in types are deprecated
2-
--> $DIR/reasons.rs:20:29
2+
--> $DIR/reasons.rs:20:34
33
|
44
LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
5-
| ^^^^^^^^^^^^^^ expected named lifetime parameter
5+
| ^^^^^^^^^ expected named lifetime parameter
66
|
77
= note: explicit anonymous lifetimes aid reasoning about ownership
88
note: the lint level is defined here
@@ -13,7 +13,7 @@ LL | #![warn(elided_lifetimes_in_paths,
1313
help: consider using the `'_` lifetime
1414
|
1515
LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
16-
| ~~~~~~~~~~~~~~~~~~
16+
| ~~~~~~~~~~~~~
1717

1818
warning: variable `Social_exchange_psychology` should have a snake case name
1919
--> $DIR/reasons.rs:30:9

0 commit comments

Comments
 (0)