Skip to content

Commit 1381773

Browse files
committed
make some rustc_feature internals private, and ensure invariants with debug assertions
1 parent 46ce5cb commit 1381773

6 files changed

Lines changed: 62 additions & 26 deletions

File tree

‎compiler/rustc_ast_passes/src/feature_gate.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
604604
if sess.opts.unstable_features.is_nightly_build(){
605605
return;
606606
}
607-
if features.enabled_features.is_empty(){
607+
if features.enabled_features().is_empty(){
608608
return;
609609
}
610610
letmut errored = false;
@@ -621,7 +621,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
621621
for ident in attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident()){
622622
let name = ident.name;
623623
let stable_since = features
624-
.enabled_lang_features
624+
.enabled_lang_features()
625625
.iter()
626626
.flat_map(|&(feature, _, since)| if feature == name { since }else{None})
627627
.next();
@@ -643,11 +643,11 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
643643

644644
fncheck_incompatible_features(sess:&Session,features:&Features){
645645
let enabled_features = features
646-
.enabled_lang_features
646+
.enabled_lang_features()
647647
.iter()
648648
.copied()
649649
.map(|(name, span, _)| (name, span))
650-
.chain(features.enabled_lib_features.iter().copied());
650+
.chain(features.enabled_lib_features().iter().copied());
651651

652652
for(f1, f2)in rustc_feature::INCOMPATIBLE_FEATURES
653653
.iter()
@@ -674,7 +674,7 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
674674

675675
// Ban GCE with the new solver, because it does not implement GCE correctly.
676676
ifletSome(&(_, gce_span, _)) = features
677-
.enabled_lang_features
677+
.enabled_lang_features()
678678
.iter()
679679
.find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
680680
{

‎compiler/rustc_expand/src/config.rs‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
8888
// If the enabled feature is stable, record it.
8989
ifletSome(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name){
9090
let since = Some(Symbol::intern(f.since));
91-
features.set_enabled_lang_feature(name, mi.span(), since);
91+
features.set_enabled_lang_feature(name, mi.span(), since,None);
9292
continue;
9393
}
9494

@@ -104,7 +104,6 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
104104

105105
// If the enabled feature is unstable, record it.
106106
ifletSome(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name){
107-
(f.set_enabled)(&mut features);
108107
// When the ICE comes from core, alloc or std (approximation of the standard
109108
// library), there's a chance that the person hitting the ICE may be using
110109
// -Zbuild-std or similar with an untested target. The bug is probably in the
@@ -115,7 +114,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
115114
{
116115
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
117116
}
118-
features.set_enabled_lang_feature(name, mi.span(),None);
117+
features.set_enabled_lang_feature(name, mi.span(),None,Some(f));
119118
continue;
120119
}
121120

‎compiler/rustc_feature/src/unstable.rs‎

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use super::{Feature, to_nonzero};
88

99
pubstructUnstableFeature{
1010
pubfeature:Feature,
11-
pubset_enabled:fn(&mutFeatures),
11+
set_enabled:fn(&mutFeatures),
1212
}
1313

1414
#[derive(PartialEq)]
@@ -54,11 +54,11 @@ macro_rules! declare_features {
5454
#[derive(Clone,Default,Debug)]
5555
pubstructFeatures{
5656
/// `#![feature]` attrs for language features, for error reporting.
57-
pubenabled_lang_features:Vec<(Symbol,Span,Option<Symbol>)>,
57+
enabled_lang_features:Vec<(Symbol,Span,Option<Symbol>)>,
5858
/// `#![feature]` attrs for non-language (library) features.
59-
pubenabled_lib_features:Vec<(Symbol,Span)>,
59+
enabled_lib_features:Vec<(Symbol,Span)>,
6060
/// `enabled_lang_features` + `enabled_lib_features`.
61-
pubenabled_features:FxHashSet<Symbol>,
61+
enabled_features:FxHashSet<Symbol>,
6262
/// State of individual features (unstable lang features only).
6363
/// This is `true` if and only if the corresponding feature is listed in `enabled_lang_features`.
6464
$(
@@ -70,17 +70,27 @@ macro_rules! declare_features {
7070
implFeatures{
7171
pubfn set_enabled_lang_feature(
7272
&mutself,
73-
symbol:Symbol,
73+
name:Symbol,
7474
span:Span,
75-
since:Option<Symbol>
75+
since:Option<Symbol>,
76+
feature:Option<&UnstableFeature>,
7677
){
77-
self.enabled_lang_features.push((symbol, span, since));
78-
self.enabled_features.insert(symbol);
78+
self.enabled_lang_features.push((name, span, since));
79+
self.enabled_features.insert(name);
80+
ifletSome(feature) = feature {
81+
assert_eq!(feature.feature.name, name);
82+
(feature.set_enabled)(self);
83+
} else {
84+
// Ensure we don't skip a `set_enabled` call.
85+
debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none());
86+
}
7987
}
8088

81-
pubfn set_enabled_lib_feature(&mutself, symbol:Symbol, span:Span){
82-
self.enabled_lib_features.push((symbol, span));
83-
self.enabled_features.insert(symbol);
89+
pubfn set_enabled_lib_feature(&mutself, name:Symbol, span:Span){
90+
self.enabled_lib_features.push((name, span));
91+
self.enabled_features.insert(name);
92+
// Ensure we don't skip a `set_enabled` call.
93+
debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none());
8494
}
8595

8696
/// This is intended for hashing the set of enabled language features.
@@ -93,9 +103,36 @@ macro_rules! declare_features {
93103
[$(self.$feature asu8),+]
94104
}
95105

106+
pubfn enabled_lang_features(&self) -> &Vec<(Symbol,Span,Option<Symbol>)> {
107+
&self.enabled_lang_features
108+
}
109+
110+
pubfn enabled_lib_features(&self) -> &Vec<(Symbol,Span)> {
111+
&self.enabled_lib_features
112+
}
113+
114+
pubfn enabled_features(&self) -> &FxHashSet<Symbol> {
115+
&self.enabled_features
116+
}
117+
96118
/// Is the given feature enabled (via `#[feature(...)]`)?
97119
pubfn enabled(&self, feature:Symbol) -> bool{
98-
self.enabled_features.contains(&feature)
120+
let e = self.enabled_features.contains(&feature);
121+
if cfg!(debug_assertions){
122+
// Ensure this matches `self.$feature`, if that exists.
123+
let e2 = match feature {
124+
$( sym::$feature => Some(self.$feature),)*
125+
_ => None,
126+
};
127+
ifletSome(e2) = e2 {
128+
assert_eq!(
129+
e, e2,
130+
"mismatch in feature state for `{feature}`: \
131+
`enabled_features` says {e} but `self.{feature}` says {e2}"
132+
);
133+
}
134+
}
135+
e
99136
}
100137

101138
/// Some features are known to be incomplete and using them is likely to have

‎compiler/rustc_lint/src/builtin.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2288,10 +2288,10 @@ impl EarlyLintPass for IncompleteInternalFeatures {
22882288
fncheck_crate(&mutself,cx:&EarlyContext<'_>, _:&ast::Crate){
22892289
let features = cx.builder.features();
22902290
features
2291-
.enabled_lang_features
2291+
.enabled_lang_features()
22922292
.iter()
22932293
.map(|(name, span, _)| (name, span))
2294-
.chain(features.enabled_lib_features.iter().map(|(name, span)| (name, span)))
2294+
.chain(features.enabled_lib_features().iter().map(|(name, span)| (name, span)))
22952295
.filter(|(&name, _)| features.incomplete(name) || features.internal(name))
22962296
.for_each(|(&name,&span)| {
22972297
if features.incomplete(name){

‎compiler/rustc_passes/src/stability.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
935935
tcx.hir().visit_all_item_likes_in_crate(&mut missing);
936936
}
937937

938-
let enabled_lang_features = &tcx.features().enabled_lang_features;
938+
let enabled_lang_features = tcx.features().enabled_lang_features();
939939
letmut lang_features = UnordSet::default();
940940
for&(feature, span, since)in enabled_lang_features {
941941
ifletSome(since) = since {
@@ -948,7 +948,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
948948
}
949949
}
950950

951-
let enabled_lib_features = &tcx.features().enabled_lib_features;
951+
let enabled_lib_features = tcx.features().enabled_lib_features();
952952
letmut remaining_lib_features = FxIndexMap::default();
953953
for(feature, span)in enabled_lib_features {
954954
if remaining_lib_features.contains_key(&feature){

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for rustc_feature::Features {
112112
fnhash_stable(&self,hcx:&mutStableHashingContext<'tcx>,hasher:&mutStableHasher){
113113
// Unfortunately we cannot exhaustively list fields here, since the
114114
// struct is macro generated.
115-
self.enabled_lang_features.hash_stable(hcx, hasher);
116-
self.enabled_lib_features.hash_stable(hcx, hasher);
115+
self.enabled_lang_features().hash_stable(hcx, hasher);
116+
self.enabled_lib_features().hash_stable(hcx, hasher);
117117

118118
self.all_lang_features()[..].hash_stable(hcx, hasher);
119119
for feature in rustc_feature::UNSTABLE_FEATURES.iter(){

0 commit comments

Comments
 (0)