Skip to content

Commit 8c5bf45

Browse files
committed
terminology: #[feature] *activates* a feature (instead of "declaring" it)
1 parent 7d53688 commit 8c5bf45

File tree

16 files changed

+101
-114
lines changed

16 files changed

+101
-114
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+43-44
Original file line numberDiff line numberDiff line change
@@ -600,60 +600,61 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
600600
}
601601

602602
fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) {
603-
// checks if `#![feature]` has been used to enable any lang feature
604-
// does not check the same for lib features unless there's at least one
605-
// declared lang feature
606-
if !sess.opts.unstable_features.is_nightly_build() {
607-
if features.declared_features.is_empty() {
608-
return;
609-
}
610-
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
611-
let mut err = errors::FeatureOnNonNightly {
612-
span: attr.span,
613-
channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"),
614-
stable_features: vec![],
615-
sugg: None,
616-
};
617-
618-
let mut all_stable = true;
619-
for ident in
620-
attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident())
621-
{
622-
let name = ident.name;
623-
let stable_since = features
624-
.declared_lang_features
625-
.iter()
626-
.flat_map(|&(feature, _, since)| if feature == name { since } else { None })
627-
.next();
628-
if let Some(since) = stable_since {
629-
err.stable_features.push(errors::StableFeature { name, since });
630-
} else {
631-
all_stable = false;
632-
}
633-
}
634-
if all_stable {
635-
err.sugg = Some(attr.span);
603+
// checks if `#![feature]` has been used to enable any feature.
604+
if sess.opts.unstable_features.is_nightly_build() {
605+
return;
606+
}
607+
if features.active_features.is_empty() {
608+
return;
609+
}
610+
let mut errored = false;
611+
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
612+
// `feature(...)` used on non-nightly. This is definitely an error.
613+
let mut err = errors::FeatureOnNonNightly {
614+
span: attr.span,
615+
channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"),
616+
stable_features: vec![],
617+
sugg: None,
618+
};
619+
620+
let mut all_stable = true;
621+
for ident in attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident()) {
622+
let name = ident.name;
623+
let stable_since = features
624+
.active_lang_features
625+
.iter()
626+
.flat_map(|&(feature, _, since)| if feature == name { since } else { None })
627+
.next();
628+
if let Some(since) = stable_since {
629+
err.stable_features.push(errors::StableFeature { name, since });
630+
} else {
631+
all_stable = false;
636632
}
637-
sess.dcx().emit_err(err);
638633
}
634+
if all_stable {
635+
err.sugg = Some(attr.span);
636+
}
637+
sess.dcx().emit_err(err);
638+
errored = true;
639639
}
640+
// Just make sure we actually error if anything is listed in `active_features`.
641+
assert!(errored);
640642
}
641643

