Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tighten span when suggesting lifetime on path #92333

Merged
merged 1 commit into from
Dec 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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