@@ -518,10 +518,20 @@ impl<'a> Parser<'a> {
518
518
match arg {
519
519
Some ( arg) => {
520
520
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) {
522
523
Ok ( ident_gen_args) => ident_gen_args,
523
- Err ( arg ) => return Ok ( Some ( AngleBracketedArg :: Arg ( arg) ) ) ,
524
+ Err ( ( ) ) => return Ok ( Some ( AngleBracketedArg :: Arg ( arg) ) ) ,
524
525
} ;
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
+ }
525
535
let kind = if self . eat ( & token:: Colon ) {
526
536
// Parse associated type constraint bound.
527
537
@@ -700,18 +710,32 @@ impl<'a> Parser<'a> {
700
710
Ok ( Some ( arg) )
701
711
}
702
712
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.
703
717
fn get_ident_from_generic_arg (
704
718
& 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
+ }
714
738
}
715
- Err ( gen_arg )
739
+ Err ( ( ) )
716
740
}
717
741
}
0 commit comments