@@ -40,6 +40,9 @@ enum SelfSemantic {
4040enum DisallowTildeConstContext < ' a > {
4141 TraitObject ,
4242 Fn ( FnKind < ' a > ) ,
43+ Trait ( Span ) ,
44+ Impl ( Span ) ,
45+ Item ,
4346}
4447
4548struct AstValidator < ' a > {
@@ -110,10 +113,6 @@ impl<'a> AstValidator<'a> {
110113 self . disallow_tilde_const = old;
111114 }
112115
113- fn with_tilde_const_allowed ( & mut self , f : impl FnOnce ( & mut Self ) ) {
114- self . with_tilde_const ( None , f)
115- }
116-
117116 fn with_banned_tilde_const (
118117 & mut self ,
119118 ctx : DisallowTildeConstContext < ' a > ,
@@ -822,11 +821,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
822821
823822 this. visit_vis ( & item. vis ) ;
824823 this. visit_ident ( item. ident ) ;
825- if let Const :: Yes ( _) = constness {
826- this. with_tilde_const_allowed ( |this| this. visit_generics ( generics) ) ;
827- } else {
828- this. visit_generics ( generics) ;
829- }
824+ let disallowed = matches ! ( constness, Const :: No )
825+ . then ( || DisallowTildeConstContext :: Impl ( item. span ) ) ;
826+ this. with_tilde_const ( disallowed, |this| this. visit_generics ( generics) ) ;
830827 this. visit_trait_ref ( t) ;
831828 this. visit_ty ( self_ty) ;
832829
@@ -926,7 +923,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
926923 self . extern_mod = old_item;
927924 return ; // Avoid visiting again.
928925 }
929- ItemKind :: Enum ( def, _) => {
926+ ItemKind :: Enum ( def, generics) => {
927+ self . visit_vis ( & item. vis ) ;
928+ self . visit_ident ( item. ident ) ;
929+
930+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
931+ this. visit_generics ( generics)
932+ } ) ;
933+
930934 for variant in & def. variants {
931935 self . visibility_not_permitted (
932936 & variant. vis ,
@@ -939,6 +943,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
939943 ) ;
940944 }
941945 }
946+ walk_list ! ( self , visit_variant, & def. variants) ;
947+ walk_list ! ( self , visit_attribute, & item. attrs) ;
948+ return ; // Avoid visiting again
942949 }
943950 ItemKind :: Trait ( box Trait { is_auto, generics, bounds, items, .. } ) => {
944951 let is_const_trait = attr:: contains_name ( & item. attrs , sym:: const_trait) ;
@@ -955,8 +962,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
955962 // context for the supertraits.
956963 this. visit_vis ( & item. vis ) ;
957964 this. visit_ident ( item. ident ) ;
958- this. visit_generics ( generics) ;
959- this. with_tilde_const_allowed ( |this| {
965+ let disallowed =
966+ ( !is_const_trait) . then ( || DisallowTildeConstContext :: Trait ( item. span ) ) ;
967+ this. with_tilde_const ( disallowed, |this| {
968+ this. visit_generics ( generics) ;
960969 walk_list ! ( this, visit_param_bound, bounds, BoundKind :: SuperTraits )
961970 } ) ;
962971 walk_list ! ( this, visit_assoc_item, items, AssocCtxt :: Trait ) ;
@@ -975,23 +984,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
975984 self . check_mod_file_item_asciionly ( item. ident ) ;
976985 }
977986 }
978- ItemKind :: Struct ( vdata, generics) => match vdata {
979- // Duplicating the `Visitor` logic allows catching all cases
980- // of `Anonymous(Struct, Union)` outside of a field struct or union.
981- //
982- // Inside `visit_ty` the validator catches every `Anonymous(Struct, Union)` it
983- // encounters, and only on `ItemKind::Struct` and `ItemKind::Union`
984- // it uses `visit_ty_common`, which doesn't contain that specific check.
985- VariantData :: Struct ( fields , .. ) => {
986- self . visit_vis ( & item . vis ) ;
987- self . visit_ident ( item . ident ) ;
988- self . visit_generics ( generics ) ;
989- walk_list ! ( self , visit_struct_field_def, fields) ;
990- walk_list ! ( self , visit_attribute , & item . attrs ) ;
991- return ;
987+ ItemKind :: Struct ( vdata, generics) => {
988+ self . visit_vis ( & item . vis ) ;
989+ self . visit_ident ( item . ident ) ;
990+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
991+ this . visit_generics ( generics )
992+ } ) ;
993+ walk_list ! ( self , visit_attribute , & item . attrs ) ;
994+
995+ match vdata {
996+ // Permit `Anon{Struct,Union}` as field type.
997+ VariantData :: Struct ( fields , .. ) => {
998+ walk_list ! ( self , visit_struct_field_def, fields)
999+ }
1000+ _ => self . visit_variant_data ( vdata ) ,
9921001 }
993- _ => { }
994- } ,
1002+ return ; // Avoid visiting again-
1003+ }
9951004 ItemKind :: Union ( vdata, generics) => {
9961005 if vdata. fields ( ) . is_empty ( ) {
9971006 self . err_handler ( ) . emit_err ( errors:: FieldlessUnion { span : item. span } ) ;
@@ -1000,20 +1009,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10001009 VariantData :: Struct ( fields, ..) => {
10011010 self . visit_vis ( & item. vis ) ;
10021011 self . visit_ident ( item. ident ) ;
1003- self . visit_generics ( generics) ;
1012+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
1013+ this. visit_generics ( generics)
1014+ } ) ;
1015+ // Permit `Anon{Struct,Union}` as field type.
10041016 walk_list ! ( self , visit_struct_field_def, fields) ;
10051017 walk_list ! ( self , visit_attribute, & item. attrs) ;
10061018 return ;
10071019 }
10081020 _ => { }
10091021 }
10101022 }
1011- ItemKind :: Const ( box ConstItem { defaultness, expr : None , .. } ) => {
1012- self . check_defaultness ( item. span , * defaultness) ;
1013- self . session . emit_err ( errors:: ConstWithoutBody {
1014- span : item. span ,
1015- replace_span : self . ending_semi_or_hi ( item. span ) ,
1023+ ItemKind :: Const ( box ConstItem { defaultness, generics, ty, expr } ) => {
1024+ self . visit_vis ( & item. vis ) ;
1025+ self . visit_ident ( item. ident ) ;
1026+ // FIXME(#117791): Also reject `default` if `expr` is `Some`.
1027+ if expr. is_none ( ) {
1028+ self . check_defaultness ( item. span , * defaultness) ;
1029+ }
1030+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
1031+ this. visit_generics ( generics)
10161032 } ) ;
1033+ self . visit_ty ( ty) ;
1034+ if let Some ( expr) = expr {
1035+ self . visit_expr ( expr) ;
1036+ } else {
1037+ self . session . emit_err ( errors:: ConstWithoutBody {
1038+ span : item. span ,
1039+ replace_span : self . ending_semi_or_hi ( item. span ) ,
1040+ } ) ;
1041+ }
1042+ walk_list ! ( self , visit_attribute, & item. attrs) ;
1043+ return ; // Avoid visiting again.
10171044 }
10181045 ItemKind :: Static ( box StaticItem { expr : None , .. } ) => {
10191046 self . session . emit_err ( errors:: StaticWithoutBody {
@@ -1022,9 +1049,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10221049 } ) ;
10231050 }
10241051 ItemKind :: TyAlias (
1025- ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. } ,
1052+ ty_alias @ box TyAlias { defaultness, generics , bounds, where_clauses, ty, .. } ,
10261053 ) => {
10271054 self . check_defaultness ( item. span , * defaultness) ;
1055+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
1056+ this. visit_generics ( generics)
1057+ } ) ;
10281058 if ty. is_none ( ) {
10291059 self . session . emit_err ( errors:: TyAliasWithoutBody {
10301060 span : item. span ,
@@ -1189,15 +1219,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11891219 if let Some ( reason) = & self . disallow_tilde_const =>
11901220 {
11911221 let reason = match reason {
1192- DisallowTildeConstContext :: TraitObject => {
1193- errors:: TildeConstReason :: TraitObject
1194- }
11951222 DisallowTildeConstContext :: Fn ( FnKind :: Closure ( ..) ) => {
11961223 errors:: TildeConstReason :: Closure
11971224 }
11981225 DisallowTildeConstContext :: Fn ( FnKind :: Fn ( _, ident, ..) ) => {
11991226 errors:: TildeConstReason :: Function { ident : ident. span }
12001227 }
1228+ & DisallowTildeConstContext :: Trait ( span) => errors:: TildeConstReason :: Trait { span } ,
1229+ & DisallowTildeConstContext :: Impl ( span) => errors:: TildeConstReason :: Impl { span } ,
1230+ DisallowTildeConstContext :: TraitObject => {
1231+ errors:: TildeConstReason :: TraitObject
1232+ }
1233+ DisallowTildeConstContext :: Item => errors:: TildeConstReason :: Item ,
12011234 } ;
12021235 self . err_handler ( )
12031236 . emit_err ( errors:: TildeConstDisallowed { span : bound. span ( ) , reason } ) ;
@@ -1305,7 +1338,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13051338 || matches ! ( fk. ctxt( ) , Some ( FnCtxt :: Assoc ( _) ) if self . in_const_trait_or_impl) ;
13061339
13071340 let disallowed = ( !tilde_const_allowed) . then ( || DisallowTildeConstContext :: Fn ( fk) ) ;
1308-
13091341 self . with_tilde_const ( disallowed, |this| visit:: walk_fn ( this, fk) ) ;
13101342 }
13111343
@@ -1374,15 +1406,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13741406 }
13751407
13761408 match & item. kind {
1377- AssocItemKind :: Type ( box TyAlias { generics, bounds, ty, .. } )
1378- if ctxt == AssocCtxt :: Trait =>
1379- {
1409+ AssocItemKind :: Type ( box TyAlias { generics, bounds, ty, .. } ) => {
13801410 self . visit_vis ( & item. vis ) ;
13811411 self . visit_ident ( item. ident ) ;
13821412 walk_list ! ( self , visit_attribute, & item. attrs) ;
1383- self . with_tilde_const_allowed ( |this| {
1413+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
13841414 this. visit_generics ( generics) ;
1385- walk_list ! ( this, visit_param_bound, bounds, BoundKind :: Bound ) ;
1415+ if ctxt == AssocCtxt :: Trait {
1416+ walk_list ! ( this, visit_param_bound, bounds, BoundKind :: Bound ) ;
1417+ }
13861418 } ) ;
13871419 walk_list ! ( self , visit_ty, ty) ;
13881420 }
@@ -1403,6 +1435,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14031435 ) ;
14041436 self . visit_fn ( kind, item. span , item. id ) ;
14051437 }
1438+ AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => {
1439+ self . visit_vis ( & item. vis ) ;
1440+ self . visit_ident ( item. ident ) ;
1441+ walk_list ! ( self , visit_attribute, & item. attrs) ;
1442+ self . with_banned_tilde_const ( DisallowTildeConstContext :: Item , |this| {
1443+ this. visit_generics ( generics) ;
1444+ } ) ;
1445+ self . visit_ty ( ty) ;
1446+ walk_list ! ( self , visit_expr, expr) ;
1447+ }
14061448 _ => self
14071449 . with_in_trait_impl ( false , None , |this| visit:: walk_assoc_item ( this, item, ctxt) ) ,
14081450 }
0 commit comments