Skip to content

Commit 86299a1

Browse files
Unify defined_lib_features and lib_features queries
1 parent 46ecc10 commit 86299a1

File tree

9 files changed

+83
-60
lines changed

9 files changed

+83
-60
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_index::{Idx, IndexVec};
2121
use rustc_middle::metadata::ModChild;
2222
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2323
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
24+
use rustc_middle::middle::lib_features::LibFeatures;
2425
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2526
use rustc_middle::ty::codec::TyDecoder;
2627
use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -828,7 +829,7 @@ impl MetadataBlob {
828829
out,
829830
"{}{}",
830831
feature,
831-
if let Some(since) = since {
832+
if let FeatureStability::AcceptedSince(since) = since {
832833
format!(" since {since}")
833834
} else {
834835
String::new()
@@ -1176,8 +1177,19 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11761177
}
11771178

11781179
/// Iterates over all the stability attributes in the given crate.
1179-
fn get_lib_features(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
1180-
tcx.arena.alloc_from_iter(self.root.lib_features.decode(self))
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+
}
1191+
}
1192+
features
11811193
}
11821194

11831195
/// 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-
defined_lib_features => { cdata.get_lib_features(tcx) }
349+
lib_features => { cdata.get_lib_features(tcx) }
350350
stability_implications => {
351351
cdata.get_stability_implications(tcx).iter().copied().collect()
352352
}

compiler/rustc_metadata/src/rmeta/encoder.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_middle::middle::dependency_format::Linkage;
2525
use rustc_middle::middle::exported_symbols::{
2626
metadata_symbol_name, ExportedSymbol, SymbolExportInfo,
2727
};
28+
use rustc_middle::middle::lib_features::FeatureStability;
2829
use rustc_middle::mir::interpret;
2930
use rustc_middle::query::LocalCrate;
3031
use rustc_middle::query::Providers;
@@ -1902,10 +1903,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
19021903
self.lazy_array(deps.iter().map(|(_, dep)| dep))
19031904
}
19041905

