summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_passes/src/stability.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_passes/src/stability.rs')
-rw-r--r--compiler/rustc_passes/src/stability.rs61
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 });
}