@@ -17,11 +17,11 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
17
17
use super :: { Parser , Restrictions , TokenType } ;
18
18
use crate :: ast:: { PatKind , TyKind } ;
19
19
use crate :: errors:: {
20
- self , FnPathFoundNamedParams , PathFoundAttributeInParams , PathFoundCVariadicParams ,
21
- PathSingleColon , PathTripleColon ,
20
+ self , AttributeOnEmptyGeneric , AttributeOnGenericType , FnPathFoundNamedParams ,
21
+ PathFoundAttributeInParams , PathFoundCVariadicParams , PathSingleColon , PathTripleColon ,
22
22
} ;
23
23
use crate :: exp;
24
- use crate :: parser:: { CommaRecoveryMode , RecoverColon , RecoverComma } ;
24
+ use crate :: parser:: { CommaRecoveryMode , ExprKind , RecoverColon , RecoverComma } ;
25
25
26
26
/// Specifies how to parse a path.
27
27
#[ derive( Copy , Clone , PartialEq ) ]
@@ -880,6 +880,15 @@ impl<'a> Parser<'a> {
880
880
& mut self ,
881
881
ty_generics : Option < & Generics > ,
882
882
) -> PResult < ' a , Option < GenericArg > > {
883
+ let mut attr_span: Option < Span > = None ;
884
+ if self . token == token:: Pound && self . look_ahead ( 1 , |t| * t == token:: OpenBracket ) {
885
+ // Parse attribute.
886
+ let attrs_wrapper = self . parse_outer_attributes ( ) ?;
887
+ if !attrs_wrapper. is_empty ( ) {
888
+ let raw_attrs = attrs_wrapper. attrs ( ) ;
889
+ attr_span = Some ( raw_attrs[ 0 ] . span . to ( raw_attrs. last ( ) . unwrap ( ) . span ) ) ;
890
+ }
891
+ }
883
892
let start = self . token . span ;
884
893
let arg = if self . check_lifetime ( ) && self . look_ahead ( 1 , |t| !t. is_like_plus ( ) ) {
885
894
// Parse lifetime argument.
@@ -934,6 +943,10 @@ impl<'a> Parser<'a> {
934
943
}
935
944
} else if self . token . is_keyword ( kw:: Const ) {
936
945
return self . recover_const_param_declaration ( ty_generics) ;
946
+ } else if let Some ( attr_span) = attr_span {
947
+ // Handle case where attribute is present but no valid generic argument follows.
948
+ let guar = self . dcx ( ) . emit_err ( AttributeOnEmptyGeneric { span : attr_span } ) ;
949
+ return Ok ( Some ( GenericArg :: Type ( self . mk_ty ( attr_span, TyKind :: Err ( guar) ) ) ) ) ;
937
950
} else {
938
951
// Fall back by trying to parse a const-expr expression. If we successfully do so,
939
952
// then we should report an error that it needs to be wrapped in braces.
@@ -953,6 +966,24 @@ impl<'a> Parser<'a> {
953
966
}
954
967
}
955
968
} ;
969
+
970
+ if let Some ( attr_span) = attr_span {
971
+ let guar = self . dcx ( ) . emit_err ( AttributeOnGenericType {
972
+ span : attr_span,
973
+ fix_span : attr_span. until ( arg. span ( ) ) ,
974
+ } ) ;
975
+
976
+ return Ok ( Some ( match arg {
977
+ GenericArg :: Type ( _) => GenericArg :: Type ( self . mk_ty ( attr_span, TyKind :: Err ( guar) ) ) ,
978
+ GenericArg :: Const ( _) => {
979
+ // Create error const expression
980
+ let error_expr = self . mk_expr ( attr_span, ExprKind :: Err ( guar) ) ;
981
+ GenericArg :: Const ( AnonConst { id : ast:: DUMMY_NODE_ID , value : error_expr } )
982
+ }
983
+ GenericArg :: Lifetime ( lt) => GenericArg :: Lifetime ( lt) , // Less common case
984
+ } ) ) ;
985
+ }
986
+
956
987
Ok ( Some ( arg) )
957
988
}
958
989
0 commit comments