@@ -40,6 +40,9 @@ enum SelfSemantic {
40
40
enum DisallowTildeConstContext < ' a > {
41
41
TraitObject ,
42
42
Fn ( FnKind < ' a > ) ,
43
+ Trait ( Span ) ,
44
+ Impl ( Span ) ,
45
+ Item ,
43
46
}
44
47
45
48
struct AstValidator < ' a > {
@@ -110,18 +113,6 @@ impl<'a> AstValidator<'a> {
110
113
self . disallow_tilde_const = old;
111
114
}
112
115
113
- fn with_tilde_const_allowed ( & mut self , f : impl FnOnce ( & mut Self ) ) {
114
- self . with_tilde_const ( None , f)
115
- }
116
-
117
- fn with_banned_tilde_const (
118
- & mut self ,
119
- ctx : DisallowTildeConstContext < ' a > ,
120
- f : impl FnOnce ( & mut Self ) ,
121
- ) {
122
- self . with_tilde_const ( Some ( ctx) , f)
123
- }
124
-
125
116
fn check_type_alias_where_clause_location (
126
117
& mut self ,
127
118
ty_alias : & TyAlias ,
@@ -173,7 +164,7 @@ impl<'a> AstValidator<'a> {
173
164
self . with_impl_trait ( Some ( t. span ) , |this| visit:: walk_ty ( this, t) )
174
165
}
175
166
TyKind :: TraitObject ( ..) => self
176
- . with_banned_tilde_const ( DisallowTildeConstContext :: TraitObject , |this| {
167
+ . with_tilde_const ( Some ( DisallowTildeConstContext :: TraitObject ) , |this| {
177
168
visit:: walk_ty ( this, t)
178
169
} ) ,
179
170
TyKind :: Path ( qself, path) => {
@@ -822,11 +813,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
822
813
823
814
this. visit_vis ( & item. vis ) ;
824
815
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
- }
816
+ let disallowed = matches ! ( constness, Const :: No )
817
+ . then ( || DisallowTildeConstContext :: Impl ( item. span ) ) ;
818
+ this. with_tilde_const ( disallowed, |this| this. visit_generics ( generics) ) ;
830
819
this. visit_trait_ref ( t) ;
831
820
this. visit_ty ( self_ty) ;
832
821
@@ -840,10 +829,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
840
829
polarity,
841
830
defaultness,
842
831
constness,
843
- generics : _ ,
832
+ generics,
844
833
of_trait : None ,
845
834
self_ty,
846
- items : _ ,
835
+ items,
847
836
} ) => {
848
837
let error =
849
838
|annotation_span, annotation, only_trait : bool | errors:: InherentImplCannot {
@@ -875,6 +864,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
875
864
if let & Const :: Yes ( span) = constness {
876
865
self . err_handler ( ) . emit_err ( error ( span, "`const`" , true ) ) ;
877
866
}
867
+
868
+ self . visit_vis ( & item. vis ) ;
869
+ self . visit_ident ( item. ident ) ;
870
+ self . with_tilde_const ( None , |this| this. visit_generics ( generics) ) ;
871
+ self . visit_ty ( self_ty) ;
872
+ walk_list ! ( self , visit_assoc_item, items, AssocCtxt :: Impl ) ;
873
+ walk_list ! ( self , visit_attribute, & item. attrs) ;
874
+ return ; // Avoid visiting again.
878
875
}
879
876
ItemKind :: Fn ( box Fn { defaultness, sig, generics, body } ) => {
880
877
self . check_defaultness ( item. span , * defaultness) ;
@@ -955,8 +952,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
955
952
// context for the supertraits.
956
953
this. visit_vis ( & item. vis ) ;
957
954
this. visit_ident ( item. ident ) ;
958
- this. visit_generics ( generics) ;
959
- this. with_tilde_const_allowed ( |this| {
955
+ let disallowed =
956
+ ( !is_const_trait) . then ( || DisallowTildeConstContext :: Trait ( item. span ) ) ;
957
+ this. with_tilde_const ( disallowed, |this| {
958
+ this. visit_generics ( generics) ;
960
959
walk_list ! ( this, visit_param_bound, bounds, BoundKind :: SuperTraits )
961
960
} ) ;
962
961
walk_list ! ( this, visit_assoc_item, items, AssocCtxt :: Trait ) ;
@@ -976,16 +975,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
976
975
}
977
976
}
978
977
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
978
VariantData :: Struct ( fields, ..) => {
986
979
self . visit_vis ( & item. vis ) ;
987
980
self . visit_ident ( item. ident ) ;
988
981
self . visit_generics ( generics) ;
982
+ // Permit `Anon{Struct,Union}` as field type.
989
983
walk_list ! ( self , visit_struct_field_def, fields) ;
990
984
walk_list ! ( self , visit_attribute, & item. attrs) ;
991
985
return ;
@@ -1001,6 +995,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1001
995
self . visit_vis ( & item. vis ) ;
1002
996
self . visit_ident ( item. ident ) ;
1003
997
self . visit_generics ( generics) ;
998
+ // Permit `Anon{Struct,Union}` as field type.
1004
999
walk_list ! ( self , visit_struct_field_def, fields) ;
1005
1000
walk_list ! ( self , visit_attribute, & item. attrs) ;
1006
1001
return ;
@@ -1189,15 +1184,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1189
1184
if let Some ( reason) = & self . disallow_tilde_const =>
1190
1185
{
1191
1186
let reason = match reason {
1192
- DisallowTildeConstContext :: TraitObject => {
1193
- errors:: TildeConstReason :: TraitObject
1194
- }
1195
1187
DisallowTildeConstContext :: Fn ( FnKind :: Closure ( ..) ) => {
1196
1188
errors:: TildeConstReason :: Closure
1197
1189
}
1198
1190
DisallowTildeConstContext :: Fn ( FnKind :: Fn ( _, ident, ..) ) => {
1199
1191
errors:: TildeConstReason :: Function { ident : ident. span }
1200
1192
}
1193
+ & DisallowTildeConstContext :: Trait ( span) => errors:: TildeConstReason :: Trait { span } ,
1194
+ & DisallowTildeConstContext :: Impl ( span) => errors:: TildeConstReason :: Impl { span } ,
1195
+ DisallowTildeConstContext :: TraitObject => {
1196
+ errors:: TildeConstReason :: TraitObject
1197
+ }
1198
+ DisallowTildeConstContext :: Item => errors:: TildeConstReason :: Item ,
1201
1199
} ;
1202
1200
self . err_handler ( )
1203
1201
. emit_err ( errors:: TildeConstDisallowed { span : bound. span ( ) , reason } ) ;
@@ -1305,7 +1303,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1305
1303
|| matches ! ( fk. ctxt( ) , Some ( FnCtxt :: Assoc ( _) ) if self . in_const_trait_or_impl) ;
1306
1304
1307
1305
let disallowed = ( !tilde_const_allowed) . then ( || DisallowTildeConstContext :: Fn ( fk) ) ;
1308
-
1309
1306
self . with_tilde_const ( disallowed, |this| visit:: walk_fn ( this, fk) ) ;
1310
1307
}
1311
1308
@@ -1374,18 +1371,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1374
1371
}
1375
1372
1376
1373
match & item. kind {
1377
- AssocItemKind :: Type ( box TyAlias { generics, bounds, ty, .. } )
1378
- if ctxt == AssocCtxt :: Trait =>
1379
- {
1380
- self . visit_vis ( & item. vis ) ;
1381
- self . visit_ident ( item. ident ) ;
1382
- walk_list ! ( self , visit_attribute, & item. attrs) ;
1383
- self . with_tilde_const_allowed ( |this| {
1384
- this. visit_generics ( generics) ;
1385
- walk_list ! ( this, visit_param_bound, bounds, BoundKind :: Bound ) ;
1386
- } ) ;
1387
- walk_list ! ( self , visit_ty, ty) ;
1388
- }
1389
1374
AssocItemKind :: Fn ( box Fn { sig, generics, body, .. } )
1390
1375
if self . in_const_trait_or_impl
1391
1376
|| ctxt == AssocCtxt :: Trait
@@ -1537,7 +1522,7 @@ pub fn check_crate(
1537
1522
in_const_trait_or_impl : false ,
1538
1523
has_proc_macro_decls : false ,
1539
1524
outer_impl_trait : None ,
1540
- disallow_tilde_const : None ,
1525
+ disallow_tilde_const : Some ( DisallowTildeConstContext :: Item ) ,
1541
1526
is_impl_trait_banned : false ,
1542
1527
lint_buffer : lints,
1543
1528
} ;
0 commit comments