@@ -20,6 +20,7 @@ use rustc_session::parse::feature_err;
20
20
use rustc_session:: Session ;
21
21
use rustc_span:: symbol:: { sym, Symbol } ;
22
22
use rustc_span:: { Span , DUMMY_SP } ;
23
+ use rustc_target:: spec:: abi:: Abi ;
23
24
24
25
use std:: cmp:: Ordering ;
25
26
use std:: iter;
@@ -95,10 +96,12 @@ struct Annotator<'a, 'tcx> {
95
96
impl < ' a , ' tcx > Annotator < ' a , ' tcx > {
96
97
// Determine the stability for a node based on its attributes and inherited
97
98
// 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
98
100
fn annotate < F > (
99
101
& mut self ,
100
102
hir_id : HirId ,
101
103
item_sp : Span ,
104
+ fn_sig : Option < & ' tcx hir:: FnSig < ' tcx > > ,
102
105
kind : AnnotationKind ,
103
106
inherit_deprecation : InheritDeprecation ,
104
107
inherit_const_stability : InheritConstStability ,
@@ -163,13 +166,30 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
163
166
}
164
167
165
168
let ( stab, const_stab) = attr:: find_stability ( & self . tcx . sess , attrs, item_sp) ;
169
+ let mut const_span = None ;
166
170
167
- let const_stab = const_stab. map ( |( const_stab, _ ) | {
171
+ let const_stab = const_stab. map ( |( const_stab, const_span_node ) | {
168
172
let const_stab = self . tcx . intern_const_stability ( const_stab) ;
169
173
self . index . const_stab_map . insert ( hir_id, const_stab) ;
174
+ const_span = Some ( const_span_node) ;
170
175
const_stab
171
176
} ) ;
172
177
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
+
173
193
// `impl const Trait for Type` items forward their const stability to their
174
194
// immediate children.
175
195
if const_stab. is_none ( ) {
@@ -367,6 +387,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
367
387
let orig_in_trait_impl = self . in_trait_impl ;
368
388
let mut kind = AnnotationKind :: Required ;
369
389
let mut const_stab_inherit = InheritConstStability :: No ;
390
+ let mut fn_sig = None ;
391
+
370
392
match i. kind {
371
393
// Inherent impls and foreign modules serve only as containers for other items,
372
394
// 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> {
387
409
self . annotate (
388
410
ctor_hir_id,
389
411
i. span ,
412
+ None ,
390
413
AnnotationKind :: Required ,
391
414
InheritDeprecation :: Yes ,
392
415
InheritConstStability :: No ,
@@ -395,12 +418,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
395
418
)
396
419
}
397
420
}
421
+ hir:: ItemKind :: Fn ( ref item_fn_sig, _, _) => {
422
+ fn_sig = Some ( item_fn_sig) ;
423
+ }
398
424
_ => { }
399
425
}
400
426
401
427
self . annotate (
402
428
i. hir_id ( ) ,
403
429
i. span ,
430
+ fn_sig,
404
431
kind,
405
432
InheritDeprecation :: Yes ,
406
433
const_stab_inherit,
@@ -411,9 +438,15 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
411
438
}
412
439
413
440
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
+
414
446
self . annotate (
415
447
ti. hir_id ( ) ,
416
448
ti. span ,
449
+ fn_sig,
417
450
AnnotationKind :: Required ,
418
451
InheritDeprecation :: Yes ,
419
452
InheritConstStability :: No ,
@@ -427,9 +460,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
427
460
fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem < ' tcx > ) {
428
461
let kind =
429
462
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
+
430
469
self . annotate (
431
470
ii. hir_id ( ) ,
432
471
ii. span ,
472
+ fn_sig,
433
473
kind,
434
474
InheritDeprecation :: Yes ,
435
475
InheritConstStability :: No ,
@@ -444,6 +484,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
444
484
self . annotate (
445
485
var. id ,
446
486
var. span ,
487
+ None ,
447
488
AnnotationKind :: Required ,
448
489
InheritDeprecation :: Yes ,
449
490
InheritConstStability :: No ,
@@ -453,6 +494,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
453
494
v. annotate (
454
495
ctor_hir_id,
455
496
var. span ,
497
+ None ,
456
498
AnnotationKind :: Required ,
457
499
InheritDeprecation :: Yes ,
458
500
InheritConstStability :: No ,
@@ -470,6 +512,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
470
512
self . annotate (
471
513
s. hir_id ,
472
514
s. span ,
515
+ None ,
473
516
AnnotationKind :: Required ,
474
517
InheritDeprecation :: Yes ,
475
518
InheritConstStability :: No ,
@@ -484,6 +527,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
484
527
self . annotate (
485
528
i. hir_id ( ) ,
486
529
i. span ,
530
+ None ,
487
531
AnnotationKind :: Required ,
488
532
InheritDeprecation :: Yes ,
489
533
InheritConstStability :: No ,
@@ -498,6 +542,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
498
542
self . annotate (
499
543
md. hir_id ( ) ,
500
544
md. span ,
545
+ None ,
501
546
AnnotationKind :: Required ,
502
547
InheritDeprecation :: Yes ,
503
548
InheritConstStability :: No ,
@@ -517,6 +562,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
517
562
self . annotate (
518
563
p. hir_id ,
519
564
p. span ,
565
+ None ,
520
566
kind,
521
567
InheritDeprecation :: No ,
522
568
InheritConstStability :: No ,
@@ -687,6 +733,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
687
733
annotator. annotate (
688
734
hir:: CRATE_HIR_ID ,
689
735
krate. item . inner ,
736
+ None ,
690
737
AnnotationKind :: Required ,
691
738
InheritDeprecation :: Yes ,
692
739
InheritConstStability :: No ,
@@ -969,3 +1016,15 @@ fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) {
969
1016
struct_span_err ! ( sess, span, E0636 , "the feature `{}` has already been declared" , feature)
970
1017
. emit ( ) ;
971
1018
}
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