642644
fn check_incompatible_features(sess: &Session, features: &Features) {
643-
let declared_features = features
644-
.declared_lang_features
645+
let active_features = features
646+
.active_lang_features
645647
.iter()
646648
.copied()
647649
.map(|(name, span, _)| (name, span))
648-
.chain(features.declared_lib_features.iter().copied());
650+
.chain(features.active_lib_features.iter().copied());
649651

650652
for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES
651653
.iter()
652654
.filter(|&&(f1, f2)| features.active(f1) && features.active(f2))
653655
{
654-
if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) {
655-
if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2)
656-
{
656+
if let Some((f1_name, f1_span)) = active_features.clone().find(|(name, _)| name == f1) {
657+
if let Some((f2_name, f2_span)) = active_features.clone().find(|(name, _)| name == f2) {
657658
let spans = vec![f1_span, f2_span];
658659
sess.dcx().emit_err(errors::IncompatibleFeatures {
659660
spans,
@@ -671,10 +672,8 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
671672
}
672673

673674
// Ban GCE with the new solver, because it does not implement GCE correctly.
674-
if let Some(&(_, gce_span, _)) = features
675-
.declared_lang_features
676-
.iter()
677-
.find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
675+
if let Some(&(_, gce_span, _)) =
676+
features.active_lang_features.iter().find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
678677
{
679678
sess.dcx().emit_err(errors::IncompatibleFeatures {
680679
spans: vec![gce_span],

compiler/rustc_const_eval/src/check_consts/check.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -699,10 +699,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
699699
// Calling an unstable function *always* requires that the corresponding gate
700700
// (or implied gate) be enabled, even if the function has
701701
// `#[rustc_allow_const_fn_unstable(the_gate)]`.
702-
let gate_declared = |gate| tcx.features().declared(gate);
703-
let feature_gate_declared = gate_declared(gate);
704-
let implied_gate_declared = implied_by.is_some_and(gate_declared);
705-
if !feature_gate_declared && !implied_gate_declared {
702+
let gate_active = |gate| tcx.features().active(gate);
703+
let feature_gate_active = gate_active(gate);
704+
let implied_gate_active = implied_by.is_some_and(gate_active);
705+
if !feature_gate_active && !implied_gate_active {
706706
self.check_op(ops::FnCallUnstable(callee, Some(gate)));
707707
return;
708708
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
A `#![feature]` attribute was declared multiple times.
1+
The same feature is activated multiple times with `#![feature]` attributes
22

33
Erroneous code example:
44

55
```compile_fail,E0636
66
#![allow(stable_features)]
77
#![feature(rust1)]
8-
#![feature(rust1)] // error: the feature `rust1` has already been declared
8+
#![feature(rust1)] // error: the feature `rust1` has already been activated
99
```

compiler/rustc_error_codes/src/error_codes/E0705.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#### Note: this error code is no longer emitted by the compiler.
22

3-
A `#![feature]` attribute was declared for a feature that is stable in the
3+
A `#![feature]` attribute was used for a feature that is stable in the
44
current edition, but not in all editions.
55

66
Erroneous code example:

compiler/rustc_expand/src/config.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
5151

5252
let mut features = Features::default();
5353

54-
// Process all features declared in the code.
54+
// Process all features activated in the code.
5555
for attr in krate_attrs {
5656
for mi in feature_list(attr) {
5757
let name = match mi.ident() {
@@ -75,7 +75,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
7575
}
7676
};
7777

78-
// If the declared feature has been removed, issue an error.
78+
// If the activated feature has been removed, issue an error.
7979
if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) {
8080
sess.dcx().emit_err(FeatureRemoved {
8181
span: mi.span(),
@@ -84,14 +84,14 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
8484
continue;
8585
}
8686

87-
// If the declared feature is stable, record it.
87+
// If the activated feature is stable, record it.
8888
if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
8989
let since = Some(Symbol::intern(f.since));
90-
features.set_declared_lang_feature(name, mi.span(), since);
90+
features.set_active_lang_feature(name, mi.span(), since);
9191
continue;
9292
}
9393

94-
// If `-Z allow-features` is used and the declared feature is
94+
// If `-Z allow-features` is used and the activated feature is
9595
// unstable and not also listed as one of the allowed features,
9696
// issue an error.
9797
if let Some(allowed) = sess.opts.unstable_opts.allow_features.as_ref() {
@@ -101,7 +101,7 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
101101
}
102102
}
103103

104-
// If the declared feature is unstable, record it.
104+
// If the activated feature is unstable, record it.
105105
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
106106
(f.set_enabled)(&mut features);
107107
// When the ICE comes from core, alloc or std (approximation of the standard
@@ -114,13 +114,13 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
114114
{
115115
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
116116
}
117-
features.set_declared_lang_feature(name, mi.span(), None);
117+
features.set_active_lang_feature(name, mi.span(), None);
118118
continue;
119119
}
120120

121121
// Otherwise, the feature is unknown. Record it as a lib feature.
122122
// It will be checked later.
123-
features.set_declared_lib_feature(name, mi.span());
123+
features.set_active_lib_feature(name, mi.span());
124124

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

compiler/rustc_expand/src/mbe/quoted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub(super) fn parse(
119119
result
120120
}
121121

122-
/// Asks for the `macro_metavar_expr` feature if it is not already declared
122+
/// Asks for the `macro_metavar_expr` feature if it is not activated
123123
fn maybe_emit_macro_metavar_expr_feature(features: &Features, sess: &Session, span: Span) {
124124
if !features.macro_metavar_expr {
125125
let msg = "meta-variable expressions are unstable";

compiler/rustc_feature/src/unstable.rs

+21-31
Original file line numberDiff line numberDiff line change
@@ -54,61 +54,48 @@ macro_rules! declare_features {
5454
#[derive(Clone, Default, Debug)]
5555
pub struct Features {
5656
/// `#![feature]` attrs for language features, for error reporting.
57-
/// "declared" here means that the feature is actually enabled in the current crate.
58-
pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
57+
pub active_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
5958
/// `#![feature]` attrs for non-language (library) features.
60-
/// "declared" here means that the feature is actually enabled in the current crate.
61-
pub declared_lib_features: Vec<(Symbol, Span)>,
62-
/// `declared_lang_features` + `declared_lib_features`.
63-
pub declared_features: FxHashSet<Symbol>,
64-
/// Active state of individual features (unstable only).
59+
pub active_lib_features: Vec<(Symbol, Span)>,
60+
/// `active_lang_features` + `active_lib_features`.
61+
pub active_features: FxHashSet<Symbol>,
62+
/// Active state of individual features (unstable lang features only).
63+
/// This is `true` if and only if the corresponding feature is listed in `active_lang_features`.
6564
$(
6665
$(#[doc = $doc])*
6766
pub $feature: bool
6867
),+
6968
}
7069

7170
impl Features {
72-
pub fn set_declared_lang_feature(
71+
pub fn set_active_lang_feature(
7372
&mut self,
7473
symbol: Symbol,
7574
span: Span,
7675
since: Option<Symbol>
7776
) {
78-
self.declared_lang_features.push((symbol, span, since));
79-
self.declared_features.insert(symbol);
77+
self.active_lang_features.push((symbol, span, since));
78+
self.active_features.insert(symbol);
8079
}
8180

82-
pub fn set_declared_lib_feature(&mut self, symbol: Symbol, span: Span) {
83-
self.declared_lib_features.push((symbol, span));
84-
self.declared_features.insert(symbol);
81+
pub fn set_active_lib_feature(&mut self, symbol: Symbol, span: Span) {
82+
self.active_lib_features.push((symbol, span));
83+
self.active_features.insert(symbol);
8584
}
8685

87-
/// This is intended for hashing the set of active features.
86+
/// This is intended for hashing the set of active language features.
8887
///
8988
/// The expectation is that this produces much smaller code than other alternatives.
9089
///
9190
/// Note that the total feature count is pretty small, so this is not a huge array.
9291
#[inline]
93-
pub fn all_features(&self) -> [u8; NUM_FEATURES] {
92+
pub fn all_lang_features(&self) -> [u8; NUM_FEATURES] {
9493
[$(self.$feature as u8),+]
9594
}
9695

97-
/// Is the given feature explicitly declared, i.e. named in a
98-
/// `#![feature(...)]` within the code?
99-
pub fn declared(&self, feature: Symbol) -> bool {
100-
self.declared_features.contains(&feature)
101-
}
102-
10396
/// Is the given feature active (enabled by the user)?
104-
///
105-
/// Panics if the symbol doesn't correspond to a declared feature.
10697
pub fn active(&self, feature: Symbol) -> bool {
107-
match feature {
108-
$( sym::$feature => self.$feature, )*
109-
110-
_ => panic!("`{}` was not listed in `declare_features`", feature),
111-
}
98+
self.active_features.contains(&feature)
11299
}
113100

114101
/// Some features are known to be incomplete and using them is likely to have
@@ -119,8 +106,11 @@ macro_rules! declare_features {
119106
$(
120107
sym::$feature => status_to_enum!($status) == FeatureStatus::Incomplete,
121108
)*
122-
// Accepted/removed features aren't in this file but are never incomplete.
123-
_ if self.declared_features.contains(&feature) => false,
109+
_ if self.active_features.contains(&feature) => {
110+
// Accepted/removed features and library features aren't in this file but
111+
// are never incomplete.
112+
false
113+
}
124114
_ => panic!("`{}` was not listed in `declare_features`", feature),
125115
}
126116
}
@@ -132,7 +122,7 @@ macro_rules! declare_features {
132122
$(
133123
sym::$feature => status_to_enum!($status) == FeatureStatus::Internal,
134124
)*
135-
_ if self.declared_features.contains(&feature) => {
125+
_ if self.active_features.contains(&feature) => {
136126
// This could be accepted/removed, or a libs feature.
137127
// Accepted/removed features aren't in this file but are never internal
138128
// (a removed feature might have been internal, but that's now irrelevant).

compiler/rustc_lint/src/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2288,10 +2288,10 @@ impl EarlyLintPass for IncompleteInternalFeatures {
22882288
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
22892289
let features = cx.builder.features();
22902290
features
2291-
.declared_lang_features
2291+
.active_lang_features
22922292
.iter()
22932293
.map(|(name, span, _)| (name, span))
2294-
.chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
2294+
.chain(features.active_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_middle/src/middle/stability.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -422,15 +422,15 @@ impl<'tcx> TyCtxt<'tcx> {
422422
debug!("stability: skipping span={:?} since it is internal", span);
423423
return EvalResult::Allow;
424424
}
425-
if self.features().declared(feature) {
425+
if self.features().active(feature) {
426426
return EvalResult::Allow;
427427
}
428428

429429
// If this item was previously part of a now-stabilized feature which is still
430430
// active (i.e. the user hasn't removed the attribute for the stabilized feature
431431
// yet) then allow use of this item.
432432
if let Some(implied_by) = implied_by
433-
&& self.features().declared(implied_by)
433+
&& self.features().active(implied_by)
434434
{
435435
return EvalResult::Allow;
436436
}
@@ -509,7 +509,7 @@ impl<'tcx> TyCtxt<'tcx> {
509509
debug!("body stability: skipping span={:?} since it is internal", span);
510510
return EvalResult::Allow;
511511
}
512-
if self.features().declared(feature) {
512+
if self.features().active(feature) {
513513
return EvalResult::Allow;
514514
}
515515

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3092,7 +3092,7 @@ impl<'tcx> TyCtxt<'tcx> {
30923092
Some(stability) if stability.is_const_unstable() => {
30933093
// has a `rustc_const_unstable` attribute, check whether the user enabled the
30943094
// corresponding feature gate.
3095-
self.features().declared(stability.feature)
3095+
self.features().active(stability.feature)
30963096
}
30973097
// functions without const stability are either stable user written
30983098
// const fn or the user is using feature gates and we thus don't

compiler/rustc_passes/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ passes_duplicate_diagnostic_item_in_crate =
252252
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`
253253
254254
passes_duplicate_feature_err =
255-
the feature `{$feature}` has already been declared
255+
the feature `{$feature}` has already been activated
256256
257257
passes_duplicate_lang_item =
258258
found duplicate lang item `{$lang_item_name}`

0 commit comments

Comments
 (0)