@@ -20,6 +20,7 @@ use rustc_session::parse::feature_err;
2020use rustc_session:: Session ;
2121use rustc_span:: symbol:: { sym, Symbol } ;
2222use rustc_span:: { Span , DUMMY_SP } ;
23+ use rustc_target:: spec:: abi:: Abi ;
2324
2425use std:: cmp:: Ordering ;
2526use std:: iter;
@@ -95,10 +96,12 @@ struct Annotator<'a, 'tcx> {
9596impl < ' a , ' tcx > Annotator < ' a , ' tcx > {
9697 // Determine the stability for a node based on its attributes and inherited
9798 // stability. The stability is recorded in the index and used as the parent.
99+ // If the node is a function, `fn_sig` is its signature
98100 fn annotate < F > (
99101 & mut self ,
100102 hir_id : HirId ,
101103 item_sp : Span ,
104+ fn_sig : Option < & ' tcx hir:: FnSig < ' tcx > > ,
102105 kind : AnnotationKind ,
103106 inherit_deprecation : InheritDeprecation ,
104107 inherit_const_stability : InheritConstStability ,
@@ -163,13 +166,30 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
163166 }
164167
165168 let ( stab, const_stab) = attr:: find_stability ( & self . tcx . sess , attrs, item_sp) ;
169+ let mut const_span = None ;
166170
167- let const_stab = const_stab. map ( |( const_stab, _ ) | {
171+ let const_stab = const_stab. map ( |( const_stab, const_span_node ) | {
168172 let const_stab = self . tcx . intern_const_stability ( const_stab) ;
169173 self . index . const_stab_map . insert ( hir_id, const_stab) ;
174+ const_span = Some ( const_span_node) ;
170175 const_stab
171176 } ) ;
172177
178+ // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI,
179+ // check if the function/method is const or the parent impl block is const
180+ if let ( Some ( const_span) , Some ( fn_sig) ) = ( const_span, fn_sig) {
181+ if fn_sig. header . abi != Abi :: RustIntrinsic
182+ && fn_sig. header . abi != Abi :: PlatformIntrinsic
183+ && !fn_sig. header . is_const ( )
184+ {
185+ if !self . in_trait_impl
186+ || ( self . in_trait_impl && !self . tcx . is_const_fn_raw ( hir_id. owner . to_def_id ( ) ) )
187+ {
188+ missing_const_err ( & self . tcx . sess , fn_sig. span , const_span) ;
189+ }
190+ }
191+ }
192+
173193 // `impl const Trait for Type` items forward their const stability to their
174194 // immediate children.
175195 if const_stab. is_none ( ) {
@@ -367,6 +387,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
367387 let orig_in_trait_impl = self . in_trait_impl ;
368388 let mut kind = AnnotationKind :: Required ;
369389 let mut const_stab_inherit = InheritConstStability :: No ;
390+ let mut fn_sig = None ;
391+
370392 match i. kind {
371393 // Inherent impls and foreign modules serve only as containers for other items,
372394 // they don't have their own stability. They still can be annotated as unstable
@@ -387,6 +409,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
387409 self . annotate (
388410 ctor_hir_id,
389411 i. span ,
412+ None ,
390413 AnnotationKind :: Required ,
391414 InheritDeprecation :: Yes ,
392415 InheritConstStability :: No ,
@@ -395,12 +418,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
395418 )
396419 }
397420 }
421+ hir:: ItemKind :: Fn ( ref item_fn_sig, _, _) => {
422+ fn_sig = Some ( item_fn_sig) ;
423+ }
398424 _ => { }
399425 }
400426
401427 self . annotate (
402428 i. hir_id ( ) ,
403429 i. span ,
430+ fn_sig,
404431 kind,
405432 InheritDeprecation :: Yes ,
406433 const_stab_inherit,
@@ -411,9 +438,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
411438 }
412439
413440 fn visit_trait_item ( & mut self , ti : & ' tcx hir:: TraitItem < ' tcx > ) {
441+ let fn_sig = match ti. kind {
442+ hir:: TraitItemKind :: Fn ( ref fn_sig, _) => Some ( fn_sig) ,
443+ _ => None ,
444+ } ;
445+
414446 self . annotate (
415447 ti. hir_id ( ) ,
416448 ti. span ,
449+ fn_sig,
417450 AnnotationKind :: Required ,
418451 InheritDeprecation :: Yes ,
419452 InheritConstStability :: No ,
@@ -427,9 +460,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
427460 fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem < ' tcx > ) {
428461 let kind =
429462 if self . in_trait_impl { AnnotationKind :: Prohibited } else { AnnotationKind :: Required } ;
463+
464+ let fn_sig = match ii. kind {
465+ hir:: ImplItemKind :: Fn ( ref fn_sig, _) => Some ( fn_sig) ,
466+ _ => None ,
467+ } ;
468+
430469 self . annotate (
431470 ii. hir_id ( ) ,
432471 ii. span ,
472+ fn_sig,
433473 kind,
434474 InheritDeprecation :: Yes ,
435475 InheritConstStability :: No ,
@@ -444,6 +484,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
444484 self . annotate (
445485 var. id ,
446486 var. span ,
487+ None ,
447488 AnnotationKind :: Required ,
448489 InheritDeprecation :: Yes ,
449490 InheritConstStability :: No ,
@@ -453,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
453494 v. annotate (
454495 ctor_hir_id,
455496 var. span ,
497+ None ,
456498 AnnotationKind :: Required ,
457499 InheritDeprecation :: Yes ,
458500 InheritConstStability :: No ,
@@ -470,6 +512,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
470512 self . annotate (
471513 s. hir_id ,
472514 s. span ,
515+ None ,
473516 AnnotationKind :: Required ,
474517 InheritDeprecation :: Yes ,
475518 InheritConstStability :: No ,
@@ -484,6 +527,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
484527 self . annotate (
485528 i. hir_id ( ) ,
486529 i. span ,
530+ None ,
487531 AnnotationKind :: Required ,
488532 InheritDeprecation :: Yes ,
489533 InheritConstStability :: No ,
@@ -498,6 +542,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
498542 self . annotate (
499543 md. hir_id ( ) ,
500544 md. span ,
545+ None ,
501546 AnnotationKind :: Required ,
502547 InheritDeprecation :: Yes ,
503548 InheritConstStability :: No ,
@@ -517,6 +562,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
517562 self . annotate (
518563 p. hir_id ,
519564 p. span ,
565+ None ,
520566 kind,
521567 InheritDeprecation :: No ,
522568 InheritConstStability :: No ,
@@ -687,6 +733,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
687733 annotator. annotate (
688734 hir:: CRATE_HIR_ID ,
689735 krate. item . inner ,
736+ None ,
690737 AnnotationKind :: Required ,
691738 InheritDeprecation :: Yes ,
692739 InheritConstStability :: No ,
@@ -969,3 +1016,15 @@ fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) {
9691016 struct_span_err ! ( sess, span, E0636 , "the feature `{}` has already been declared" , feature)
9701017 . emit ( ) ;
9711018}
1019+
1020+ fn missing_const_err ( session : & Session , fn_sig_span : Span , const_span : Span ) {
1021+ const ERROR_MSG : & ' static str = "attributes `#[rustc_const_unstable]` \
1022+ and `#[rustc_const_stable]` require \
1023+ the function or method to be `const`";
1024+
1025+ session
1026+ . struct_span_err ( fn_sig_span, ERROR_MSG )
1027+ . span_help ( fn_sig_span, "make the function or method const" )
1028+ . span_label ( const_span, "attribute specified here" )
1029+ . emit ( ) ;
1030+ }
0 commit comments