Skip to content

Commit

Permalink
Rollup merge of #92333 - compiler-errors:elided-lifetime-spans, r=cjg…
Browse files Browse the repository at this point in the history
…illot

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`
  • Loading branch information
matthiaskrgr authored Dec 28, 2021
2 parents 9aaa61b + e37d012 commit 98c61b6
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 7 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 34 additions & 0 deletions src/test/ui/in-band-lifetimes/missing-lifetime-in-alias.rs
Original file line number Diff line number Diff line change
@@ -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() {}
43 changes: 43 additions & 0 deletions src/test/ui/in-band-lifetimes/missing-lifetime-in-alias.stderr
Original file line number Diff line number Diff line change
@@ -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`.
6 changes: 3 additions & 3 deletions src/test/ui/lint/reasons.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down

0 comments on commit 98c61b6

Please sign in to comment.