@@ -54,6 +54,9 @@ struct AstValidator<'a> {
5454
5555 in_const_trait_impl : bool ,
5656
57+ /// Are we inside a const trait defn?
58+ in_const_trait_defn : bool ,
59+
5760 has_proc_macro_decls : bool ,
5861
5962 /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
@@ -85,6 +88,12 @@ impl<'a> AstValidator<'a> {
8588 self . in_const_trait_impl = old_const;
8689 }
8790
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+
8897 fn with_banned_impl_trait ( & mut self , f : impl FnOnce ( & mut Self ) ) {
8998 let old = mem:: replace ( & mut self . is_impl_trait_banned , true ) ;
9099 f ( self ) ;
@@ -933,23 +942,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
933942 }
934943 }
935944 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+ }
943954
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 ) ;
951964 } ) ;
952- walk_list ! ( self , visit_assoc_item, items, AssocCtxt :: Trait ) ;
953965 walk_list ! ( self , visit_attribute, & item. attrs) ;
954966 return ; // Avoid visiting again
955967 }
@@ -1277,8 +1289,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12771289 }
12781290
12791291 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+ } ;
12821302
12831303 let disallowed = ( !tilde_const_allowed) . then ( || DisallowTildeConstContext :: Fn ( fk) ) ;
12841304
@@ -1511,6 +1531,7 @@ pub fn check_crate(
15111531 extern_mod : None ,
15121532 in_trait_impl : false ,
15131533 in_const_trait_impl : false ,
1534+ in_const_trait_defn : false ,
15141535 has_proc_macro_decls : false ,
15151536 outer_impl_trait : None ,
15161537 disallow_tilde_const : None ,
0 commit comments