@@ -768,6 +768,9 @@ pub(crate) struct DiagMetadata<'ast> {
768768 /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
769769 current_where_predicate : Option < & ' ast WherePredicate > ,
770770
771+ /// Whether we are visiting an associated type equality binding like `Trait<Assoc = &T>`.
772+ in_assoc_ty_binding : bool ,
773+
771774 current_type_path : Option < & ' ast Ty > ,
772775
773776 /// The current impl items (used to suggest).
@@ -1327,7 +1330,11 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
13271330 }
13281331 match constraint. kind {
13291332 AssocItemConstraintKind :: Equality { ref term } => match term {
1330- Term :: Ty ( ty) => self . visit_ty ( ty) ,
1333+ Term :: Ty ( ty) => {
1334+ let prev = replace ( & mut self . diag_metadata . in_assoc_ty_binding , true ) ;
1335+ self . visit_ty ( ty) ;
1336+ self . diag_metadata . in_assoc_ty_binding = prev;
1337+ }
13311338 Term :: Const ( c) => {
13321339 self . resolve_anon_const ( c, AnonConstKind :: ConstArg ( IsRepeatExpr :: No ) )
13331340 }
@@ -1927,21 +1934,35 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19271934 }
19281935 LifetimeRibKind :: AnonymousReportError => {
19291936 let guar = if elided {
1930- let suggestion = self . lifetime_ribs [ i..] . iter ( ) . rev ( ) . find_map ( |rib| {
1931- if let LifetimeRibKind :: Generics {
1932- span,
1933- kind : LifetimeBinderKind :: PolyTrait | LifetimeBinderKind :: WhereBound ,
1934- ..
1935- } = rib. kind
1936- {
1937- Some ( crate :: diagnostics:: ElidedAnonymousLifetimeReportErrorSuggestion {
1938- lo : span. shrink_to_lo ( ) ,
1939- hi : lifetime. ident . span . shrink_to_hi ( ) ,
1940- } )
1941- } else {
1942- None
1943- }
1944- } ) ;
1937+ let suggestion = if self . diag_metadata . in_assoc_ty_binding {
1938+ // In an associated type binding like `I: IntoIterator<Item = &T>`,
1939+ // introducing the lifetime on the trait ref would produce
1940+ // `I: for<'a> IntoIterator<Item = &'a T>`. Prefer a named lifetime
1941+ // from an enclosing item instead, so the assoc-ty-binding-specific path
1942+ // below builds that suggestion.
1943+ None
1944+ } else {
1945+ self . lifetime_ribs [ i..] . iter ( ) . rev ( ) . find_map ( |rib| {
1946+ // Look for a `Generics` rib that represents a trait or where-bound
1947+ // binder (`T: Trait<&U>` or `where T: Trait<&U>`), since that is
1948+ // where the generic E0637 diagnostic can insert `for<'a>`.
1949+ if let LifetimeRibKind :: Generics {
1950+ span,
1951+ kind :
1952+ LifetimeBinderKind :: PolyTrait
1953+ | LifetimeBinderKind :: WhereBound ,
1954+ ..
1955+ } = rib. kind
1956+ {
1957+ Some ( crate :: diagnostics:: ElidedAnonymousLifetimeReportErrorSuggestion {
1958+ lo : span. shrink_to_lo ( ) ,
1959+ hi : lifetime. ident . span . shrink_to_hi ( ) ,
1960+ } )
1961+ } else {
1962+ None
1963+ }
1964+ } )
1965+ } ;
19451966 // are we trying to use an anonymous lifetime
19461967 // on a non GAT associated trait type?
19471968 if !self . in_func_body
@@ -1993,6 +2014,22 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19932014 self . point_at_impl_lifetimes ( & mut err, i, lifetime. ident . span ) ;
19942015 err. emit ( )
19952016 }
2017+ } else if self . diag_metadata . in_assoc_ty_binding {
2018+ // For associated type bindings, e.g.
2019+ // `fn f<I: IntoIterator<Item = &T>>()`, introduce a named lifetime
2020+ // on an enclosing generics binder instead:
2021+ // `fn f<'a, I: IntoIterator<Item = &'a T>>()`.
2022+ let mut err = self . r . dcx ( ) . create_err (
2023+ crate :: diagnostics:: ElidedAnonymousLifetimeReportError {
2024+ span : lifetime. ident . span ,
2025+ suggestion,
2026+ } ,
2027+ ) ;
2028+ self . suggest_introducing_lifetime_for_assoc_ty_binding (
2029+ & mut err,
2030+ lifetime. ident . span ,
2031+ ) ;
2032+ err. emit ( )
19962033 } else {
19972034 self . r . dcx ( ) . emit_err (
19982035 crate :: diagnostics:: ElidedAnonymousLifetimeReportError {
0 commit comments