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`
This commit is contained in:
commit
98c61b673e
5 changed files with 89 additions and 7 deletions
|
@ -277,7 +277,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
|
||||
let elided_lifetime_span = if generic_args.span.is_empty() {
|
||||
// If there are no brackets, use the identifier span.
|
||||
path_span
|
||||
// HACK: we use find_ancestor_inside to properly suggest elided spans in paths
|
||||
// originating from macros, since the segment's span might be from a macro arg.
|
||||
segment.ident.span.find_ancestor_inside(path_span).unwrap_or(path_span)
|
||||
} else if generic_args.is_empty() {
|
||||
// If there are brackets, but not generic arguments, then use the opening bracket
|
||||
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
|
||||
|
|
|
@ -2115,10 +2115,13 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
|||
let spans_suggs: Vec<_> = formatters
|
||||
.into_iter()
|
||||
.zip(spans_with_counts.iter())
|
||||
.filter_map(|(fmt, (span, _))| {
|
||||
if let Some(formatter) = fmt { Some((formatter, span)) } else { None }
|
||||
.filter_map(|(formatter, (span, _))| {
|
||||
if let Some(formatter) = formatter {
|
||||
Some((*span, formatter(name)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|(formatter, span)| (*span, formatter(name)))
|
||||
.collect();
|
||||
if spans_suggs.is_empty() {
|
||||
// If all the spans come from macros, we cannot extract snippets and then
|
||||
|
|
34
src/test/ui/in-band-lifetimes/missing-lifetime-in-alias.rs
Normal file
34
src/test/ui/in-band-lifetimes/missing-lifetime-in-alias.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
#![feature(generic_associated_types)]
|
||||
#![allow(unused)]
|
||||
|
||||
trait Trait<'a> {
|
||||
type Foo;
|
||||
|
||||
type Bar<'b>
|
||||
//~^ NOTE associated type defined here, with 1 lifetime parameter
|
||||
//~| NOTE
|
||||
where
|
||||
Self: 'b;
|
||||
}
|
||||
|
||||
struct Impl<'a>(&'a ());
|
||||
|
||||
impl<'a> Trait<'a> for Impl<'a> {
|
||||
type Foo = &'a ();
|
||||
type Bar<'b> = &'b ();
|
||||
}
|
||||
|
||||
type A<'a> = Impl<'a>;
|
||||
|
||||
type B<'a> = <A<'a> as Trait>::Foo;
|
||||
//~^ ERROR missing lifetime specifier
|
||||
//~| NOTE expected named lifetime parameter
|
||||
|
||||
type C<'a, 'b> = <A<'a> as Trait>::Bar;
|
||||
//~^ ERROR missing lifetime specifier
|
||||
//~| ERROR missing generics for associated type
|
||||
//~| NOTE expected named lifetime parameter
|
||||
//~| NOTE these named lifetimes are available to use
|
||||
//~| NOTE expected 1 lifetime argument
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,43 @@
|
|||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-in-alias.rs:23:24
|
||||
|
|
||||
LL | type B<'a> = <A<'a> as Trait>::Foo;
|
||||
| ^^^^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider using the `'a` lifetime
|
||||
|
|
||||
LL | type B<'a> = <A<'a> as Trait<'a>>::Foo;
|
||||
| ~~~~~~~~~
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-in-alias.rs:27:28
|
||||
|
|
||||
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
|
||||
| ^^^^^ expected named lifetime parameter
|
||||
|
|
||||
note: these named lifetimes are available to use
|
||||
--> $DIR/missing-lifetime-in-alias.rs:27:8
|
||||
|
|
||||
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
|
||||
| ^^ ^^
|
||||
|
||||
error[E0107]: missing generics for associated type `Trait::Bar`
|
||||
--> $DIR/missing-lifetime-in-alias.rs:27:36
|
||||
|
|
||||
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
|
||||
| ^^^ expected 1 lifetime argument
|
||||
|
|
||||
note: associated type defined here, with 1 lifetime parameter: `'b`
|
||||
--> $DIR/missing-lifetime-in-alias.rs:7:10
|
||||
|
|
||||
LL | type Bar<'b>
|
||||
| ^^^ --
|
||||
help: add missing lifetime argument
|
||||
|
|
||||
LL | type C<'a, 'b> = <A<'a> as Trait>::Bar<'a>;
|
||||
| ~~~~~~~
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0107.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
|
@ -1,8 +1,8 @@
|
|||
warning: hidden lifetime parameters in types are deprecated
|
||||
--> $DIR/reasons.rs:20:29
|
||||
--> $DIR/reasons.rs:20:34
|
||||
|
|
||||
LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
| ^^^^^^^^^^^^^^ expected named lifetime parameter
|
||||
| ^^^^^^^^^ expected named lifetime parameter
|
||||
|
|
||||
= note: explicit anonymous lifetimes aid reasoning about ownership
|
||||
note: the lint level is defined here
|
||||
|
@ -13,7 +13,7 @@ LL | #![warn(elided_lifetimes_in_paths,
|
|||
help: consider using the `'_` lifetime
|
||||
|
|
||||
LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
| ~~~~~~~~~~~~~
|
||||
|
||||
warning: variable `Social_exchange_psychology` should have a snake case name
|
||||
--> $DIR/reasons.rs:30:9
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue