@@ -54,6 +54,9 @@ struct AstValidator<'a> {
54
54
55
55
in_const_trait_impl : bool ,
56
56
57
+ /// Are we inside a const trait defn?
58
+ in_const_trait_defn : bool ,
59
+
57
60
has_proc_macro_decls : bool ,
58
61
59
62
/// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
@@ -85,6 +88,12 @@ impl<'a> AstValidator<'a> {
85
88
self . in_const_trait_impl = old_const;
86
89
}
87
90
91
+ fn with_in_trait ( & mut self , is_const : bool , f : impl FnOnce ( & mut Self ) ) {
92
+ let old = mem:: replace ( & mut self . in_const_trait_defn , is_const) ;
93
+ f ( self ) ;
94
+ self . in_const_trait_defn = old;
95
+ }
96
+
88
97
fn with_banned_impl_trait ( & mut self , f : impl FnOnce ( & mut Self ) ) {
89
98
let old = mem:: replace ( & mut self . is_impl_trait_banned , true ) ;
90
99
f ( self ) ;
@@ -933,23 +942,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
933
942
}
934
943
}
935
944
ItemKind :: Trait ( box Trait { is_auto, generics, bounds, items, .. } ) => {
936
- if * is_auto == IsAuto :: Yes {
937
- // Auto traits cannot have generics, super traits nor contain items.
938
- self . deny_generic_params ( generics, item. ident . span ) ;
939
- self . deny_super_traits ( bounds, item. ident . span ) ;
940
- self . deny_where_clause ( & generics. where_clause , item. ident . span ) ;
941
- self . deny_items ( items, item. ident . span ) ;
942
- }
945
+ let is_const_trait = attr:: contains_name ( & item. attrs , sym:: const_trait) ;
946
+ self . with_in_trait ( is_const_trait, |this| {
947
+ if * is_auto == IsAuto :: Yes {
948
+ // Auto traits cannot have generics, super traits nor contain items.
949
+ this. deny_generic_params ( generics, item. ident . span ) ;
950
+ this. deny_super_traits ( bounds, item. ident . span ) ;
951
+ this. deny_where_clause ( & generics. where_clause , item. ident . span ) ;
952
+ this. deny_items ( items, item. ident . span ) ;
953
+ }
943
954
944
- // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
945
- // context for the supertraits.
946
- self . visit_vis ( & item. vis ) ;
947
- self . visit_ident ( item. ident ) ;
948
- self . visit_generics ( generics) ;
949
- self . with_tilde_const_allowed ( |this| {
950
- walk_list ! ( this, visit_param_bound, bounds, BoundKind :: SuperTraits )
955
+ // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
956
+ // context for the supertraits.
957
+ this. visit_vis ( & item. vis ) ;
958
+ this. visit_ident ( item. ident ) ;
959
+ this. visit_generics ( generics) ;
960
+ this. with_tilde_const_allowed ( |this| {
961
+ walk_list ! ( this, visit_param_bound, bounds, BoundKind :: SuperTraits )
962
+ } ) ;
963
+ walk_list ! ( this, visit_assoc_item, items, AssocCtxt :: Trait ) ;
951
964
} ) ;
952
- walk_list ! ( self , visit_assoc_item, items, AssocCtxt :: Trait ) ;
953
965
walk_list ! ( self , visit_attribute, & item. attrs) ;
954
966
return ; // Avoid visiting again
955
967
}
@@ -1277,8 +1289,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
1277
1289
}
1278
1290
1279
1291
let tilde_const_allowed =
1280
- matches ! ( fk. header( ) , Some ( FnHeader { constness: ast:: Const :: Yes ( _) , .. } ) )
1281
- || matches ! ( fk. ctxt( ) , Some ( FnCtxt :: Assoc ( _) ) ) ;
1292
+ if matches ! ( fk. header( ) , Some ( FnHeader { constness: ast:: Const :: Yes ( _) , .. } ) ) {
1293
+ true
1294
+ } else if let Some ( FnCtxt :: Assoc ( ctxt) ) = fk. ctxt ( ) {
1295
+ match ctxt {
1296
+ AssocCtxt :: Trait => self . in_const_trait_defn ,
1297
+ AssocCtxt :: Impl => self . in_const_trait_impl ,
1298
+ }
1299
+ } else {
1300
+ false
1301
+ } ;
1282
1302
1283
1303
let disallowed = ( !tilde_const_allowed) . then ( || DisallowTildeConstContext :: Fn ( fk) ) ;
1284
1304
@@ -1511,6 +1531,7 @@ pub fn check_crate(
1511
1531
extern_mod : None ,
1512
1532
in_trait_impl : false ,
1513
1533
in_const_trait_impl : false ,
1534
+ in_const_trait_defn : false ,
1514
1535
has_proc_macro_decls : false ,
1515
1536
outer_impl_trait : None ,
1516
1537
disallow_tilde_const : None ,
0 commit comments