Skip to content

Commit 2d187d5

Browse files
Store feature stability un-split
1 parent 86299a1 commit 2d187d5

File tree

5 files changed

+36
-54
lines changed

5 files changed

+36
-54
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -1177,19 +1177,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11771177
}
11781178

11791179
/// Iterates over all the stability attributes in the given crate.
1180-
fn get_lib_features(self, _tcx: TyCtxt<'tcx>) -> LibFeatures {
1181-
let mut features = LibFeatures::default();
1182-
for (symbol, stability) in self.root.lib_features.decode(self) {
1183-
match stability {
1184-
FeatureStability::AcceptedSince(since) => {
1185-
features.stable.insert(symbol, (since, DUMMY_SP));
1186-
}
1187-
FeatureStability::Unstable => {
1188-
features.unstable.insert(symbol, DUMMY_SP);
1189-
}
1190-
}
1180+
fn get_lib_features(self) -> LibFeatures {
1181+
LibFeatures {
1182+
stability: self
1183+
.root
1184+
.lib_features
1185+
.decode(self)
1186+
.map(|(sym, stab)| (sym, (stab, DUMMY_SP)))
1187+
.collect(),
11911188
}
1192-
features
11931189
}
11941190

11951191
/// Iterates over the stability implications in the given crate (when a `#[unstable]` attribute

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ provide! { tcx, def_id, other, cdata,
346346
module_children => {
347347
tcx.arena.alloc_from_iter(cdata.get_module_children(def_id.index, tcx.sess))
348348
}
349-
lib_features => { cdata.get_lib_features(tcx) }
349+
lib_features => { cdata.get_lib_features() }
350350
stability_implications => {
351351
cdata.get_stability_implications(tcx).iter().copied().collect()
352352
}

compiler/rustc_middle/src/middle/mod.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,14 @@ pub mod lib_features {
1616

1717
#[derive(HashStable, Debug, Default)]
1818
pub struct LibFeatures {
19-
/// A map from feature to stabilisation version.
20-
pub stable: FxHashMap<Symbol, (Symbol, Span)>,
21-
pub unstable: FxHashMap<Symbol, Span>,
19+
pub stability: FxHashMap<Symbol, (FeatureStability, Span)>,
2220
}
2321

2422
impl LibFeatures {
2523
pub fn to_vec(&self) -> Vec<(Symbol, FeatureStability)> {
26-
let mut all_features: Vec<_> = self
27-
.stable
28-
.iter()
29-
.map(|(f, (s, _))| (*f, FeatureStability::AcceptedSince(*s)))
30-
.chain(self.unstable.iter().map(|(f, _)| (*f, FeatureStability::Unstable)))
31-
.collect();
32-
all_features.sort_unstable_by(|a, b| a.0.as_str().partial_cmp(b.0.as_str()).unwrap());
24+
let mut all_features: Vec<_> =
25+
self.stability.iter().map(|(&sym, &(stab, _))| (sym, stab)).collect();
26+
all_features.sort_unstable_by(|(a, _), (b, _)| a.as_str().cmp(b.as_str()));
3327
all_features
3428
}
3529
}

compiler/rustc_passes/src/lib_features.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -86,44 +86,38 @@ impl<'tcx> LibFeatureCollector<'tcx> {
8686
}
8787

8888
fn collect_feature(&mut self, feature: Symbol, stability: FeatureStability, span: Span) {
89-
let already_in_stable = self.lib_features.stable.contains_key(&feature);
90-
let already_in_unstable = self.lib_features.unstable.contains_key(&feature);
89+
let existing_stability = self.lib_features.stability.get(&feature).cloned();
9190

92-
match (stability, already_in_stable, already_in_unstable) {
93-
(FeatureStability::AcceptedSince(since), _, false) => {
94-
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature)
95-
&& *prev_since != since
96-
{
97-
self.tcx.sess.emit_err(FeatureStableTwice {
98-
span,
99-
feature,
100-
since,
101-
prev_since: *prev_since,
102-
});
103-
return;
91+
match (stability, existing_stability) {
92+
(_, None) => {
93+
self.lib_features.stability.insert(feature, (stability, span));
94+
}
95+
(
96+
FeatureStability::AcceptedSince(since),
97+
Some((FeatureStability::AcceptedSince(prev_since), _)),
98+
) => {
99+
if prev_since != since {
100+
self.tcx.sess.emit_err(FeatureStableTwice { span, feature, since, prev_since });
104101
}
105-
106-
self.lib_features.stable.insert(feature, (since, span));
107102
}
108-
(FeatureStability::AcceptedSince(_), _, true) => {
103+
(FeatureStability::AcceptedSince(_), Some((FeatureStability::Unstable, _))) => {
109104
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
110105
span,
111106
feature,
112107
declared: "stable",
113108
prev_declared: "unstable",
114109
});
115110
}
116-
(FeatureStability::Unstable, false, _) => {
117-
self.lib_features.unstable.insert(feature, span);
118-
}
119-
(FeatureStability::Unstable, true, _) => {
111+
(FeatureStability::Unstable, Some((FeatureStability::AcceptedSince(_), _))) => {
120112
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
121113
span,
122114
feature,
123115
declared: "unstable",
124116
prev_declared: "stable",
125117
});
126118
}
119+
// duplicate `unstable` feature is ok.
120+
(FeatureStability::Unstable, Some((FeatureStability::Unstable, _))) => {}
127121
}
128122
}
129123
}

compiler/rustc_passes/src/stability.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_attr::{
99
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
1010
use rustc_hir as hir;
1111
use rustc_hir::def::{DefKind, Res};
12-
use rustc_hir::def_id::{LocalDefId, LocalModDefId, CRATE_DEF_ID};
12+
use rustc_hir::def_id::{LocalDefId, LocalModDefId, CRATE_DEF_ID, LOCAL_CRATE};
1313
use rustc_hir::hir_id::CRATE_HIR_ID;
1414
use rustc_hir::intravisit::{self, Visitor};
1515
use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
@@ -1008,12 +1008,11 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10081008
}
10091009

10101010
// All local crate implications need to have the feature that implies it confirmed to exist.
1011-
let mut remaining_implications =
1012-
tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
1011+
let mut remaining_implications = tcx.stability_implications(LOCAL_CRATE).clone();
10131012

10141013
// We always collect the lib features declared in the current crate, even if there are
10151014
// no unknown features, because the collection also does feature attribute validation.
1016-
let local_defined_features = tcx.lib_features(rustc_hir::def_id::LOCAL_CRATE);
1015+
let local_defined_features = tcx.lib_features(LOCAL_CRATE);
10171016
if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
10181017
// Loading the implications of all crates is unavoidable to be able to emit the partial
10191018
// stabilization diagnostic, but it can be avoided when there are no
@@ -1050,13 +1049,12 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10501049
}
10511050

10521051
for (implied_by, feature) in remaining_implications {
1053-
let local_defined_features = tcx.lib_features(rustc_hir::def_id::LOCAL_CRATE);
1054-
let span = *local_defined_features
1055-
.stable
1052+
let local_defined_features = tcx.lib_features(LOCAL_CRATE);
1053+
let span = local_defined_features
1054+
.stability
10561055
.get(&feature)
1057-
.map(|(_, span)| span)
1058-
.or_else(|| local_defined_features.unstable.get(&feature))
1059-
.expect("feature that implied another does not exist");
1056+
.expect("feature that implied another does not exist")
1057+
.1;
10601058
tcx.sess.emit_err(errors::ImpliedFeatureNotExist { span, feature, implied_by });
10611059
}
10621060

0 commit comments

Comments
 (0)