@@ -253,12 +253,65 @@ 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` is ok 
289+             ( 
290+                 BoundConstness :: Always ( span) , 
291+                 TraitOrTraitImpl :: TraitImpl  {  constness :  Const :: Yes ( _) ,  .. } , 
292+             )  => { 
293+                 if  !const_trait_impl { 
294+                     self . sess 
295+                         . create_feature_err ( errors:: ConstInTrait  {  span } ,  sym:: const_trait_impl) 
296+                         . emit ( ) ; 
297+                 } 
298+                 return ; 
299+             } 
300+             ( BoundConstness :: Always ( span) ,  _)  => span, 
301+             ( 
302+                 BoundConstness :: Maybe ( span) , 
303+                 TraitOrTraitImpl :: Trait  {  constness_span :  Some ( _) ,  .. } , 
304+             )  => { 
305+                 if  !const_trait_impl { 
306+                     self . sess 
307+                         . create_feature_err ( errors:: ConstInTrait  {  span } ,  sym:: const_trait_impl) 
308+                         . emit ( ) ; 
309+                 } 
310+                 return ; 
311+             } 
312+             ( BoundConstness :: Maybe ( span) ,  _)  => span, 
259313        } ; 
260314
261-         let  const_trait_impl = self . features . const_trait_impl ( ) ; 
262315        let  make_impl_const_sugg = if  const_trait_impl
263316            && let  TraitOrTraitImpl :: TraitImpl  { 
264317                constness :  Const :: No , 
@@ -500,8 +553,9 @@ impl<'a> AstValidator<'a> {
500553            None  => ( ) , 
501554        } 
502555        match  constness { 
503-             Const :: Yes ( span)  => report_err ( span,  "const" ) , 
504-             Const :: No  => ( ) , 
556+             BoundConstness :: Always ( span)  => report_err ( span,  "const" ) , 
557+             BoundConstness :: Maybe ( span)  => report_err ( span,  "~const" ) , 
558+             BoundConstness :: Never  => ( ) , 
505559        } 
506560        match  ext { 
507561            Extern :: None  => ( ) , 
@@ -538,7 +592,9 @@ impl<'a> AstValidator<'a> {
538592        } 
539593
540594        if  let  Some ( header)  = fk. header ( )  { 
541-             if  let  Const :: Yes ( const_span)  = header. constness  { 
595+             if  let  BoundConstness :: Always ( const_span)  | BoundConstness :: Maybe ( const_span)  =
596+                 header. constness 
597+             { 
542598                let  mut  spans = variadic_spans. clone ( ) ; 
543599                spans. push ( const_span) ; 
544600                self . dcx ( ) . emit_err ( errors:: ConstAndCVariadic  { 
@@ -1347,7 +1403,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13471403
13481404        // Functions cannot both be `const async` or `const gen` 
13491405        if  let  Some ( & FnHeader  { 
1350-             constness :  Const :: Yes ( const_span) , 
1406+             constness :  BoundConstness :: Always ( const_span )  |  BoundConstness :: Maybe ( const_span) , 
13511407            coroutine_kind :  Some ( coroutine_kind) , 
13521408            ..
13531409        } )  = fk. header ( ) 
@@ -1398,14 +1454,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13981454            } ) ; 
13991455        } 
14001456
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 ( ) ; 
1457+         let  tilde_const_allowed =  matches ! ( fk . header ( ) ,   Some ( FnHeader   {  constness :  ast :: BoundConstness :: Always ( _ )  | ast :: BoundConstness :: Maybe ( _ ) ,  ..  } ) ) 
1458+             // FIXME(const_trait_impls): remove this, we don't want to allow `~const` trait bounds in non-const methods 
1459+             || matches ! ( fk. ctxt( ) ,  Some ( FnCtxt :: Assoc ( _) ) ) 
1460+                 && self 
1461+                     . outer_trait_or_trait_impl 
1462+                     . as_ref ( ) 
1463+                     . and_then ( TraitOrTraitImpl :: constness) 
1464+                     . is_some ( ) ; 
14091465
14101466        let  disallowed = ( !tilde_const_allowed) . then ( || match  fk { 
14111467            FnKind :: Fn ( _,  _,  f)  => TildeConstReason :: Function  {  ident :  f. ident . span  } , 
@@ -1474,7 +1530,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14741530        if  let  Some ( parent)  = & self . outer_trait_or_trait_impl  { 
14751531            self . visibility_not_permitted ( & item. vis ,  errors:: VisibilityNotPermittedNote :: TraitImpl ) ; 
14761532            if  let  AssocItemKind :: Fn ( box  Fn  {  sig,  .. } )  = & item. kind  { 
1477-                 self . check_trait_fn_not_const ( sig. header . constness ,  parent) ; 
1533+                 self . check_trait_fn_not_const ( sig. header . constness ,  sig . span ,   parent) ; 
14781534            } 
14791535        } 
14801536
@@ -1489,7 +1545,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14891545            AssocItemKind :: Fn ( func) 
14901546                if  parent_is_const
14911547                    || ctxt == AssocCtxt :: Trait 
1492-                     || matches ! ( func. sig. header. constness,  Const :: Yes ( _ ) )  =>
1548+                     || ! matches ! ( func. sig. header. constness,  ast :: BoundConstness :: Never )  =>
14931549            { 
14941550                self . visit_attrs_vis_ident ( & item. attrs ,  & item. vis ,  & func. ident ) ; 
14951551                let  kind = FnKind :: Fn ( FnCtxt :: Assoc ( ctxt) ,  & item. vis ,  & * func) ; 
0 commit comments