@@ -253,12 +253,55 @@ impl<'a> AstValidator<'a> {
253253        } 
254254    } 
255255
256-     fn  check_trait_fn_not_const ( & self ,  constness :  Const ,  parent :  & TraitOrTraitImpl )  { 
257-         let  Const :: Yes ( span)  = constness else  { 
258-             return ; 
256+     fn  check_trait_fn_not_const ( 
257+         & self , 
258+         constness :  BoundConstness , 
259+         sig_span :  Span , 
260+         parent :  & TraitOrTraitImpl , 
261+     )  { 
262+         let  const_trait_impl = self . features . const_trait_impl ( ) ; 
263+ 
264+         let  span = match  ( constness,  parent)  { 
265+             ( BoundConstness :: Never ,  toti)  => { 
266+                 // only `(const)` or `const` fn are allowed in traits or impls respectively. 
267+                 // But for bootstrap purposes we allow the stage1 std and the stage0 std to be the same. 
268+                 if  toti. constness ( ) . is_some ( )  && !self . features . staged_api ( )  { 
269+                     // FIXME(const_trait_impls): allow non-const fns 
270+                     self . dcx ( ) 
271+                         . struct_span_err ( 
272+                             sig_span. shrink_to_lo ( ) , 
273+                             "non-const fn in const traits are not supported yet" , 
274+                         ) 
275+                         . with_span_suggestion ( 
276+                             sig_span. shrink_to_lo ( ) , 
277+                             "mark the function as const" , 
278+                             match  toti { 
279+                                 TraitOrTraitImpl :: Trait  {  .. }  => "(const) " , 
280+                                 TraitOrTraitImpl :: TraitImpl  {  .. }  => "const " , 
281+                             } , 
282+                             rustc_errors:: Applicability :: MachineApplicable , 
283+                         ) 
284+                         . emit ( ) ; 
285+                 } 
286+                 return ; 
287+             } 
288+             // `(const) fn` in `const Trait` or `impl const Trait` is ok 
289+             ( BoundConstness :: Always ( span) ,  _)  => span, 
290+             ( 
291+                 BoundConstness :: Maybe ( span) , 
292+                 TraitOrTraitImpl :: Trait  {  constness_span :  Some ( _) ,  .. } 
293+                 | TraitOrTraitImpl :: TraitImpl  {  constness :  Const :: Yes ( _) ,  .. } , 
294+             )  => { 
295+                 if  !const_trait_impl { 
296+                     self . sess 
297+                         . create_feature_err ( errors:: ConstInTrait  {  span } ,  sym:: const_trait_impl) 
298+                         . emit ( ) ; 
299+                 } 
300+                 return ; 
301+             } 
302+             ( BoundConstness :: Maybe ( span) ,  _)  => span, 
259303        } ; 
260304
261-         let  const_trait_impl = self . features . const_trait_impl ( ) ; 
262305        let  make_impl_const_sugg = if  const_trait_impl
263306            && let  TraitOrTraitImpl :: TraitImpl  { 
264307                constness :  Const :: No , 
@@ -500,8 +543,9 @@ impl<'a> AstValidator<'a> {
500543            None  => ( ) , 
501544        } 
502545        match  constness { 
503-             Const :: Yes ( span)  => report_err ( span,  "const" ) , 
504-             Const :: No  => ( ) , 
546+             BoundConstness :: Always ( span)  => report_err ( span,  "const" ) , 
547+             BoundConstness :: Maybe ( span)  => report_err ( span,  "~const" ) , 
548+             BoundConstness :: Never  => ( ) , 
505549        } 
506550        match  ext { 
507551            Extern :: None  => ( ) , 
@@ -538,7 +582,9 @@ impl<'a> AstValidator<'a> {
538582        } 
539583
540584        if  let  Some ( header)  = fk. header ( )  { 
541-             if  let  Const :: Yes ( const_span)  = header. constness  { 
585+             if  let  BoundConstness :: Always ( const_span)  | BoundConstness :: Maybe ( const_span)  =
586+                 header. constness 
587+             { 
542588                let  mut  spans = variadic_spans. clone ( ) ; 
543589                spans. push ( const_span) ; 
544590                self . dcx ( ) . emit_err ( errors:: ConstAndCVariadic  { 
@@ -1347,7 +1393,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13471393
13481394        // Functions cannot both be `const async` or `const gen` 
13491395        if  let  Some ( & FnHeader  { 
1350-             constness :  Const :: Yes ( const_span) , 
1396+             constness :  BoundConstness :: Always ( const_span )  |  BoundConstness :: Maybe ( const_span) , 
13511397            coroutine_kind :  Some ( coroutine_kind) , 
13521398            ..
13531399        } )  = fk. header ( ) 
@@ -1398,14 +1444,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13981444            } ) ; 
13991445        } 
14001446
1401-         let  tilde_const_allowed =
1402-             matches ! ( fk . header ( ) ,   Some ( FnHeader   {  constness :  ast :: Const :: Yes ( _ ) ,  ..  } ) ) 
1403-                  || matches ! ( fk. ctxt( ) ,  Some ( FnCtxt :: Assoc ( _) ) ) 
1404-                      && self 
1405-                          . outer_trait_or_trait_impl 
1406-                          . as_ref ( ) 
1407-                          . and_then ( TraitOrTraitImpl :: constness) 
1408-                          . is_some ( ) ; 
1447+         let  tilde_const_allowed =  matches ! ( fk . header ( ) ,   Some ( FnHeader   {  constness :  ast :: BoundConstness :: Always ( _ )  | ast :: BoundConstness :: Maybe ( _ ) ,  ..  } ) ) 
1448+             // FIXME(const_trait_impls): remove this, we don't want to allow `~const` trait bounds in non-const methods 
1449+             || matches ! ( fk. ctxt( ) ,  Some ( FnCtxt :: Assoc ( _) ) ) 
1450+                 && self 
1451+                     . outer_trait_or_trait_impl 
1452+                     . as_ref ( ) 
1453+                     . and_then ( TraitOrTraitImpl :: constness) 
1454+                     . is_some ( ) ; 
14091455
14101456        let  disallowed = ( !tilde_const_allowed) . then ( || match  fk { 
14111457            FnKind :: Fn ( _,  _,  f)  => TildeConstReason :: Function  {  ident :  f. ident . span  } , 
@@ -1474,7 +1520,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14741520        if  let  Some ( parent)  = & self . outer_trait_or_trait_impl  { 
14751521            self . visibility_not_permitted ( & item. vis ,  errors:: VisibilityNotPermittedNote :: TraitImpl ) ; 
14761522            if  let  AssocItemKind :: Fn ( box  Fn  {  sig,  .. } )  = & item. kind  { 
1477-                 self . check_trait_fn_not_const ( sig. header . constness ,  parent) ; 
1523+                 self . check_trait_fn_not_const ( sig. header . constness ,  sig . span ,   parent) ; 
14781524            } 
14791525        } 
14801526
@@ -1489,7 +1535,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14891535            AssocItemKind :: Fn ( func) 
14901536                if  parent_is_const
14911537                    || ctxt == AssocCtxt :: Trait 
1492-                     || matches ! ( func. sig. header. constness,  Const :: Yes ( _ ) )  =>
1538+                     || ! matches ! ( func. sig. header. constness,  ast :: BoundConstness :: Never )  =>
14931539            { 
14941540                self . visit_attrs_vis_ident ( & item. attrs ,  & item. vis ,  & func. ident ) ; 
14951541                let  kind = FnKind :: Fn ( FnCtxt :: Assoc ( ctxt) ,  & item. vis ,  & * func) ; 
0 commit comments