From d5113efac3380874b6f22cb8c1698fce90dabdfc Mon Sep 17 00:00:00 2001 From: Veera Date: Sat, 30 Mar 2024 14:56:42 -0400 Subject: [PATCH 1/2] Add tests --- ...etime-for-associated-types-issue-122025.rs | 28 ++++++++++ ...e-for-associated-types-issue-122025.stderr | 55 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.rs create mode 100644 tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.stderr diff --git a/tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.rs b/tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.rs new file mode 100644 index 0000000000000..4db51ec1dd8e4 --- /dev/null +++ b/tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.rs @@ -0,0 +1,28 @@ +struct MyType; + +fn foo() +where + F: Iterator, //~ `&` without an explicit lifetime name cannot be used here +{ +} + +fn bar() { + fn baz() + where + F: Iterator, //~ `&` without an explicit lifetime name cannot be used here + { + } +} + +fn function() +where + T: Iterator, //~ `&` without an explicit lifetime name cannot be used here +{ + fn lambda() + where + A: Iterator, //~ `&` without an explicit lifetime name cannot be used here + { + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.stderr b/tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.stderr new file mode 100644 index 0000000000000..735f080c59e87 --- /dev/null +++ b/tests/ui/lifetimes/suggest-explicit-lifetime-for-associated-types-issue-122025.stderr @@ -0,0 +1,55 @@ +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/suggest-explicit-lifetime-for-associated-types-issue-122025.rs:5:24 + | +LL | F: Iterator, + | ^ explicit lifetime name needed here + | +help: consider adding an explicit lifetime here + | +LL ~ fn foo<'a, F>() +LL | where +LL ~ F: Iterator, + | + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/suggest-explicit-lifetime-for-associated-types-issue-122025.rs:12:28 + | +LL | F: Iterator, + | ^ explicit lifetime name needed here + | +help: consider adding an explicit lifetime here + | +LL ~ fn baz<'a, F>() +LL | where +LL ~ F: Iterator, + | + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/suggest-explicit-lifetime-for-associated-types-issue-122025.rs:19:24 + | +LL | T: Iterator, + | ^ explicit lifetime name needed here + | +help: consider adding an explicit lifetime here + | +LL ~ fn function<'a, T>() +LL | where +LL ~ T: Iterator, + | + +error[E0637]: `&` without an explicit lifetime name cannot be used here + --> $DIR/suggest-explicit-lifetime-for-associated-types-issue-122025.rs:23:28 + | +LL | A: Iterator, + | ^ explicit lifetime name needed here + | +help: consider adding an explicit lifetime here + | +LL ~ fn lambda<'a, A>() +LL | where +LL ~ A: Iterator, + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0637`. From 169b379392d9129cdbabdefb4043bee9bbbc9aca Mon Sep 17 00:00:00 2001 From: Veera Date: Sat, 30 Mar 2024 15:19:17 -0400 Subject: [PATCH 2/2] Suggest Explicit Lifetime for Associated Type Bindings --- compiler/rustc_resolve/src/late.rs | 56 +++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 49b4a6efd3c3e..eb1951919dada 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1634,7 +1634,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { #[instrument(level = "debug", skip(self))] fn resolve_anonymous_lifetime(&mut self, lifetime: &Lifetime, elided: bool) { debug_assert_eq!(lifetime.ident.name, kw::UnderscoreLifetime); - let kind = if elided { MissingLifetimeKind::Ampersand } else { MissingLifetimeKind::Underscore }; let missing_lifetime = @@ -1685,14 +1684,53 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { .. } = &rib.kind { - diag.multipart_suggestion( - "consider introducing a higher-ranked lifetime here", - vec![ - (span.shrink_to_lo(), "for<'a> ".into()), - (lifetime.ident.span.shrink_to_hi(), "'a ".into()), - ], - Applicability::MachineApplicable, - ); + // hacky way to check if lifetime suggestion is for + // an associated type binding + let is_associated_type_binding = lifetime.ident.span + != self.r.tcx.sess.source_map().span_extend_to_prev_char( + lifetime.ident.span, + '=', + false, + ); + if is_associated_type_binding { + for upper_rib in self.lifetime_ribs[0..i].iter().rev() { + if let LifetimeRibKind::Generics { + kind: LifetimeBinderKind::Function, + span: function_span, + .. + } = upper_rib.kind + { + let type_parameter_span = self + .r + .tcx + .sess + .source_map() + .span_through_char(function_span, '<') + .shrink_to_hi(); + diag.multipart_suggestion( + "consider adding an explicit lifetime here", + vec![ + (type_parameter_span, "'a, ".into()), + ( + lifetime.ident.span.shrink_to_hi(), + "'a ".into(), + ), + ], + Applicability::MaybeIncorrect, + ); + break; + } + } + } else { + diag.multipart_suggestion( + "consider introducing a higher-ranked lifetime here", + vec![ + (span.shrink_to_lo(), "for<'a> ".into()), + (lifetime.ident.span.shrink_to_hi(), "'a ".into()), + ], + Applicability::MachineApplicable, + ); + } break; } }