@@ -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,81 @@ 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
+ /// This function is analogous to `check_optional_stability` but with the logic in
616
+ /// `eval_stability_allow_unstable` inlined, and which operating on const stability
617
+ /// instead of regular stability.
618
+ ///
619
+ /// This enforces *syntactical* const stability of const traits. In other words,
620
+ /// it enforces the ability to name `~const`/`const` traits in trait bounds in various
621
+ /// syntax positions in HIR (including in the trait of an impl header).
622
+ pub fn check_const_stability ( self , def_id : DefId , span : Span , const_kw_span : Span ) {
623
+ let is_staged_api = self . lookup_stability ( def_id. krate . as_def_id ( ) ) . is_some ( ) ;
624
+ if !is_staged_api {
625
+ return ;
626
+ }
627
+
628
+ // Only the cross-crate scenario matters when checking unstable APIs
629
+ let cross_crate = !def_id. is_local ( ) ;
630
+ if !cross_crate {
631
+ return ;
632
+ }
633
+
634
+ let stability = self . lookup_const_stability ( def_id) ;
635
+ debug ! (
636
+ "stability: \
637
+ inspecting def_id={:?} span={:?} of stability={:?}",
638
+ def_id, span, stability
639
+ ) ;
640
+
641
+ match stability {
642
+ Some ( ConstStability {
643
+ level : attr:: StabilityLevel :: Unstable { reason, issue, is_soft, implied_by, .. } ,
644
+ feature,
645
+ ..
646
+ } ) => {
647
+ assert ! ( !is_soft) ;
648
+
649
+ if span. allows_unstable ( feature) {
650
+ debug ! ( "body stability: skipping span={:?} since it is internal" , span) ;
651
+ return ;
652
+ }
653
+ if self . features ( ) . enabled ( feature) {
654
+ return ;
655
+ }
656
+
657
+ // If this item was previously part of a now-stabilized feature which is still
658
+ // enabled (i.e. the user hasn't removed the attribute for the stabilized feature
659
+ // yet) then allow use of this item.
660
+ if let Some ( implied_by) = implied_by
661
+ && self . features ( ) . enabled ( implied_by)
662
+ {
663
+ return ;
664
+ }
665
+
666
+ report_unstable (
667
+ self . sess ,
668
+ feature,
669
+ reason. to_opt_reason ( ) ,
670
+ issue,
671
+ None ,
672
+ false ,
673
+ span,
674
+ |_, _, _| { } ,
675
+ UnstableKind :: Const ( const_kw_span) ,
676
+ ) ;
677
+ }
678
+ Some ( _) | None => { }
679
+ }
680
+ }
681
+
597
682
pub fn lookup_deprecation ( self , id : DefId ) -> Option < Deprecation > {
598
683
self . lookup_deprecation_entry ( id) . map ( |depr| depr. attr )
599
684
}
0 commit comments