@@ -576,6 +576,44 @@ impl<'a> Parser<'a> {
576576 let mut generics = if self . choose_generics_over_qpath ( 0 ) {
577577 self . parse_generics ( ) ?
578578 } else {
579+ // We might be mistakenly trying to use a generic type as a generic parameter.
580+ // impl<X<T>> Trait for Y<T> { ... }
581+ if self . look_ahead ( 0 , |t| t == & token:: Lt )
582+ && self . look_ahead ( 1 , |t| t. is_ident ( ) )
583+ && self . look_ahead ( 2 , |t| t == & token:: Lt )
584+ {
585+ self . bump ( ) ; // <
586+ let ident = self . parse_ident ( ) ?;
587+ let generics = self . parse_generics ( ) ?;
588+ let span = ident. span . to ( generics. span ) ;
589+ let snippet = self . span_to_snippet ( span) . unwrap ( ) ;
590+
591+ let msg = format ! ( "expected type parameter, found path `{}`" , snippet) ;
592+ let mut err = self . dcx ( ) . struct_span_err ( span, msg) ;
593+ err. span_label ( span, "expected type parameter, found path" ) ;
594+ err. span_suggestion (
595+ span,
596+ "you might have meant to bind a type parameter to a trait" ,
597+ format ! ( "T: {snippet}" ) ,
598+ Applicability :: Unspecified ,
599+ ) ;
600+
601+ let mut mapped = String :: new ( ) ;
602+ for i in 0 ..generics. params . len ( ) {
603+ mapped += & format ! ( "{}: {}" , generics. params[ i] . ident, ident) ;
604+ if i != ( generics. params . len ( ) - 1 ) {
605+ mapped += ", " ;
606+ }
607+ }
608+ err. span_suggestion ( span, if generics. params . len ( ) == 1 {
609+ format ! ( "alternatively, you might have meant to bind type parameter `{}` to trait `{}`" , generics. params[ 0 ] . ident. name. as_str( ) , ident. name. as_str( ) )
610+ } else {
611+ format ! ( "alternatively, you might have meant to bind type parameters to trait `{}`" , ident. name. as_str( ) )
612+ } , mapped, Applicability :: Unspecified ) ;
613+
614+ return Err ( err) ;
615+ }
616+
579617 let mut generics = Generics :: default ( ) ;
580618 // impl A for B {}
581619 // /\ this is where `generics.span` should point when there are no type params.
0 commit comments