@@ -30,6 +30,14 @@ pub enum StabilityLevel {
30
30
Stable ,
31
31
}
32
32
33
+ #[ derive( Copy , Clone ) ]
34
+ pub enum UnstableKind {
35
+ /// Enforcing regular stability of an item
36
+ Regular ,
37
+ /// Enforcing const stability of an item
38
+ Const ( Span ) ,
39
+ }
40
+
33
41
/// An entry in the `depr_map`.
34
42
#[ derive( Copy , Clone , HashStable , Debug , Encodable , Decodable ) ]
35
43
pub struct DeprecationEntry {
@@ -108,10 +116,16 @@ pub fn report_unstable(
108
116
is_soft : bool ,
109
117
span : Span ,
110
118
soft_handler : impl FnOnce ( & ' static Lint , Span , String ) ,
119
+ kind : UnstableKind ,
111
120
) {
121
+ let qual = match kind {
122
+ UnstableKind :: Regular => "" ,
123
+ UnstableKind :: Const ( _) => " const" ,
124
+ } ;
125
+
112
126
let msg = match reason {
113
- Some ( r) => format ! ( "use of unstable library feature `{feature}`: {r}" ) ,
114
- None => format ! ( "use of unstable library feature `{feature}`" ) ,
127
+ Some ( r) => format ! ( "use of unstable{qual} library feature `{feature}`: {r}" ) ,
128
+ None => format ! ( "use of unstable{qual} library feature `{feature}`" ) ,
115
129
} ;
116
130
117
131
if is_soft {
@@ -121,6 +135,9 @@ pub fn report_unstable(
121
135
if let Some ( ( inner_types, msg, sugg, applicability) ) = suggestion {
122
136
err. span_suggestion ( inner_types, msg, sugg, applicability) ;
123
137
}
138
+ if let UnstableKind :: Const ( kw) = kind {
139
+ err. span_label ( kw, "trait is not stable as const yet" ) ;
140
+ }
124
141
err. emit ( ) ;
125
142
}
126
143
}
@@ -587,13 +604,74 @@ impl<'tcx> TyCtxt<'tcx> {
587
604
is_soft,
588
605
span,
589
606
soft_handler,
607
+ UnstableKind :: Regular ,
590
608
) ,
591
609
EvalResult :: Unmarked => unmarked ( span, def_id) ,
592
610
}
593
611
594
612
is_allowed
595
613
}
596
614
615
+ pub fn check_const_stability ( self , def_id : DefId , span : Span , const_kw_span : Span ) {
616
+ let is_staged_api = self . lookup_stability ( def_id. krate . as_def_id ( ) ) . is_some ( ) ;
617
+ if !is_staged_api {
618
+ return ;
619
+ }
620
+
621
+ // Only the cross-crate scenario matters when checking unstable APIs
622
+ let cross_crate = !def_id. is_local ( ) ;
623
+ if !cross_crate {
624
+ return ;
625
+ }
626
+
627
+ let stability = self . lookup_const_stability ( def_id) ;
628
+ debug ! (
629
+ "stability: \
630
+ inspecting def_id={:?} span={:?} of stability={:?}",
631
+ def_id, span, stability
632
+ ) ;
633
+
634
+ match stability {
635
+ Some ( ConstStability {
636
+ level : attr:: StabilityLevel :: Unstable { reason, issue, is_soft, implied_by, .. } ,
637
+ feature,
638
+ ..
639
+ } ) => {
640
+ assert ! ( !is_soft) ;
641
+
642
+ if span. allows_unstable ( feature) {
643
+ debug ! ( "body stability: skipping span={:?} since it is internal" , span) ;
644
+ return ;
645
+ }
646
+ if self . features ( ) . enabled ( feature) {
647
+ return ;
648
+ }
649
+
650
+ // If this item was previously part of a now-stabilized feature which is still
651
+ // enabled (i.e. the user hasn't removed the attribute for the stabilized feature
652
+ // yet) then allow use of this item.
653
+ if let Some ( implied_by) = implied_by
654
+ && self . features ( ) . enabled ( implied_by)
655
+ {
656
+ return ;
657
+ }
658
+
659
+ report_unstable (
660
+ self . sess ,
661
+ feature,
662
+ reason. to_opt_reason ( ) ,
663
+ issue,
664
+ None ,
665
+ false ,
666
+ span,
667
+ |_, _, _| { } ,
668
+ UnstableKind :: Const ( const_kw_span) ,
669
+ ) ;
670
+ }
671
+ Some ( _) | None => { }
672
+ }
673
+ }
674
+
597
675
pub fn lookup_deprecation ( self , id : DefId ) -> Option < Deprecation > {
598
676
self . lookup_deprecation_entry ( id) . map ( |depr| depr. attr )
599
677
}
0 commit comments