@@ -48,15 +48,17 @@ enum SelfSemantic {
4848 No ,
4949}
5050
51- enum TraitOrTraitImpl {
51+ enum TraitOrImpl {
5252 Trait { vis : Span , constness : Const } ,
5353 TraitImpl { constness : Const , polarity : ImplPolarity , trait_ref_span : Span } ,
54+ Impl { constness : Const } ,
5455}
5556
56- impl TraitOrTraitImpl {
57+ impl TraitOrImpl {
5758 fn constness ( & self ) -> Option < Span > {
5859 match self {
5960 Self :: Trait { constness : Const :: Yes ( span) , .. }
61+ | Self :: Impl { constness : Const :: Yes ( span) , .. }
6062 | Self :: TraitImpl { constness : Const :: Yes ( span) , .. } => Some ( * span) ,
6163 _ => None ,
6264 }
@@ -70,7 +72,7 @@ struct AstValidator<'a> {
7072 /// The span of the `extern` in an `extern { ... }` block, if any.
7173 extern_mod_span : Option < Span > ,
7274
73- outer_trait_or_trait_impl : Option < TraitOrTraitImpl > ,
75+ outer_trait_or_trait_impl : Option < TraitOrImpl > ,
7476
7577 has_proc_macro_decls : bool ,
7678
@@ -93,27 +95,20 @@ struct AstValidator<'a> {
9395}
9496
9597impl < ' a > AstValidator < ' a > {
96- fn with_in_trait_impl (
98+ fn with_in_trait_or_impl (
9799 & mut self ,
98- trait_ : Option < ( Const , ImplPolarity , & ' a TraitRef ) > ,
100+ in_trait_or_impl : Option < TraitOrImpl > ,
99101 f : impl FnOnce ( & mut Self ) ,
100102 ) {
101- let old = mem:: replace (
102- & mut self . outer_trait_or_trait_impl ,
103- trait_. map ( |( constness, polarity, trait_ref) | TraitOrTraitImpl :: TraitImpl {
104- constness,
105- polarity,
106- trait_ref_span : trait_ref. path . span ,
107- } ) ,
108- ) ;
103+ let old = mem:: replace ( & mut self . outer_trait_or_trait_impl , in_trait_or_impl) ;
109104 f ( self ) ;
110105 self . outer_trait_or_trait_impl = old;
111106 }
112107
113108 fn with_in_trait ( & mut self , vis : Span , constness : Const , f : impl FnOnce ( & mut Self ) ) {
114109 let old = mem:: replace (
115110 & mut self . outer_trait_or_trait_impl ,
116- Some ( TraitOrTraitImpl :: Trait { vis, constness } ) ,
111+ Some ( TraitOrImpl :: Trait { vis, constness } ) ,
117112 ) ;
118113 f ( self ) ;
119114 self . outer_trait_or_trait_impl = old;
@@ -247,14 +242,28 @@ impl<'a> AstValidator<'a> {
247242 }
248243 }
249244
250- fn check_trait_fn_not_const ( & self , constness : Const , parent : & TraitOrTraitImpl ) {
245+ fn check_impl_fn_not_const ( & self , constness : Const , parent_constness : Const ) {
246+ let Const :: Yes ( span) = constness else {
247+ return ;
248+ } ;
249+
250+ let span = self . sess . source_map ( ) . span_extend_while_whitespace ( span) ;
251+
252+ let Const :: Yes ( parent_constness) = parent_constness else {
253+ return ;
254+ } ;
255+
256+ self . dcx ( ) . emit_err ( errors:: ImplFnConst { span, parent_constness } ) ;
257+ }
258+
259+ fn check_trait_fn_not_const ( & self , constness : Const , parent : & TraitOrImpl ) {
251260 let Const :: Yes ( span) = constness else {
252261 return ;
253262 } ;
254263
255264 let const_trait_impl = self . features . const_trait_impl ( ) ;
256265 let make_impl_const_sugg = if const_trait_impl
257- && let TraitOrTraitImpl :: TraitImpl {
266+ && let TraitOrImpl :: TraitImpl {
258267 constness : Const :: No ,
259268 polarity : ImplPolarity :: Positive ,
260269 trait_ref_span,
@@ -269,7 +278,7 @@ impl<'a> AstValidator<'a> {
269278 let map = self . sess . source_map ( ) ;
270279
271280 let make_trait_const_sugg = if const_trait_impl
272- && let & TraitOrTraitImpl :: Trait { vis, constness : ast:: Const :: No } = parent
281+ && let & TraitOrImpl :: Trait { vis, constness : ast:: Const :: No } = parent
273282 {
274283 Some ( map. span_extend_while_whitespace ( vis) . shrink_to_hi ( ) )
275284 } else {
@@ -279,7 +288,7 @@ impl<'a> AstValidator<'a> {
279288 let parent_constness = parent. constness ( ) ;
280289 self . dcx ( ) . emit_err ( errors:: TraitFnConst {
281290 span,
282- in_impl : matches ! ( parent, TraitOrTraitImpl :: TraitImpl { .. } ) ,
291+ in_impl : matches ! ( parent, TraitOrImpl :: TraitImpl { .. } ) ,
283292 const_context_label : parent_constness,
284293 remove_const_sugg : (
285294 map. span_extend_while_whitespace ( span) ,
@@ -295,7 +304,7 @@ impl<'a> AstValidator<'a> {
295304 } ) ;
296305 }
297306
298- fn check_async_fn_in_const_trait_or_impl ( & self , sig : & FnSig , parent : & TraitOrTraitImpl ) {
307+ fn check_async_fn_in_const_trait_or_impl ( & self , sig : & FnSig , parent : & TraitOrImpl ) {
299308 let Some ( const_keyword) = parent. constness ( ) else { return } ;
300309
301310 let Some ( CoroutineKind :: Async { span : async_keyword, .. } ) = sig. header . coroutine_kind
@@ -305,7 +314,7 @@ impl<'a> AstValidator<'a> {
305314
306315 self . dcx ( ) . emit_err ( errors:: AsyncFnInConstTraitOrTraitImpl {
307316 async_keyword,
308- in_impl : matches ! ( parent, TraitOrTraitImpl :: TraitImpl { .. } ) ,
317+ in_impl : matches ! ( parent, TraitOrImpl :: TraitImpl { .. } ) ,
309318 const_keyword,
310319 } ) ;
311320 }
@@ -1070,14 +1079,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10701079 match & item. kind {
10711080 ItemKind :: Impl ( Impl {
10721081 generics,
1082+ constness,
10731083 of_trait :
1074- Some ( box TraitImplHeader {
1075- safety,
1076- polarity,
1077- defaultness : _,
1078- constness,
1079- trait_ref : t,
1080- } ) ,
1084+ Some ( box TraitImplHeader { safety, polarity, defaultness : _, trait_ref : t } ) ,
10811085 self_ty,
10821086 items,
10831087 } ) => {
@@ -1105,24 +1109,46 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11051109 self . visit_trait_ref ( t) ;
11061110 self . visit_ty ( self_ty) ;
11071111
1108- self . with_in_trait_impl ( Some ( ( * constness, * polarity, t) ) , |this| {
1109- walk_list ! ( this, visit_assoc_item, items, AssocCtxt :: Impl { of_trait: true } ) ;
1110- } ) ;
1112+ self . with_in_trait_or_impl (
1113+ Some ( TraitOrImpl :: TraitImpl {
1114+ constness : * constness,
1115+ polarity : * polarity,
1116+ trait_ref_span : t. path . span ,
1117+ } ) ,
1118+ |this| {
1119+ walk_list ! (
1120+ this,
1121+ visit_assoc_item,
1122+ items,
1123+ AssocCtxt :: Impl { of_trait: true }
1124+ ) ;
1125+ } ,
1126+ ) ;
11111127 }
1112- ItemKind :: Impl ( Impl { generics, of_trait : None , self_ty, items } ) => {
1128+ ItemKind :: Impl ( Impl { generics, of_trait : None , self_ty, items, constness } ) => {
11131129 self . visit_attrs_vis ( & item. attrs , & item. vis ) ;
11141130 self . visibility_not_permitted (
11151131 & item. vis ,
11161132 errors:: VisibilityNotPermittedNote :: IndividualImplItems ,
11171133 ) ;
11181134
1119- self . with_tilde_const ( Some ( TildeConstReason :: Impl { span : item. span } ) , |this| {
1120- this. visit_generics ( generics)
1121- } ) ;
1135+ let disallowed = matches ! ( constness, ast:: Const :: No )
1136+ . then ( || TildeConstReason :: Impl { span : item. span } ) ;
1137+
1138+ self . with_tilde_const ( disallowed, |this| this. visit_generics ( generics) ) ;
1139+
11221140 self . visit_ty ( self_ty) ;
1123- self . with_in_trait_impl ( None , |this| {
1124- walk_list ! ( this, visit_assoc_item, items, AssocCtxt :: Impl { of_trait: false } ) ;
1125- } ) ;
1141+ self . with_in_trait_or_impl (
1142+ Some ( TraitOrImpl :: Impl { constness : * constness } ) ,
1143+ |this| {
1144+ walk_list ! (
1145+ this,
1146+ visit_assoc_item,
1147+ items,
1148+ AssocCtxt :: Impl { of_trait: false }
1149+ ) ;
1150+ } ,
1151+ ) ;
11261152 }
11271153 ItemKind :: Fn (
11281154 func @ box Fn {
@@ -1240,7 +1266,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12401266 this. visit_generics ( generics) ;
12411267 walk_list ! ( this, visit_param_bound, bounds, BoundKind :: SuperTraits )
12421268 } ) ;
1243- self . with_in_trait ( item. vis . span , * constness, |this| {
1269+ self . with_in_trait ( item. span , * constness, |this| {
12441270 walk_list ! ( this, visit_assoc_item, items, AssocCtxt :: Trait ) ;
12451271 } ) ;
12461272 }
@@ -1610,7 +1636,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
16101636 && self
16111637 . outer_trait_or_trait_impl
16121638 . as_ref ( )
1613- . and_then ( TraitOrTraitImpl :: constness)
1639+ . and_then ( TraitOrImpl :: constness)
16141640 . is_some ( ) ;
16151641
16161642 let disallowed = ( !tilde_const_allowed) . then ( || match fk {
@@ -1677,20 +1703,31 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
16771703 ) ;
16781704 }
16791705
1680- if let Some ( parent) = & self . outer_trait_or_trait_impl {
1681- self . visibility_not_permitted ( & item. vis , errors:: VisibilityNotPermittedNote :: TraitImpl ) ;
1682- if let AssocItemKind :: Fn ( box Fn { sig, .. } ) = & item. kind {
1683- self . check_trait_fn_not_const ( sig. header . constness , parent) ;
1684- self . check_async_fn_in_const_trait_or_impl ( sig, parent) ;
1706+ match & self . outer_trait_or_trait_impl {
1707+ Some ( parent @ ( TraitOrImpl :: Trait { .. } | TraitOrImpl :: TraitImpl { .. } ) ) => {
1708+ self . visibility_not_permitted (
1709+ & item. vis ,
1710+ errors:: VisibilityNotPermittedNote :: TraitImpl ,
1711+ ) ;
1712+ if let AssocItemKind :: Fn ( box Fn { sig, .. } ) = & item. kind {
1713+ self . check_trait_fn_not_const ( sig. header . constness , parent) ;
1714+ self . check_async_fn_in_const_trait_or_impl ( sig, parent) ;
1715+ }
1716+ }
1717+ Some ( TraitOrImpl :: Impl { constness } ) => {
1718+ if let AssocItemKind :: Fn ( box Fn { sig, .. } ) = & item. kind {
1719+ self . check_impl_fn_not_const ( sig. header . constness , * constness) ;
1720+ }
16851721 }
1722+ None => { }
16861723 }
16871724
16881725 if let AssocItemKind :: Const ( ci) = & item. kind {
16891726 self . check_item_named ( ci. ident , "const" ) ;
16901727 }
16911728
16921729 let parent_is_const =
1693- self . outer_trait_or_trait_impl . as_ref ( ) . and_then ( TraitOrTraitImpl :: constness) . is_some ( ) ;
1730+ self . outer_trait_or_trait_impl . as_ref ( ) . and_then ( TraitOrImpl :: constness) . is_some ( ) ;
16941731
16951732 match & item. kind {
16961733 AssocItemKind :: Fn ( func)
@@ -1704,19 +1741,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
17041741 }
17051742 AssocItemKind :: Type ( _) => {
17061743 let disallowed = ( !parent_is_const) . then ( || match self . outer_trait_or_trait_impl {
1707- Some ( TraitOrTraitImpl :: Trait { .. } ) => {
1744+ Some ( TraitOrImpl :: Trait { .. } ) => {
17081745 TildeConstReason :: TraitAssocTy { span : item. span }
17091746 }
1710- Some ( TraitOrTraitImpl :: TraitImpl { .. } ) => {
1747+ Some ( TraitOrImpl :: TraitImpl { .. } ) => {
17111748 TildeConstReason :: TraitImplAssocTy { span : item. span }
17121749 }
1713- None => TildeConstReason :: InherentAssocTy { span : item. span } ,
1750+ Some ( TraitOrImpl :: Impl { .. } ) | None => {
1751+ TildeConstReason :: InherentAssocTy { span : item. span }
1752+ }
17141753 } ) ;
17151754 self . with_tilde_const ( disallowed, |this| {
1716- this. with_in_trait_impl ( None , |this| visit:: walk_assoc_item ( this, item, ctxt) )
1755+ this. with_in_trait_or_impl ( None , |this| {
1756+ visit:: walk_assoc_item ( this, item, ctxt)
1757+ } )
17171758 } )
17181759 }
1719- _ => self . with_in_trait_impl ( None , |this| visit:: walk_assoc_item ( this, item, ctxt) ) ,
1760+ _ => self . with_in_trait_or_impl ( None , |this| visit:: walk_assoc_item ( this, item, ctxt) ) ,
17201761 }
17211762 }
17221763
0 commit comments