11//! A pass that annotates every item and method with its stability level,
22//! propagating default levels lexically from parent to children ast nodes.
33
4- use rustc_ast:: Attribute ;
54use rustc_attr:: { self as attr, ConstStability , Stability } ;
6- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
5+ use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap } ;
76use rustc_errors:: struct_span_err;
87use rustc_hir as hir;
98use rustc_hir:: def:: { DefKind , Res } ;
10- use rustc_hir:: def_id:: { DefId , LocalDefId , CRATE_DEF_ID , CRATE_DEF_INDEX , LOCAL_CRATE } ;
9+ use rustc_hir:: def_id:: { DefId , LocalDefId , CRATE_DEF_ID , CRATE_DEF_INDEX } ;
1110use rustc_hir:: hir_id:: CRATE_HIR_ID ;
1211use rustc_hir:: intravisit:: { self , Visitor } ;
1312use rustc_hir:: { FieldDef , Generics , HirId , Item , TraitRef , Ty , TyKind , Variant } ;
@@ -113,12 +112,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
113112 {
114113 let attrs = self . tcx . get_attrs ( def_id. to_def_id ( ) ) ;
115114 debug ! ( "annotate(id = {:?}, attrs = {:?})" , def_id, attrs) ;
116- let mut did_error = false ;
117- if !self . tcx . features ( ) . staged_api {
118- did_error = self . forbid_staged_api_attrs ( def_id, attrs, inherit_deprecation. clone ( ) ) ;
119- }
120115
121- let depr = if did_error { None } else { attr:: find_deprecation ( & self . tcx . sess , attrs) } ;
116+ let depr = attr:: find_deprecation ( & self . tcx . sess , attrs) ;
122117 let mut is_deprecated = false ;
123118 if let Some ( ( depr, span) ) = & depr {
124119 is_deprecated = true ;
@@ -148,16 +143,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
148143 }
149144 }
150145
151- if self . tcx . features ( ) . staged_api {
152- if let Some ( a) = attrs. iter ( ) . find ( |a| a. has_name ( sym:: deprecated) ) {
153- self . tcx
154- . sess
155- . struct_span_err ( a. span , "`#[deprecated]` cannot be used in staged API" )
156- . span_label ( a. span , "use `#[rustc_deprecated]` instead" )
157- . span_label ( item_sp, "" )
158- . emit ( ) ;
146+ if !self . tcx . features ( ) . staged_api {
147+ // Propagate unstability. This can happen even for non-staged-api crates in case
148+ // -Zforce-unstable-if-unmarked is set.
149+ if let Some ( stab) = self . parent_stab {
150+ if inherit_deprecation. yes ( ) && stab. level . is_unstable ( ) {
151+ self . index . stab_map . insert ( def_id, stab) ;
152+ }
159153 }
160- } else {
154+
161155 self . recurse_with_stability_attrs (
162156 depr. map ( |( d, _) | DeprecationEntry :: local ( d, def_id) ) ,
163157 None ,
@@ -329,47 +323,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
329323 self . parent_const_stab = orig_parent_const_stab;
330324 }
331325 }
332-
333- // returns true if an error occurred, used to suppress some spurious errors
334- fn forbid_staged_api_attrs (
335- & mut self ,
336- def_id : LocalDefId ,
337- attrs : & [ Attribute ] ,
338- inherit_deprecation : InheritDeprecation ,
339- ) -> bool {
340- // Emit errors for non-staged-api crates.
341- let unstable_attrs = [
342- sym:: unstable,
343- sym:: stable,
344- sym:: rustc_deprecated,
345- sym:: rustc_const_unstable,
346- sym:: rustc_const_stable,
347- ] ;
348- let mut has_error = false ;
349- for attr in attrs {
350- let name = attr. name_or_empty ( ) ;
351- if unstable_attrs. contains ( & name) {
352- struct_span_err ! (
353- self . tcx. sess,
354- attr. span,
355- E0734 ,
356- "stability attributes may not be used outside of the standard library" ,
357- )
358- . emit ( ) ;
359- has_error = true ;
360- }
361- }
362-
363- // Propagate unstability. This can happen even for non-staged-api crates in case
364- // -Zforce-unstable-if-unmarked is set.
365- if let Some ( stab) = self . parent_stab {
366- if inherit_deprecation. yes ( ) && stab. level . is_unstable ( ) {
367- self . index . stab_map . insert ( def_id, stab) ;
368- }
369- }
370-
371- has_error
372- }
373326}
374327
375328impl < ' a , ' tcx > Visitor < ' tcx > for Annotator < ' a , ' tcx > {
@@ -654,28 +607,12 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
654607}
655608
656609fn stability_index ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> Index {
657- let is_staged_api =
658- tcx. sess . opts . debugging_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ;
659- let mut staged_api = FxHashMap :: default ( ) ;
660- staged_api. insert ( LOCAL_CRATE , is_staged_api) ;
661610 let mut index = Index {
662- staged_api,
663611 stab_map : Default :: default ( ) ,
664612 const_stab_map : Default :: default ( ) ,
665613 depr_map : Default :: default ( ) ,
666- active_features : Default :: default ( ) ,
667614 } ;
668615
669- let active_lib_features = & tcx. features ( ) . declared_lib_features ;
670- let active_lang_features = & tcx. features ( ) . declared_lang_features ;
671-
672- // Put the active features into a map for quick lookup.
673- index. active_features = active_lib_features
674- . iter ( )
675- . map ( |& ( s, ..) | s)
676- . chain ( active_lang_features. iter ( ) . map ( |& ( s, ..) | s) )
677- . collect ( ) ;
678-
679616 {
680617 let mut annotator = Annotator {
681618 tcx,
@@ -728,7 +665,16 @@ fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
728665}
729666
730667pub ( crate ) fn provide ( providers : & mut Providers ) {
731- * providers = Providers { check_mod_unstable_api_usage, stability_index, ..* providers } ;
668+ * providers = Providers {
669+ check_mod_unstable_api_usage,
670+ stability_index,
671+ lookup_stability : |tcx, id| tcx. stability ( ) . local_stability ( id. expect_local ( ) ) ,
672+ lookup_const_stability : |tcx, id| tcx. stability ( ) . local_const_stability ( id. expect_local ( ) ) ,
673+ lookup_deprecation_entry : |tcx, id| {
674+ tcx. stability ( ) . local_deprecation_entry ( id. expect_local ( ) )
675+ } ,
676+ ..* providers
677+ } ;
732678}
733679
734680struct Checker < ' tcx > {
@@ -884,9 +830,10 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
884830/// were expected to be library features), and the list of features used from
885831/// libraries, identify activated features that don't exist and error about them.
886832pub fn check_unused_or_stable_features ( tcx : TyCtxt < ' _ > ) {
887- let access_levels = & tcx. privacy_access_levels ( ( ) ) ;
888-
889- if tcx. stability ( ) . staged_api [ & LOCAL_CRATE ] {
833+ let is_staged_api =
834+ tcx. sess . opts . debugging_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ;
835+ if is_staged_api {
836+ let access_levels = & tcx. privacy_access_levels ( ( ) ) ;
890837 let mut missing = MissingStabilityAnnotations { tcx, access_levels } ;
891838 missing. check_missing_stability ( CRATE_DEF_ID , tcx. hir ( ) . span ( CRATE_HIR_ID ) ) ;
892839 tcx. hir ( ) . walk_toplevel_module ( & mut missing) ;
@@ -907,7 +854,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
907854 }
908855
909856 let declared_lib_features = & tcx. features ( ) . declared_lib_features ;
910- let mut remaining_lib_features = FxHashMap :: default ( ) ;
857+ let mut remaining_lib_features = FxIndexMap :: default ( ) ;
911858 for ( feature, span) in declared_lib_features {
912859 if !tcx. sess . opts . unstable_features . is_nightly_build ( ) {
913860 struct_span_err ! (
@@ -934,7 +881,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
934881 remaining_lib_features. remove ( & sym:: libc) ;
935882 remaining_lib_features. remove ( & sym:: test) ;
936883
937- let check_features = |remaining_lib_features : & mut FxHashMap < _ , _ > , defined_features : & [ _ ] | {
884+ let check_features = |remaining_lib_features : & mut FxIndexMap < _ , _ > , defined_features : & [ _ ] | {
938885 for & ( feature, since) in defined_features {
939886 if let Some ( since) = since {
940887 if let Some ( span) = remaining_lib_features. get ( & feature) {
0 commit comments