Skip to content

Commit 8207d89

Browse files
authored
Rollup merge of #132114 - jieyouxu:features-bundle, r=fee1-dead
Use `Enabled{Lang,Lib}Feature` instead of n-tuples Instead of passing around e.g. `(gate_name, attr_span, stable_since)` 3-tuples for enabled lang features or `(gate_name, attr_span)` 2-tuples for enabled lib features, use `Enabled{Lang,Lib}Feature` structs with named fields. Also did some minor code-golfing of involved iterator chains to hopefully make them easier to follow. Follow-up to #132098 (comment) cc `@RalfJung.`
2 parents a06b7cb + 3528149 commit 8207d89

7 files changed

Lines changed: 101 additions & 51 deletions

File tree

‎compiler/rustc_ast_passes/src/feature_gate.rs‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,9 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
623623
let stable_since = features
624624
.enabled_lang_features()
625625
.iter()
626-
.flat_map(|&(feature, _, since)| if feature == name { since }else{None})
627-
.next();
626+
.find(|feat| feat.gate_name == name)
627+
.map(|feat| feat.stable_since)
628+
.flatten();
628629
ifletSome(since) = stable_since {
629630
err.stable_features.push(errors::StableFeature{ name, since });
630631
}else{
@@ -642,16 +643,15 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
642643
}
643644

