Skip to content

Commit 19878fe

Browse files
committed
Auto merge of #66945 - Centril:de-macro-gating, r=<try>
de-macro-ize feature gate checking This PR removes the usage of macros in feature gating preferring to take in symbols instead. The aim is to make feature gating more understandable overall while also reducing some duplication. To check whether a feature gate is active, `tcx.features().on(sym::my_feature)` can be used. Inside `PostExpansionVisitor` it's however better to use `self.gate(...)` which provides a nicer API atop of that. Outside of the visitor, if `gate_feature` can be used, it should be preferred over `feature_err`. As a follow-up, and once #66878 is merged, it might be a good idea to add a method to `Session` for more convenient access to `gate_feature` and `feature_err` respectively. Originally I intended to go for a `HashSet` representation, but this felt like a smaller change to just expand to a `match` on the symbol => field pairs. r? @oli-obk
2 parents f577b0e + 359de34 commit 19878fe

File tree

52 files changed

+478
-528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+478
-528
lines changed

src/librustc/hir/lowering.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ impl<'a> LoweringContext<'a> {
834834
return;
835835
}
836836

837-
if !self.sess.features_untracked().in_band_lifetimes {
837+
if !self.sess.features_untracked().on(sym::in_band_lifetimes) {
838838
return;
839839
}
840840

@@ -1394,7 +1394,7 @@ impl<'a> LoweringContext<'a> {
13941394
}
13951395
ImplTraitContext::Disallowed(pos) => {
13961396
let allowed_in = if self.sess.features_untracked()
1397-
.impl_trait_in_bindings {
1397+
.on(sym::impl_trait_in_bindings) {
13981398
"bindings or function and inherent method return types"
13991399
} else {
14001400
"function and inherent method return types"
@@ -2118,7 +2118,7 @@ impl<'a> LoweringContext<'a> {
21182118

21192119
fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
21202120
let mut ids = SmallVec::<[NodeId; 1]>::new();
2121-
if self.sess.features_untracked().impl_trait_in_bindings {
2121+
if self.sess.features_untracked().on(sym::impl_trait_in_bindings) {
21222122
if let Some(ref ty) = l.ty {
21232123
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
21242124
visitor.visit_ty(ty);
@@ -2130,7 +2130,7 @@ impl<'a> LoweringContext<'a> {
21302130
ty: l.ty
21312131
.as_ref()
21322132
.map(|t| self.lower_ty(t,
2133-
if self.sess.features_untracked().impl_trait_in_bindings {
2133+
if self.sess.features_untracked().on(sym::impl_trait_in_bindings) {
21342134
ImplTraitContext::OpaqueTy(Some(parent_def_id))
21352135
} else {
21362136
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)

src/librustc/hir/lowering/item.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,15 @@ impl LoweringContext<'_> {
181181
ItemKind::Impl(.., None, _, _) => smallvec![i.id],
182182
ItemKind::Static(ref ty, ..) => {
183183
let mut ids = smallvec![i.id];
184-
if self.sess.features_untracked().impl_trait_in_bindings {
184+
if self.sess.features_untracked().on(sym::impl_trait_in_bindings) {
185185
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
186186
visitor.visit_ty(ty);
187187
}
188188
ids
189189
},
190190
ItemKind::Const(ref ty, ..) => {
191191
let mut ids = smallvec![i.id];
192-
if self.sess.features_untracked().impl_trait_in_bindings {
192+
if self.sess.features_untracked().on(sym::impl_trait_in_bindings) {
193193
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
194194
visitor.visit_ty(ty);
195195
}
@@ -285,7 +285,7 @@ impl LoweringContext<'_> {
285285
hir::ItemKind::Static(
286286
self.lower_ty(
287287
t,
288-
if self.sess.features_untracked().impl_trait_in_bindings {
288+
if self.sess.features_untracked().on(sym::impl_trait_in_bindings) {
289289
ImplTraitContext::OpaqueTy(None)
290290
} else {
291291
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
@@ -299,7 +299,7 @@ impl LoweringContext<'_> {
299299
hir::ItemKind::Const(
300300
self.lower_ty(
301301
t,
302-
if self.sess.features_untracked().impl_trait_in_bindings {
302+
if self.sess.features_untracked().on(sym::impl_trait_in_bindings) {
303303
ImplTraitContext::OpaqueTy(None)
304304
} else {
305305
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)

src/librustc/infer/error_reporting/need_type_info.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::infer::InferCtxt;
55
use crate::infer::type_variable::TypeVariableOriginKind;
66
use crate::ty::{self, Ty, Infer, TyVar};
77
use crate::ty::print::Print;
8-
use syntax::source_map::DesugaringKind;
9-
use syntax_pos::Span;
8+
use syntax_pos::source_map::DesugaringKind;
9+
use syntax_pos::{Span, symbol::sym};
1010
use errors::{Applicability, DiagnosticBuilder};
1111

1212
use rustc_error_codes::*;
@@ -217,7 +217,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
217217
let is_named_and_not_impl_trait = |ty: Ty<'_>| {
218218
&ty.to_string() != "_" &&
219219
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. #63527
220-
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings)
220+
(!ty.is_impl_trait() || self.tcx.features().on(sym::impl_trait_in_bindings))
221221
};
222222

223223
let ty_msg = match local_visitor.found_ty {

src/librustc/infer/opaque_types/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use errors::DiagnosticBuilder;
1313
use rustc::session::config::nightly_options;
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_data_structures::sync::Lrc;
16-
use syntax_pos::Span;
16+
use syntax_pos::{Span, symbol::sym};
1717

1818
use rustc_error_codes::*;
1919

@@ -488,7 +488,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
488488
conflict2: ty::Region<'tcx>,
489489
) -> bool {
490490
// If we have `#![feature(member_constraints)]`, no problems.
491-
if self.tcx.features().member_constraints {
491+
if self.tcx.features().on(sym::member_constraints) {
492492
return false;
493493
}
494494

src/librustc/lint/levels.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,13 @@ impl<'a> LintLevelsBuilder<'a> {
231231
// FIXME (#55112): issue unused-attributes lint if we thereby
232232
// don't have any lint names (`#[level(reason = "foo")]`)
233233
if let ast::LitKind::Str(rationale, _) = name_value.kind {
234-
if !self.sess.features_untracked().lint_reasons {
235-
feature_gate::feature_err(
236-
&self.sess.parse_sess,
237-
sym::lint_reasons,
238-
item.span,
239-
"lint reasons are experimental"
240-
)
241-
.emit();
242-
}
234+
feature_gate::gate_feature(
235+
&self.sess.parse_sess,
236+
self.sess.features_untracked(),
237+
item.span,
238+
sym::lint_reasons,
239+
"lint reasons are experimental"
240+
);
243241
reason = Some(rationale);
244242
} else {
245243
bad_attr(name_value.span)

src/librustc/middle/stability.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
116116
item_sp: Span, kind: AnnotationKind, visit_children: F)
117117
where F: FnOnce(&mut Self)
118118
{
119-
if self.tcx.features().staged_api {
119+
if self.tcx.features().on(sym::staged_api) {
120120
// This crate explicitly wants staged API.
121121
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
122122
if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
@@ -393,7 +393,7 @@ impl<'tcx> Index<'tcx> {
393393
pub fn new(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
394394
let is_staged_api =
395395
tcx.sess.opts.debugging_opts.force_unstable_if_unmarked ||
396-
tcx.features().staged_api;
396+
tcx.features().on(sym::staged_api);
397397
let mut staged_api = FxHashMap::default();
398398
staged_api.insert(LOCAL_CRATE, is_staged_api);
399399
let mut index = Index {
@@ -836,7 +836,7 @@ impl Visitor<'tcx> for Checker<'tcx> {
836836

837837
// There's no good place to insert stability check for non-Copy unions,
838838
// so semi-randomly perform it here in stability.rs
839-
hir::ItemKind::Union(..) if !self.tcx.features().untagged_unions => {
839+
hir::ItemKind::Union(..) if !self.tcx.features().on(sym::untagged_unions) => {
840840
let def_id = self.tcx.hir().local_def_id(item.hir_id);
841841
let adt_def = self.tcx.adt_def(def_id);
842842
let ty = self.tcx.type_of(def_id);

src/librustc/traits/error_reporting.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2353,13 +2353,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
23532353
}
23542354
ObligationCauseCode::VariableType(_) => {
23552355
err.note("all local variables must have a statically known size");
2356-
if !self.tcx.features().unsized_locals {
2356+
if !self.tcx.features().on(sym::unsized_locals) {
23572357
err.help("unsized locals are gated as an unstable feature");
23582358
}
23592359
}
23602360
ObligationCauseCode::SizedArgumentType => {
23612361
err.note("all function arguments must have a statically known size");
2362-
if !self.tcx.features().unsized_locals {
2362+
if !self.tcx.features().on(sym::unsized_locals) {
23632363
err.help("unsized locals are gated as an unstable feature");
23642364
}
23652365
}

src/librustc/traits/select.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2215,7 +2215,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
22152215
}
22162216

22172217
if let Some(principal) = data.principal() {
2218-
if !self.infcx.tcx.features().object_safe_for_dispatch {
2218+
if !self.infcx.tcx.features().on(sym::object_safe_for_dispatch) {
22192219
principal.with_self_ty(self.tcx(), self_ty)
22202220
} else if self.tcx().is_object_safe(principal.def_id()) {
22212221
principal.with_self_ty(self.tcx(), self_ty)

src/librustc/traits/specialize/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::infer::{InferCtxt, InferOk};
1616
use crate::lint;
1717
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
1818
use rustc_data_structures::fx::FxHashSet;
19-
use syntax_pos::DUMMY_SP;
19+
use syntax_pos::{DUMMY_SP, symbol::sym};
2020
use crate::traits::select::IntercrateAmbiguityCause;
2121
use crate::ty::{self, TyCtxt, TypeFoldable};
2222
use crate::ty::subst::{Subst, InternalSubsts, SubstsRef};
@@ -155,7 +155,7 @@ pub(super) fn specializes(
155155

156156
// The feature gate should prevent introducing new specializations, but not
157157
// taking advantage of upstream ones.
158-
if !tcx.features().specialization &&
158+
if !tcx.features().on(sym::specialization) &&
159159
(impl1_def_id.is_local() || impl2_def_id.is_local()) {
160160
return false;
161161
}

src/librustc/ty/constness.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::ty::query::Providers;
22
use crate::hir::def_id::DefId;
33
use crate::hir;
44
use crate::ty::TyCtxt;
5-
use syntax_pos::symbol::Symbol;
5+
use syntax_pos::symbol::{sym, Symbol};
66
use crate::hir::map::blocks::FnLikeNode;
77
use syntax::attr;
88

@@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> {
4242
return false;
4343
}
4444

45-
if self.features().staged_api {
45+
if self.features().on(sym::staged_api) {
4646
// in order for a libstd function to be considered min_const_fn
4747
// it needs to be stable and have no `rustc_const_unstable` attribute
4848
match self.lookup_stability(def_id) {
@@ -56,7 +56,7 @@ impl<'tcx> TyCtxt<'tcx> {
5656
}
5757
} else {
5858
// users enabling the `const_fn` feature gate can do what they want
59-
!self.features().const_fn
59+
!self.features().on(sym::const_fn)
6060
}
6161
}
6262
}

src/librustc/ty/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ impl<'tcx> TyCtxt<'tcx> {
14731473
//
14741474
// * Otherwise, use the behavior requested via `-Z borrowck=...`
14751475

1476-
if self.features().nll { return BorrowckMode::Mir; }
1476+
if self.features().on(sym::nll) { return BorrowckMode::Mir; }
14771477

14781478
self.sess.opts.borrowck_mode
14791479
}
@@ -2437,7 +2437,7 @@ impl<'tcx> TyCtxt<'tcx> {
24372437

24382438
#[inline]
24392439
pub fn mk_diverging_default(self) -> Ty<'tcx> {
2440-
if self.features().never_type_fallback {
2440+
if self.features().on(sym::never_type_fallback) {
24412441
self.types.never
24422442
} else {
24432443
self.types.unit

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2898,7 +2898,7 @@ impl<'tcx> TyCtxt<'tcx> {
28982898
(ImplPolarity::Negative, ImplPolarity::Negative) => {}
28992899
};
29002900

2901-
let is_marker_overlap = if self.features().overlapping_marker_traits {
2901+
let is_marker_overlap = if self.features().on(sym::overlapping_marker_traits) {
29022902
let trait1_is_empty = self.impl_trait_ref(def_id1)
29032903
.map_or(false, |trait_ref| {
29042904
self.associated_item_def_ids(trait_ref.def_id).is_empty()

src/librustc/ty/wf.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ty::subst::SubstsRef;
55
use crate::traits::{self, AssocTypeBoundData};
66
use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
77
use std::iter::once;
8-
use syntax::symbol::{kw, Ident};
8+
use syntax::symbol::{kw, sym, Ident};
99
use syntax_pos::Span;
1010
use crate::middle::lang_items;
1111

@@ -538,7 +538,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
538538
// checking those
539539

540540
let defer_to_coercion =
541-
self.infcx.tcx.features().object_safe_for_dispatch;
541+
self.infcx.tcx.features().on(sym::object_safe_for_dispatch);
542542

543543
if !defer_to_coercion {
544544
let cause = self.cause(traits::MiscObligation);

src/librustc_codegen_utils/symbol_names_test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn report_symbol_names(tcx: TyCtxt<'_>) {
1515
// if the `rustc_attrs` feature is not enabled, then the
1616
// attributes we are interested in cannot be present anyway, so
1717
// skip the walk.
18-
if !tcx.features().rustc_attrs {
18+
if !tcx.features().on(sym::rustc_attrs) {
1919
return;
2020
}
2121

src/librustc_feature/active.rs

+36-33
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,22 @@ use syntax_pos::edition::Edition;
66
use syntax_pos::Span;
77
use syntax_pos::symbol::{Symbol, sym};
88

9-
macro_rules! set {
10-
($field: ident) => {{
11-
fn f(features: &mut Features, _: Span) {
12-
features.$field = true;
13-
}
14-
f as fn(&mut Features, Span)
15-
}}
16-
}
17-
189
macro_rules! declare_features {
1910
($(
2011
$(#[doc = $doc:tt])* (active, $feature:ident, $ver:expr, $issue:expr, $edition:expr),
2112
)+) => {
2213
/// Represents active features that are currently being implemented or
2314
/// currently being considered for addition/removal.
24-
pub const ACTIVE_FEATURES:
25-
&[Feature] =
26-
&[$(
27-
// (sym::$feature, $ver, $issue, $edition, set!($feature))
28-
Feature {
29-
state: State::Active { set: set!($feature) },
30-
name: sym::$feature,
31-
since: $ver,
32-
issue: $issue,
33-
edition: $edition,
34-
description: concat!($($doc,)*),
35-
}
36-
),+];
15+
pub const ACTIVE_FEATURES: &[Feature] = &[$(
16+
Feature {
17+
state: State::Active,
18+
name: sym::$feature,
19+
since: $ver,
20+
issue: $issue,
21+
edition: $edition,
22+
description: concat!($($doc,)*),
23+
}
24+
),+];
3725

3826
/// A set of features to be used by later passes.
3927
#[derive(Clone, Default)]
@@ -44,28 +32,43 @@ macro_rules! declare_features {
4432
pub declared_lib_features: Vec<(Symbol, Span)>,
4533
$(
4634
$(#[doc = $doc])*
47-
pub $feature: bool
35+
$feature: bool
4836
),+
4937
}
5038

5139
impl Features {
40+
/// Is the given feature enabled?
41+
///
42+
/// Panics if the symbol doesn't correspond to a declared feature.
43+
pub fn on(&self, name: Symbol) -> bool {
44+
match name {
45+
$(sym::$feature => self.$feature,)+
46+
_ => panic!("unknown feature `{}`", name),
47+
}
48+
}
49+
50+
/// Enable the given `feature`.
51+
///
52+
/// Panics if called on a non-active feature
53+
/// or a symbol not corresponding to a declared feature.
54+
pub fn enable(&mut self, feature: &Feature, _: Span) {
55+
let Feature { name, .. } = feature;
56+
match feature.state {
57+
State::Active => match *name {
58+
$(sym::$feature => self.$feature = true,)+
59+
_ => panic!("unknown feature `{}`", name),
60+
},
61+
_ => panic!("called `set` on feature `{}` which is not `active`", name),
62+
}
63+
}
64+
5265
pub fn walk_feature_fields(&self, mut f: impl FnMut(&str, bool)) {
5366
$(f(stringify!($feature), self.$feature);)+
5467
}
5568
}
5669
};
5770
}
5871

59-
impl Feature {
60-
/// Sets this feature in `Features`. Panics if called on a non-active feature.
61-
pub fn set(&self, features: &mut Features, span: Span) {
62-
match self.state {
63-
State::Active { set } => set(features, span),
64-
_ => panic!("called `set` on feature `{}` which is not `active`", self.name)
65-
}
66-
}
67-
}
68-
6972
// If you change this, please modify `src/doc/unstable-book` as well.
7073
//
7174
// Don't ever remove anything from this list; move them to `removed.rs`.

0 commit comments

Comments
 (0)