diff options
Diffstat (limited to 'compiler/rustc_passes/src/stability.rs')
-rw-r--r-- | compiler/rustc_passes/src/stability.rs | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 6a2498f3f..676622cef 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -9,11 +9,12 @@ use rustc_attr::{ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{LocalDefId, LocalModDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::{LocalDefId, LocalModDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::hir_id::CRATE_HIR_ID; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant}; use rustc_middle::hir::nested_filter; +use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index}; use rustc_middle::query::Providers; @@ -110,7 +111,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { ) where F: FnOnce(&mut Self), { - let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id)); + let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); let depr = attr::find_deprecation(self.tcx.sess, self.tcx.features(), attrs); @@ -119,7 +120,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { is_deprecated = true; if matches!(kind, AnnotationKind::Prohibited | AnnotationKind::DeprecationProhibited) { - let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + let hir_id = self.tcx.local_def_id_to_hir_id(def_id); self.tcx.emit_spanned_lint( USELESS_DEPRECATED, hir_id, @@ -157,9 +158,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { return; } - let stab = attr::find_stability(&self.tcx.sess, attrs, item_sp); - let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item_sp); - let body_stab = attr::find_body_stability(&self.tcx.sess, attrs); + let stab = attr::find_stability(self.tcx.sess, attrs, item_sp); + let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item_sp); + let body_stab = attr::find_body_stability(self.tcx.sess, attrs); let mut const_span = None; let const_stab = const_stab.map(|(const_stab, const_span_node)| { @@ -196,7 +197,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } } - if let Some((depr, span)) = &depr && depr.is_since_rustc_version() && stab.is_none() { + if let Some((depr, span)) = &depr + && depr.is_since_rustc_version() + && stab.is_none() + { self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span }); } @@ -717,8 +721,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { let features = self.tcx.features(); if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); - let stab = attr::find_stability(&self.tcx.sess, attrs, item.span); - let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item.span); + let stab = attr::find_stability(self.tcx.sess, attrs, item.span); + let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item.span); // If this impl block has an #[unstable] attribute, give an // error if all involved types and traits are stable, because @@ -975,29 +979,27 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { tcx: TyCtxt<'tcx>, remaining_lib_features: &mut FxIndexMap<&Symbol, Span>, remaining_implications: &mut FxHashMap<Symbol, Symbol>, - defined_features: &[(Symbol, Option<Symbol>)], + defined_features: &LibFeatures, all_implications: &FxHashMap<Symbol, Symbol>, ) { - for (feature, since) in defined_features { - if let Some(since) = since + for (feature, since) in defined_features.to_vec() { + if let FeatureStability::AcceptedSince(since) = since && let Some(span) = remaining_lib_features.get(&feature) { // Warn if the user has enabled an already-stable lib feature. if let Some(implies) = all_implications.get(&feature) { - unnecessary_partially_stable_feature_lint( - tcx, *span, *feature, *implies, *since, - ); + unnecessary_partially_stable_feature_lint(tcx, *span, feature, *implies, since); } else { - unnecessary_stable_feature_lint(tcx, *span, *feature, *since); + unnecessary_stable_feature_lint(tcx, *span, feature, since); } } - remaining_lib_features.remove(feature); + remaining_lib_features.remove(&feature); // `feature` is the feature doing the implying, but `implied_by` is the feature with // the attribute that establishes this relationship. `implied_by` is guaranteed to be a // feature defined in the local crate because `remaining_implications` is only the // implications from this crate. - remaining_implications.remove(feature); + remaining_implications.remove(&feature); if remaining_lib_features.is_empty() && remaining_implications.is_empty() { break; @@ -1006,12 +1008,11 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { } // All local crate implications need to have the feature that implies it confirmed to exist. - let mut remaining_implications = - tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone(); + let mut remaining_implications = tcx.stability_implications(LOCAL_CRATE).clone(); // We always collect the lib features declared in the current crate, even if there are // no unknown features, because the collection also does feature attribute validation. - let local_defined_features = tcx.lib_features(()).to_vec(); + let local_defined_features = tcx.lib_features(LOCAL_CRATE); if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() { // Loading the implications of all crates is unavoidable to be able to emit the partial // stabilization diagnostic, but it can be avoided when there are no @@ -1025,7 +1026,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { tcx, &mut remaining_lib_features, &mut remaining_implications, - local_defined_features.as_slice(), + local_defined_features, &all_implications, ); @@ -1037,7 +1038,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { tcx, &mut remaining_lib_features, &mut remaining_implications, - tcx.defined_lib_features(cnum).to_vec().as_slice(), + tcx.lib_features(cnum), &all_implications, ); } @@ -1047,14 +1048,16 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { tcx.sess.emit_err(errors::UnknownFeature { span, feature: *feature }); } + // We only use the hash map contents to emit errors, and the order of + // emitted errors do not affect query stability. + #[allow(rustc::potential_query_instability)] for (implied_by, feature) in remaining_implications { - let local_defined_features = tcx.lib_features(()); - let span = *local_defined_features - .stable + let local_defined_features = tcx.lib_features(LOCAL_CRATE); + let span = local_defined_features + .stability .get(&feature) - .map(|(_, span)| span) - .or_else(|| local_defined_features.unstable.get(&feature)) - .expect("feature that implied another does not exist"); + .expect("feature that implied another does not exist") + .1; tcx.sess.emit_err(errors::ImpliedFeatureNotExist { span, feature, implied_by }); } |