1905-
fn encode_lib_features(&mut self) -> LazyArray<(Symbol, Option<Symbol>)> {
1906+
fn encode_lib_features(&mut self) -> LazyArray<(Symbol, FeatureStability)> {
19061907
empty_proc_macro!(self);
19071908
let tcx = self.tcx;
1908-
let lib_features = tcx.lib_features(());
1909+
let lib_features = tcx.lib_features(LOCAL_CRATE);
19091910
self.lazy_array(lib_features.to_vec())
19101911
}
19111912

compiler/rustc_metadata/src/rmeta/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use decoder::Metadata;
33
use def_path_hash_map::DefPathHashMapRef;
44
use rustc_data_structures::fx::FxHashMap;
55
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
6+
use rustc_middle::middle::lib_features::FeatureStability;
67
use table::TableBuilder;
78

89
use rustc_ast as ast;
@@ -263,7 +264,7 @@ pub(crate) struct CrateRoot {
263264

264265
crate_deps: LazyArray<CrateDep>,
265266
dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,
266-
lib_features: LazyArray<(Symbol, Option<Symbol>)>,
267+
lib_features: LazyArray<(Symbol, FeatureStability)>,
267268
stability_implications: LazyArray<(Symbol, Symbol)>,
268269
lang_items: LazyArray<(DefIndex, LangItem)>,
269270
lang_items_missing: LazyArray<LangItem>,

compiler/rustc_middle/src/middle/mod.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,27 @@ pub mod lib_features {
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_span::{symbol::Symbol, Span};
99

10-
#[derive(HashStable, Debug)]
10+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11+
#[derive(HashStable, TyEncodable, TyDecodable)]
12+
pub enum FeatureStability {
13+
AcceptedSince(Symbol),
14+
Unstable,
15+
}
16+
17+
#[derive(HashStable, Debug, Default)]
1118
pub struct LibFeatures {
1219
/// A map from feature to stabilisation version.
1320
pub stable: FxHashMap<Symbol, (Symbol, Span)>,
1421
pub unstable: FxHashMap<Symbol, Span>,
1522
}
1623

1724
impl LibFeatures {
18-
pub fn to_vec(&self) -> Vec<(Symbol, Option<Symbol>)> {
25+
pub fn to_vec(&self) -> Vec<(Symbol, FeatureStability)> {
1926
let mut all_features: Vec<_> = self
2027
.stable
2128
.iter()
22-
.map(|(f, (s, _))| (*f, Some(*s)))
23-
.chain(self.unstable.keys().map(|f| (*f, None)))
29+
.map(|(f, (s, _))| (*f, FeatureStability::AcceptedSince(*s)))
30+
.chain(self.unstable.iter().map(|(f, _)| (*f, FeatureStability::Unstable)))
2431
.collect();
2532
all_features.sort_unstable_by(|a, b| a.0.as_str().partial_cmp(b.0.as_str()).unwrap());
2633
all_features

compiler/rustc_middle/src/query/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1732,13 +1732,10 @@ rustc_queries! {
17321732
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
17331733
}
17341734

1735-
query lib_features(_: ()) -> &'tcx LibFeatures {
1736-
arena_cache
1737-
desc { "calculating the lib features map" }
1738-
}
1739-
query defined_lib_features(_: CrateNum) -> &'tcx [(Symbol, Option<Symbol>)] {
1735+
query lib_features(_: CrateNum) -> &'tcx LibFeatures {
17401736
desc { "calculating the lib features defined in a crate" }
17411737
separate_provide_extern
1738+
arena_cache
17421739
}
17431740
query stability_implications(_: CrateNum) -> &'tcx FxHashMap<Symbol, Symbol> {
17441741
arena_cache

compiler/rustc_middle/src/ty/parameterized.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ trivially_parameterized_over_tcx! {
5959
crate::middle::codegen_fn_attrs::CodegenFnAttrs,
6060
crate::middle::debugger_visualizer::DebuggerVisualizerFile,
6161
crate::middle::exported_symbols::SymbolExportInfo,
62+
crate::middle::lib_features::FeatureStability,
6263
crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
6364
crate::mir::ConstQualifs,
6465
ty::AssocItemContainer,

compiler/rustc_passes/src/lib_features.rs

+36-31
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,25 @@ use rustc_ast::Attribute;
88
use rustc_attr::VERSION_PLACEHOLDER;
99
use rustc_hir::intravisit::Visitor;
1010
use rustc_middle::hir::nested_filter;
11-
use rustc_middle::middle::lib_features::LibFeatures;
12-
use rustc_middle::query::Providers;
11+
use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
12+
use rustc_middle::query::{LocalCrate, Providers};
1313
use rustc_middle::ty::TyCtxt;
1414
use rustc_span::symbol::Symbol;
1515
use rustc_span::{sym, Span};
1616

1717
use crate::errors::{FeaturePreviouslyDeclared, FeatureStableTwice};
1818

19-
fn new_lib_features() -> LibFeatures {
20-
LibFeatures { stable: Default::default(), unstable: Default::default() }
21-
}
22-
2319
pub struct LibFeatureCollector<'tcx> {
2420
tcx: TyCtxt<'tcx>,
2521
lib_features: LibFeatures,
2622
}
2723

2824
impl<'tcx> LibFeatureCollector<'tcx> {
2925
fn new(tcx: TyCtxt<'tcx>) -> LibFeatureCollector<'tcx> {
30-
LibFeatureCollector { tcx, lib_features: new_lib_features() }
26+
LibFeatureCollector { tcx, lib_features: LibFeatures::default() }
3127
}
3228

33-
fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
29+
fn extract(&self, attr: &Attribute) -> Option<(Symbol, FeatureStability, Span)> {
3430
let stab_attrs = [
3531
sym::stable,
3632
sym::unstable,
@@ -72,8 +68,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
7268
| sym::rustc_const_unstable
7369
| sym::rustc_default_body_unstable
7470
);
75-
if since.is_some() || is_unstable {
76-
return Some((feature, since, attr.span));
71+
if is_unstable {
72+
return Some((feature, FeatureStability::Unstable, attr.span));
73+
}
74+
if let Some(since) = since {
75+
return Some((feature, FeatureStability::AcceptedSince(since), attr.span));
7776
}
7877
}
7978
// We need to iterate over the other attributes, because
@@ -86,37 +85,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
8685
None
8786
}
8887

89-
fn collect_feature(&mut self, feature: Symbol, since: Option<Symbol>, span: Span) {
88+
fn collect_feature(&mut self, feature: Symbol, stability: FeatureStability, span: Span) {
9089
let already_in_stable = self.lib_features.stable.contains_key(&feature);
9190
let already_in_unstable = self.lib_features.unstable.contains_key(&feature);
9291

93-
match (since, already_in_stable, already_in_unstable) {
94-
(Some(since), _, false) => {
95-
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature) {
96-
if *prev_since != since {
97-
self.tcx.sess.emit_err(FeatureStableTwice {
98-
span,
99-
feature,
100-
since,
101-
prev_since: *prev_since,
102-
});
103-
return;
104-
}
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;
105104
}
106105

107106
self.lib_features.stable.insert(feature, (since, span));
108107
}
109-
(None, false, _) => {
108+
(FeatureStability::AcceptedSince(_), _, true) => {
109+
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
110+
span,
111+
feature,
112+
declared: "stable",
113+
prev_declared: "unstable",
114+
});
115+
}
116+
(FeatureStability::Unstable, false, _) => {
110117
self.lib_features.unstable.insert(feature, span);
111118
}
112-
(Some(_), _, true) | (None, true, _) => {
113-
let declared = if since.is_some() { "stable" } else { "unstable" };
114-
let prev_declared = if since.is_none() { "stable" } else { "unstable" };
119+
(FeatureStability::Unstable, true, _) => {
115120
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
116121
span,
117122
feature,
118-
declared,
119-
prev_declared,
123+
declared: "unstable",
124+
prev_declared: "stable",
120125
});
121126
}
122127
}
@@ -137,11 +142,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
137142
}
138143
}
139144

140-
fn lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures {
145+
fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures {
141146
// If `staged_api` is not enabled then we aren't allowed to define lib
142147
// features; there is no point collecting them.
143148
if !tcx.features().staged_api {
144-
return new_lib_features();
149+
return LibFeatures::default();
145150
}
146151

147152
let mut collector = LibFeatureCollector::new(tcx);

compiler/rustc_passes/src/stability.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ 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};
1616
use rustc_middle::hir::nested_filter;
17+
use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
1718
use rustc_middle::middle::privacy::EffectiveVisibilities;
1819
use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
1920
use rustc_middle::query::Providers;
@@ -978,29 +979,27 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
978979
tcx: TyCtxt<'tcx>,
979980
remaining_lib_features: &mut FxIndexMap<&Symbol, Span>,
980981
remaining_implications: &mut FxHashMap<Symbol, Symbol>,
981-
defined_features: &[(Symbol, Option<Symbol>)],
982+
defined_features: &LibFeatures,
982983
all_implications: &FxHashMap<Symbol, Symbol>,
983984
) {
984-
for (feature, since) in defined_features {
985-
if let Some(since) = since
985+
for (feature, since) in defined_features.to_vec() {
986+
if let FeatureStability::AcceptedSince(since) = since
986987
&& let Some(span) = remaining_lib_features.get(&feature)
987988
{
988989
// Warn if the user has enabled an already-stable lib feature.
989990
if let Some(implies) = all_implications.get(&feature) {
990-
unnecessary_partially_stable_feature_lint(
991-
tcx, *span, *feature, *implies, *since,
992-
);
991+
unnecessary_partially_stable_feature_lint(tcx, *span, feature, *implies, since);
993992
} else {
994-
unnecessary_stable_feature_lint(tcx, *span, *feature, *since);
993+
unnecessary_stable_feature_lint(tcx, *span, feature, since);
995994
}
996995
}
997-
remaining_lib_features.remove(feature);
996+
remaining_lib_features.remove(&feature);
998997

999998
// `feature` is the feature doing the implying, but `implied_by` is the feature with
1000999
// the attribute that establishes this relationship. `implied_by` is guaranteed to be a
10011000
// feature defined in the local crate because `remaining_implications` is only the
10021001
// implications from this crate.
1003-
remaining_implications.remove(feature);
1002+
remaining_implications.remove(&feature);
10041003

10051004
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
10061005
break;
@@ -1014,7 +1013,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10141013

10151014
// We always collect the lib features declared in the current crate, even if there are
10161015
// no unknown features, because the collection also does feature attribute validation.
1017-
let local_defined_features = tcx.lib_features(()).to_vec();
1016+
let local_defined_features = tcx.lib_features(rustc_hir::def_id::LOCAL_CRATE);
10181017
if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
10191018
// Loading the implications of all crates is unavoidable to be able to emit the partial
10201019
// stabilization diagnostic, but it can be avoided when there are no
@@ -1028,7 +1027,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10281027
tcx,
10291028
&mut remaining_lib_features,
10301029
&mut remaining_implications,
1031-
local_defined_features.as_slice(),
1030+
local_defined_features,
10321031
&all_implications,
10331032
);
10341033

@@ -1040,7 +1039,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10401039
tcx,
10411040
&mut remaining_lib_features,
10421041
&mut remaining_implications,
1043-
tcx.defined_lib_features(cnum).to_vec().as_slice(),
1042+
tcx.lib_features(cnum),
10441043
&all_implications,
10451044
);
10461045
}
@@ -1051,7 +1050,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10511050
}
10521051

10531052
for (implied_by, feature) in remaining_implications {
1054-
let local_defined_features = tcx.lib_features(());
1053+
let local_defined_features = tcx.lib_features(rustc_hir::def_id::LOCAL_CRATE);
10551054
let span = *local_defined_features
10561055
.stable
10571056
.get(&feature)

0 commit comments

Comments
 (0)