diff options
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/middle/mod.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/stability.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 8 |
3 files changed, 36 insertions, 10 deletions
diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index fc35cafcc77..8dc68b1f5a8 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -3,14 +3,14 @@ pub mod dependency_format; pub mod exported_symbols; pub mod lang_items; pub mod lib_features { - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; - use rustc_span::symbol::Symbol; + use rustc_data_structures::fx::FxHashMap; + use rustc_span::{symbol::Symbol, Span}; #[derive(HashStable, Debug)] pub struct LibFeatures { - // A map from feature to stabilisation version. - pub stable: FxHashMap<Symbol, Symbol>, - pub unstable: FxHashSet<Symbol>, + /// A map from feature to stabilisation version. + pub stable: FxHashMap<Symbol, (Symbol, Span)>, + pub unstable: FxHashMap<Symbol, Span>, } impl LibFeatures { @@ -18,8 +18,8 @@ pub mod lib_features { let mut all_features: Vec<_> = self .stable .iter() - .map(|(f, s)| (*f, Some(*s))) - .chain(self.unstable.iter().map(|f| (*f, None))) + .map(|(f, (s, _))| (*f, Some(*s))) + .chain(self.unstable.iter().map(|(f, _)| (*f, None))) .collect(); all_features.sort_unstable_by(|a, b| a.0.as_str().partial_cmp(b.0.as_str()).unwrap()); all_features diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 96e068a3601..0fbad3f0f0f 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -62,6 +62,19 @@ pub struct Index { pub stab_map: FxHashMap<LocalDefId, Stability>, pub const_stab_map: FxHashMap<LocalDefId, ConstStability>, pub depr_map: FxHashMap<LocalDefId, DeprecationEntry>, + /// Mapping from feature name to feature name based on the `implied_by` field of `#[unstable]` + /// attributes. If a `#[unstable(feature = "implier", implied_by = "impliee")]` attribute + /// exists, then this map will have a `impliee -> implier` entry. + /// + /// This mapping is necessary unless both the `#[stable]` and `#[unstable]` attributes should + /// specify their implications (both `implies` and `implied_by`). If only one of the two + /// attributes do (as in the current implementation, `implied_by` in `#[unstable]`), then this + /// mapping is necessary for diagnostics. When a "unnecessary feature attribute" error is + /// reported, only the `#[stable]` attribute information is available, so the map is necessary + /// to know that the feature implies another feature. If it were reversed, and the `#[stable]` + /// attribute had an `implies` meta item, then a map would be necessary when avoiding a "use of + /// unstable feature" error for a feature that was implied. + pub implications: FxHashMap<Symbol, Symbol>, } impl Index { @@ -423,7 +436,9 @@ impl<'tcx> TyCtxt<'tcx> { match stability { Some(Stability { - level: attr::Unstable { reason, issue, is_soft }, feature, .. + level: attr::Unstable { reason, issue, is_soft, implied_by }, + feature, + .. }) => { if span.allows_unstable(feature) { debug!("stability: skipping span={:?} since it is internal", span); @@ -433,6 +448,13 @@ impl<'tcx> TyCtxt<'tcx> { return EvalResult::Allow; } + // If this item was previously part of a now-stabilized feature which is still + // active (i.e. the user hasn't removed the attribute for the stabilized feature + // yet) then allow use of this item. + if let Some(implied_by) = implied_by && self.features().active(implied_by) { + return EvalResult::Allow; + } + // When we're compiling the compiler itself we may pull in // crates from crates.io, but those crates may depend on other // crates also pulled in from crates.io. We want to ideally be diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0581ef41f66..466a0fc25f7 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1634,11 +1634,15 @@ rustc_queries! { storage(ArenaCacheSelector<'tcx>) desc { "calculating the lib features map" } } - query defined_lib_features(_: CrateNum) - -> &'tcx [(Symbol, Option<Symbol>)] { + query defined_lib_features(_: CrateNum) -> &'tcx [(Symbol, Option<Symbol>)] { desc { "calculating the lib features defined in a crate" } separate_provide_extern } + query stability_implications(_: CrateNum) -> FxHashMap<Symbol, Symbol> { + storage(ArenaCacheSelector<'tcx>) + desc { "calculating the implications between `#[unstable]` features defined in a crate" } + separate_provide_extern + } /// Whether the function is an intrinsic query is_intrinsic(def_id: DefId) -> bool { desc { |tcx| "is_intrinsic({})", tcx.def_path_str(def_id) } |
