Skip to content

Commit d221878

Browse files
Unify defined_lib_features and lib_features queries
1 parent 4e21162 commit d221878

File tree

9 files changed

+84
-58
lines changed

9 files changed

+84
-58
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 14 additions & 2 deletions
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;
@@ -1007,8 +1008,19 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10071008
}
10081009

10091010
/// Iterates over all the stability attributes in the given crate.
1010-
fn get_lib_features(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
1011-
tcx.arena.alloc_from_iter(self.root.lib_features.decode(self))
1011+
fn get_lib_features(self, _tcx: TyCtxt<'tcx>) -> LibFeatures {
1012+
let mut features = LibFeatures::default();
1013+
for (symbol, stability) in self.root.lib_features.decode(self) {
1014+
match stability {
1015+
FeatureStability::AcceptedSince(since) => {
1016+
features.stable.insert(symbol, (since, DUMMY_SP));
1017+
}
1018+
FeatureStability::Unstable => {
1019+
features.unstable.insert(symbol, DUMMY_SP);
1020+
}
1021+
}
1022+
}
1023+
features
10121024
}
10131025

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ provide! { tcx, def_id, other, cdata,
343343
module_children => {
344344
tcx.arena.alloc_from_iter(cdata.get_module_children(def_id.index, tcx.sess))
345345
}
346-
defined_lib_features => { cdata.get_lib_features(tcx) }
346+
lib_features => { cdata.get_lib_features(tcx) }
347347
stability_implications => {
348348
cdata.get_stability_implications(tcx).iter().copied().collect()
349349
}

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc_middle::middle::dependency_format::Linkage;
2424
use rustc_middle::middle::exported_symbols::{
2525
metadata_symbol_name, ExportedSymbol, SymbolExportInfo,
2626
};
27+
use rustc_middle::middle::lib_features::FeatureStability;
2728
use rustc_middle::mir::interpret;
2829
use rustc_middle::query::LocalCrate;
2930
use rustc_middle::query::Providers;
@@ -1871,10 +1872,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18711872
self.lazy_array(deps.iter().map(|(_, dep)| dep))
18721873
}
18731874

1874-
fn encode_lib_features(&mut self) -> LazyArray<(Symbol, Option<Symbol>)> {
1875+
fn encode_lib_features(&mut self) -> LazyArray<(Symbol, FeatureStability)> {
18751876
empty_proc_macro!(self);
18761877
let tcx = self.tcx;
1877-
let lib_features = tcx.lib_features(());
1878+
let lib_features = tcx.lib_features(LOCAL_CRATE);
18781879
self.lazy_array(lib_features.to_vec())
18791880
}
18801881

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 1 deletion
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;
@@ -264,7 +265,7 @@ pub(crate) struct CrateRoot {
264265

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

compiler/rustc_middle/src/middle/mod.rs

Lines changed: 11 additions & 4 deletions
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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,13 +1744,10 @@ rustc_queries! {
17441744
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
17451745
}
17461746

1747-
query lib_features(_: ()) -> &'tcx LibFeatures {
1748-
arena_cache
1749-
desc { "calculating the lib features map" }
1750-
}
1751-
query defined_lib_features(_: CrateNum) -> &'tcx [(Symbol, Option<Symbol>)] {
1747+
query lib_features(_: CrateNum) -> &'tcx LibFeatures {
17521748
desc { "calculating the lib features defined in a crate" }
17531749
separate_provide_extern
1750+
arena_cache
17541751
}
17551752
query stability_implications(_: CrateNum) -> &'tcx FxHashMap<Symbol, Symbol> {
17561753
arena_cache

compiler/rustc_middle/src/ty/parameterized.rs

Lines changed: 1 addition & 0 deletions
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

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,25 @@ use rustc_ast::Attribute;
88
use rustc_attr::{rust_version_symbol, 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,
@@ -70,8 +66,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
7066
| sym::rustc_const_unstable
7167
| sym::rustc_default_body_unstable
7268
);
73-
if since.is_some() || is_unstable {
74-
return Some((feature, since, attr.span));
69+
if is_unstable {
70+
return Some((feature, FeatureStability::Unstable, attr.span));
71+
}
72+
if let Some(since) = since {
73+
return Some((feature, FeatureStability::AcceptedSince(since), attr.span));
7574
}
7675
}
7776
// We need to iterate over the other attributes, because
@@ -84,37 +83,43 @@ impl<'tcx> LibFeatureCollector<'tcx> {
8483
None
8584
}
8685

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

91-
match (since, already_in_stable, already_in_unstable) {
92-
(Some(since), _, false) => {
93-
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature) {
94-
if *prev_since != since {
95-
self.tcx.sess.emit_err(FeatureStableTwice {
96-
span,
97-
feature,
98-
since,
99-
prev_since: *prev_since,
100-
});
101-
return;
102-
}
90+
match (stability, already_in_stable, already_in_unstable) {
91+
(FeatureStability::AcceptedSince(since), _, false) => {
92+
if let Some((prev_since, _)) = self.lib_features.stable.get(&feature)
93+
&& *prev_since != since
94+
{
95+
self.tcx.sess.emit_err(FeatureStableTwice {
96+
span,
97+
feature,
98+
since,
99+
prev_since: *prev_since,
100+
});
101+
return;
103102
}
104103

105104
self.lib_features.stable.insert(feature, (since, span));
106105
}
107-
(None, false, _) => {
106+
(FeatureStability::AcceptedSince(_), _, true) => {
107+
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
108+
span,
109+
feature,
110+
declared: "stable",
111+
prev_declared: "unstable",
112+
});
113+
}
114+
(FeatureStability::Unstable, false, _) => {
108115
self.lib_features.unstable.insert(feature, span);
109116
}
110-
(Some(_), _, true) | (None, true, _) => {
111-
let declared = if since.is_some() { "stable" } else { "unstable" };
112-
let prev_declared = if since.is_none() { "stable" } else { "unstable" };
117+
(FeatureStability::Unstable, true, _) => {
113118
self.tcx.sess.emit_err(FeaturePreviouslyDeclared {
114119
span,
115120
feature,
116-
declared,
117-
prev_declared,
121+
declared: "unstable",
122+
prev_declared: "stable",
118123
});
119124
}
120125
}
@@ -135,11 +140,11 @@ impl<'tcx> Visitor<'tcx> for LibFeatureCollector<'tcx> {
135140
}
136141
}
137142

138-
fn lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures {
143+
fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures {
139144
// If `staged_api` is not enabled then we aren't allowed to define lib
140145
// features; there is no point collecting them.
141146
if !tcx.features().staged_api {
142-
return new_lib_features();
147+
return LibFeatures::default();
143148
}
144149

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

compiler/rustc_passes/src/stability.rs

Lines changed: 14 additions & 12 deletions
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;
@@ -994,26 +995,27 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
994995
tcx: TyCtxt<'tcx>,
995996
remaining_lib_features: &mut FxIndexMap<&Symbol, Span>,
996997
remaining_implications: &mut FxHashMap<Symbol, Symbol>,
997-
defined_features: &[(Symbol, Option<Symbol>)],
998+
defined_features: &LibFeatures,
998999
all_implications: &FxHashMap<Symbol, Symbol>,
9991000
) {
1000-
for (feature, since) in defined_features {
1001-
if let Some(since) = since && let Some(span) = remaining_lib_features.get(&feature) {
1001+
for (feature, stability) in defined_features.to_vec() {
1002+
if let FeatureStability::AcceptedSince(since) = stability
1003+
&& let Some(span) = remaining_lib_features.get(&feature)
1004+
{
10021005
// Warn if the user has enabled an already-stable lib feature.
10031006
if let Some(implies) = all_implications.get(&feature) {
1004-
unnecessary_partially_stable_feature_lint(tcx, *span, *feature, *implies, *since);
1007+
unnecessary_partially_stable_feature_lint(tcx, *span, feature, *implies, since);
10051008
} else {
1006-
unnecessary_stable_feature_lint(tcx, *span, *feature, *since);
1009+
unnecessary_stable_feature_lint(tcx, *span, feature, since);
10071010
}
1008-
10091011
}
1010-
remaining_lib_features.remove(feature);
1012+
remaining_lib_features.remove(&feature);
10111013

10121014
// `feature` is the feature doing the implying, but `implied_by` is the feature with
10131015
// the attribute that establishes this relationship. `implied_by` is guaranteed to be a
10141016
// feature defined in the local crate because `remaining_implications` is only the
10151017
// implications from this crate.
1016-
remaining_implications.remove(feature);
1018+
remaining_implications.remove(&feature);
10171019

10181020
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
10191021
break;
@@ -1027,7 +1029,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10271029

10281030
// We always collect the lib features declared in the current crate, even if there are
10291031
// no unknown features, because the collection also does feature attribute validation.
1030-
let local_defined_features = tcx.lib_features(()).to_vec();
1032+
let local_defined_features = tcx.lib_features(rustc_hir::def_id::LOCAL_CRATE);
10311033
if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
10321034
// Loading the implications of all crates is unavoidable to be able to emit the partial
10331035
// stabilization diagnostic, but it can be avoided when there are no
@@ -1041,7 +1043,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10411043
tcx,
10421044
&mut remaining_lib_features,
10431045
&mut remaining_implications,
1044-
local_defined_features.as_slice(),
1046+
local_defined_features,
10451047
&all_implications,
10461048
);
10471049

@@ -1053,7 +1055,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10531055
tcx,
10541056
&mut remaining_lib_features,
10551057
&mut remaining_implications,
1056-
tcx.defined_lib_features(cnum).to_vec().as_slice(),
1058+
tcx.lib_features(cnum),
10571059
&all_implications,
10581060
);
10591061
}
@@ -1064,7 +1066,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10641066
}
10651067

10661068
for (implied_by, feature) in remaining_implications {
1067-
let local_defined_features = tcx.lib_features(());
1069+
let local_defined_features = tcx.lib_features(rustc_hir::def_id::LOCAL_CRATE);
10681070
let span = *local_defined_features
10691071
.stable
10701072
.get(&feature)

0 commit comments

Comments
 (0)