@@ -518,10 +518,20 @@ impl<'a> Parser<'a> {
518518 match arg {
519519 Some ( arg) => {
520520 if self . check ( & token:: Colon ) | self . check ( & token:: Eq ) {
521- let ( ident, gen_args) = match self . get_ident_from_generic_arg ( arg) {
521+ let arg_span = arg. span ( ) ;
522+ let ( binder, ident, gen_args) = match self . get_ident_from_generic_arg ( & arg) {
522523 Ok ( ident_gen_args) => ident_gen_args,
523- Err ( arg ) => return Ok ( Some ( AngleBracketedArg :: Arg ( arg) ) ) ,
524+ Err ( ( ) ) => return Ok ( Some ( AngleBracketedArg :: Arg ( arg) ) ) ,
524525 } ;
526+ if binder. is_some ( ) {
527+ // FIXME(compiler-errors): this could be improved by suggesting lifting
528+ // this up to the trait, at least before this becomes real syntax.
529+ // e.g. `Trait<for<'a> Assoc = Ty>` -> `for<'a> Trait<Assoc = Ty>`
530+ return Err ( self . struct_span_err (
531+ arg_span,
532+ "`for<...>` is not allowed on associated type bounds" ,
533+ ) ) ;
534+ }
525535 let kind = if self . eat ( & token:: Colon ) {
526536 // Parse associated type constraint bound.
527537
@@ -700,18 +710,32 @@ impl<'a> Parser<'a> {
700710 Ok ( Some ( arg) )
701711 }
702712
713+ /// Given a arg inside of generics, we try to destructure it as if it were the LHS in
714+ /// `LHS = ...`, i.e. an associated type binding.
715+ /// This returns (optionally, if they are present) any `for<'a, 'b>` binder args, the
716+ /// identifier, and any GAT arguments.
703717 fn get_ident_from_generic_arg (
704718 & self ,
705- gen_arg : GenericArg ,
706- ) -> Result < ( Ident , Option < GenericArgs > ) , GenericArg > {
707- if let GenericArg :: Type ( ty) = & gen_arg
708- && let ast:: TyKind :: Path ( qself, path) = & ty. kind
709- && qself. is_none ( )
710- && path. segments . len ( ) == 1
711- {
712- let seg = & path. segments [ 0 ] ;
713- return Ok ( ( seg. ident , seg. args . as_deref ( ) . cloned ( ) ) ) ;
719+ gen_arg : & GenericArg ,
720+ ) -> Result < ( Option < Vec < ast:: GenericParam > > , Ident , Option < GenericArgs > ) , ( ) > {
721+ if let GenericArg :: Type ( ty) = gen_arg {
722+ if let ast:: TyKind :: Path ( qself, path) = & ty. kind
723+ && qself. is_none ( )
724+ && let [ seg] = path. segments . as_slice ( )
725+ {
726+ return Ok ( ( None , seg. ident , seg. args . as_deref ( ) . cloned ( ) ) ) ;
727+ } else if let ast:: TyKind :: TraitObject ( bounds, ast:: TraitObjectSyntax :: None ) = & ty. kind
728+ && let [ ast:: GenericBound :: Trait ( trait_ref, ast:: TraitBoundModifier :: None ) ] =
729+ bounds. as_slice ( )
730+ && let [ seg] = trait_ref. trait_ref . path . segments . as_slice ( )
731+ {
732+ return Ok ( (
733+ Some ( trait_ref. bound_generic_params . clone ( ) ) ,
734+ seg. ident ,
735+ seg. args . as_deref ( ) . cloned ( ) ,
736+ ) ) ;
737+ }
714738 }
715- Err ( gen_arg )
739+ Err ( ( ) )
716740 }
717741}
0 commit comments