644645
fncheck_incompatible_features(sess:&Session,features:&Features){
645-
let enabled_features = features
646-
.enabled_lang_features()
647-
.iter()
648-
.copied()
649-
.map(|(name, span, _)| (name, span))
650-
.chain(features.enabled_lib_features().iter().copied());
646+
let enabled_lang_features =
647+
features.enabled_lang_features().iter().map(|feat| (feat.gate_name, feat.attr_sp));
648+
let enabled_lib_features =
649+
features.enabled_lib_features().iter().map(|feat| (feat.gate_name, feat.attr_sp));
650+
let enabled_features = enabled_lang_features.chain(enabled_lib_features);
651651

652652
for(f1, f2)in rustc_feature::INCOMPATIBLE_FEATURES
653653
.iter()
654-
.filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2))
654+
.filter(|(f1, f2)| features.enabled(*f1) && features.enabled(*f2))
655655
{
656656
ifletSome((f1_name, f1_span)) = enabled_features.clone().find(|(name, _)| name == f1){
657657
ifletSome((f2_name, f2_span)) = enabled_features.clone().find(|(name, _)| name == f2)
@@ -673,10 +673,11 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
673673
}
674674

675675
// Ban GCE with the new solver, because it does not implement GCE correctly.
676-
ifletSome(&(_,gce_span, _)) = features
676+
ifletSome(gce_span) = features
677677
.enabled_lang_features()
678678
.iter()
679-
.find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
679+
.find(|feat| feat.gate_name == sym::generic_const_exprs)
680+
.map(|feat| feat.attr_sp)
680681
{
681682
sess.dcx().emit_err(errors::IncompatibleFeatures{
682683
spans:vec![gce_span],

‎compiler/rustc_expand/src/config.rs‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use rustc_ast::{
1111
use rustc_attr as attr;
1212
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1313
use rustc_feature::{
14-
ACCEPTED_LANG_FEATURES,AttributeSafety,Features,REMOVED_LANG_FEATURES,
15-
UNSTABLE_LANG_FEATURES,
14+
ACCEPTED_LANG_FEATURES,AttributeSafety,EnabledLangFeature,EnabledLibFeature,Features,
15+
REMOVED_LANG_FEATURES,UNSTABLE_LANG_FEATURES,
1616
};
1717
use rustc_lint_defs::BuiltinLintDiag;
1818
use rustc_parse::validate_attr;
@@ -88,8 +88,11 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
8888

8989
// If the enabled feature is stable, record it.
9090
ifletSome(f) = ACCEPTED_LANG_FEATURES.iter().find(|f| name == f.name){
91-
let since = Some(Symbol::intern(f.since));
92-
features.set_enabled_lang_feature(name, mi.span(), since);
91+
features.set_enabled_lang_feature(EnabledLangFeature{
92+
gate_name: name,
93+
attr_sp: mi.span(),
94+
stable_since:Some(Symbol::intern(f.since)),
95+
});
9396
continue;
9497
}
9598

@@ -115,13 +118,19 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
115118
{
116119
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
117120
}
118-
features.set_enabled_lang_feature(name, mi.span(),None);
121+
122+
features.set_enabled_lang_feature(EnabledLangFeature{
123+
gate_name: name,
124+
attr_sp: mi.span(),
125+
stable_since:None,
126+
});
119127
continue;
120128
}
121129

122130
// Otherwise, the feature is unknown. Enable it as a lib feature.
123131
// It will be checked later whether the feature really exists.
124-
features.set_enabled_lib_feature(name, mi.span());
132+
features
133+
.set_enabled_lib_feature(EnabledLibFeature{gate_name: name,attr_sp: mi.span()});
125134

126135
// Similar to above, detect internal lib features to suppress
127136
// the ICE message that asks for a report.

‎compiler/rustc_feature/src/lib.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,6 @@ pub use builtin_attrs::{
135135
is_valid_for_get_attr,
136136
};
137137
pubuse removed::REMOVED_LANG_FEATURES;
138-
pubuse unstable::{Features,INCOMPATIBLE_FEATURES,UNSTABLE_LANG_FEATURES};
138+
pubuse unstable::{
139+
EnabledLangFeature,EnabledLibFeature,Features,INCOMPATIBLE_FEATURES,UNSTABLE_LANG_FEATURES,
140+
};

‎compiler/rustc_feature/src/unstable.rs‎

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,54 @@ macro_rules! status_to_enum {
3636
#[derive(Clone,Default,Debug)]
3737
pubstructFeatures{
3838
/// `#![feature]` attrs for language features, for error reporting.
39-
enabled_lang_features:Vec<(Symbol,Span,Option<Symbol>)>,
39+
enabled_lang_features:Vec<EnabledLangFeature>,
4040
/// `#![feature]` attrs for non-language (library) features.
41-
enabled_lib_features:Vec<(Symbol,Span)>,
41+
enabled_lib_features:Vec<EnabledLibFeature>,
4242
/// `enabled_lang_features` + `enabled_lib_features`.
4343
enabled_features:FxHashSet<Symbol>,
4444
}
4545

46+
/// Information about an enabled language feature.
47+
#[derive(Debug,Copy,Clone)]
48+
pubstructEnabledLangFeature{
49+
/// Name of the feature gate guarding the language feature.
50+
pubgate_name:Symbol,
51+
/// Span of the `#[feature(...)]` attribute.
52+
pubattr_sp:Span,
53+
/// If the lang feature is stable, the version number when it was stabilized.
54+
pubstable_since:Option<Symbol>,
55+
}
56+
57+
/// Information abhout an enabled library feature.
58+
#[derive(Debug,Copy,Clone)]
59+
pubstructEnabledLibFeature{
60+
pubgate_name:Symbol,
61+
pubattr_sp:Span,
62+
}
63+
4664
implFeatures{
4765
/// `since` should be set for stable features that are nevertheless enabled with a `#[feature]`
4866
/// attribute, indicating since when they are stable.
49-
pubfnset_enabled_lang_feature(&mutself,name:Symbol,span:Span,since:Option<Symbol>){
50-
self.enabled_lang_features.push((name, span, since));
51-
self.enabled_features.insert(name);
67+
pubfnset_enabled_lang_feature(&mutself,lang_feat:EnabledLangFeature){
68+
self.enabled_lang_features.push(lang_feat);
69+
self.enabled_features.insert(lang_feat.gate_name);
5270
}
5371

54-
pubfnset_enabled_lib_feature(&mutself,name:Symbol,span:Span){
55-
self.enabled_lib_features.push((name, span));
56-
self.enabled_features.insert(name);
72+
pubfnset_enabled_lib_feature(&mutself,lib_feat:EnabledLibFeature){
73+
self.enabled_lib_features.push(lib_feat);
74+
self.enabled_features.insert(lib_feat.gate_name);
5775
}
5876

59-
/// Returns a list of triples with:
60-
/// - feature gate name
61-
/// - the span of the `#[feature]` attribute
62-
/// - (for already stable features) the version since which it is stable
63-
pubfnenabled_lang_features(&self) -> &Vec<(Symbol,Span,Option<Symbol>)>{
77+
/// Returns a list of [`EnabledLangFeature`] with info about:
78+
///
79+
/// - Feature gate name.
80+
/// - The span of the `#[feature]` attribute.
81+
/// - For stable language features, version info for when it was stabilized.
82+
pubfnenabled_lang_features(&self) -> &Vec<EnabledLangFeature>{
6483
&self.enabled_lang_features
6584
}
6685

67-
pubfnenabled_lib_features(&self) -> &Vec<(Symbol,Span)>{
86+
pubfnenabled_lib_features(&self) -> &Vec<EnabledLibFeature>{
6887
&self.enabled_lib_features
6988
}
7089

‎compiler/rustc_lint/src/builtin.rs‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,13 +2289,15 @@ declare_lint_pass!(
22892289
implEarlyLintPassforIncompleteInternalFeatures{
22902290
fncheck_crate(&mutself,cx:&EarlyContext<'_>, _:&ast::Crate){
22912291
let features = cx.builder.features();
2292-
features
2293-
.enabled_lang_features()
2294-
.iter()
2295-
.map(|(name, span, _)| (name, span))
2296-
.chain(features.enabled_lib_features().iter().map(|(name, span)| (name, span)))
2297-
.filter(|(&name, _)| features.incomplete(name) || features.internal(name))
2298-
.for_each(|(&name,&span)| {
2292+
let lang_features =
2293+
features.enabled_lang_features().iter().map(|feat| (feat.gate_name, feat.attr_sp));
2294+
let lib_features =
2295+
features.enabled_lib_features().iter().map(|feat| (feat.gate_name, feat.attr_sp));
2296+
2297+
lang_features
2298+
.chain(lib_features)
2299+
.filter(|(name, _)| features.incomplete(*name) || features.internal(*name))
2300+
.for_each(|(name, span)| {
22992301
if features.incomplete(name){
23002302
let note = rustc_feature::find_feature_issue(name,GateIssue::Language)
23012303
.map(|n| BuiltinFeatureIssueNote{ n });

‎compiler/rustc_passes/src/stability.rs‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_attr::{
1010
};
1111
use rustc_data_structures::fx::FxIndexMap;
1212
use rustc_data_structures::unord::{ExtendUnord,UnordMap,UnordSet};
13-
use rustc_feature::ACCEPTED_LANG_FEATURES;
13+
use rustc_feature::{ACCEPTED_LANG_FEATURES,EnabledLangFeature,EnabledLibFeature};
1414
use rustc_hir as hir;
1515
use rustc_hir::def::{DefKind,Res};
1616
use rustc_hir::def_id::{CRATE_DEF_ID,LOCAL_CRATE,LocalDefId,LocalModDefId};
@@ -994,25 +994,25 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
994994

995995
let enabled_lang_features = tcx.features().enabled_lang_features();
996996
letmut lang_features = UnordSet::default();
997-
for&(feature, span, since)in enabled_lang_features {
998-
ifletSome(since) = since{
997+
forEnabledLangFeature{ gate_name, attr_sp, stable_since }in enabled_lang_features {
998+
ifletSome(version) = stable_since{
999999
// Warn if the user has enabled an already-stable lang feature.
1000-
unnecessary_stable_feature_lint(tcx,span, feature, since);
1000+
unnecessary_stable_feature_lint(tcx,*attr_sp,*gate_name,*version);
10011001
}
1002-
if !lang_features.insert(feature){
1002+
if !lang_features.insert(gate_name){
10031003
// Warn if the user enables a lang feature multiple times.
1004-
tcx.dcx().emit_err(errors::DuplicateFeatureErr{ span, feature });
1004+
tcx.dcx().emit_err(errors::DuplicateFeatureErr{span:*attr_sp,feature:*gate_name});
10051005
}
10061006
}
10071007

10081008
let enabled_lib_features = tcx.features().enabled_lib_features();
10091009
letmut remaining_lib_features = FxIndexMap::default();
1010-
for(feature, span)in enabled_lib_features {
1011-
if remaining_lib_features.contains_key(&feature){
1010+
forEnabledLibFeature{ gate_name, attr_sp }in enabled_lib_features {
1011+
if remaining_lib_features.contains_key(gate_name){
10121012
// Warn if the user enables a lib feature multiple times.
1013-
tcx.dcx().emit_err(errors::DuplicateFeatureErr{span:*span,feature:*feature});
1013+
tcx.dcx().emit_err(errors::DuplicateFeatureErr{span:*attr_sp,feature:*gate_name});
10141014
}
1015-
remaining_lib_features.insert(feature,*span);
1015+
remaining_lib_features.insert(*gate_name,*attr_sp);
10161016
}
10171017
// `stdbuild` has special handling for `libc`, so we need to
10181018
// recognise the feature when building std.
@@ -1044,7 +1044,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10441044
/// time, less loading from metadata is performed and thus compiler performance is improved.
10451045
fncheck_features<'tcx>(
10461046
tcx:TyCtxt<'tcx>,
1047-
remaining_lib_features:&mutFxIndexMap<&Symbol,Span>,
1047+
remaining_lib_features:&mutFxIndexMap<Symbol,Span>,
10481048
remaining_implications:&mutUnordMap<Symbol,Symbol>,
10491049
defined_features:&LibFeatures,
10501050
all_implications:&UnordMap<Symbol,Symbol>,
@@ -1114,7 +1114,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
11141114
}
11151115

11161116
for(feature, span)in remaining_lib_features {
1117-
tcx.dcx().emit_err(errors::UnknownFeature{ span,feature:*feature});
1117+
tcx.dcx().emit_err(errors::UnknownFeature{ span, feature });
11181118
}
11191119

11201120
for(&implied_by,&feature)in remaining_implications.to_sorted_stable_ord(){

‎compiler/rustc_query_system/src/ich/impls_syntax.rs‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,20 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
116116
self.enabled_lib_features().hash_stable(hcx, hasher);
117117
}
118118
}
119+
120+
impl<'tcx>HashStable<StableHashingContext<'tcx>>for rustc_feature::EnabledLangFeature{
121+
fnhash_stable(&self,hcx:&mutStableHashingContext<'tcx>,hasher:&mutStableHasher){
122+
let rustc_feature::EnabledLangFeature{ gate_name, attr_sp, stable_since } = self;
123+
gate_name.hash_stable(hcx, hasher);
124+
attr_sp.hash_stable(hcx, hasher);
125+
stable_since.hash_stable(hcx, hasher);
126+
}
127+
}
128+
129+
impl<'tcx>HashStable<StableHashingContext<'tcx>>for rustc_feature::EnabledLibFeature{
130+
fnhash_stable(&self,hcx:&mutStableHashingContext<'tcx>,hasher:&mutStableHasher){
131+
let rustc_feature::EnabledLibFeature{ gate_name, attr_sp } = self;
132+
gate_name.hash_stable(hcx, hasher);
133+
attr_sp.hash_stable(hcx, hasher);
134+
}
135+
}

0 commit comments

Comments
 (0)