Skip to content

Commit cb771fd

Browse files
committed
feature_gate: Eliminate check::Context
Use `PostExpansionVisitor` directly instead
1 parent a01ba39 commit cb771fd

File tree

1 file changed

+51
-59
lines changed

1 file changed

+51
-59
lines changed

src/libsyntax/feature_gate/check.rs

+51-59
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,10 @@ pub enum Stability {
3232
Deprecated(&'static str, Option<&'static str>),
3333
}
3434

35-
struct Context<'a> {
36-
parse_sess: &'a ParseSess,
37-
features: &'a Features,
38-
}
39-
4035
macro_rules! gate_feature_fn {
4136
($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
4237
let (cx, has_feature, span,
43-
name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
38+
name, explain, level) = (&*$cx, $has_feature, $span, $name, $explain, $level);
4439
let has_feature: bool = has_feature(&$cx.features);
4540
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
4641
if !has_feature && !span.allows_unstable($name) {
@@ -62,45 +57,7 @@ macro_rules! gate_feature {
6257
}
6358

6459
crate fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
65-
let cx = &Context { parse_sess, features };
66-
let attr_info =
67-
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
68-
// Check feature gates for built-in attributes.
69-
if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
70-
gate_feature_fn!(cx, has_feature, attr.span, name, descr, GateStrength::Hard);
71-
}
72-
// Check input tokens for built-in and key-value attributes.
73-
match attr_info {
74-
// `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
75-
Some((name, _, template, _)) if name != sym::rustc_dummy =>
76-
check_builtin_attribute(parse_sess, attr, name, template),
77-
_ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
78-
if token == token::Eq {
79-
// All key-value attributes are restricted to meta-item syntax.
80-
attr.parse_meta(parse_sess).map_err(|mut err| err.emit()).ok();
81-
}
82-
}
83-
}
84-
// Check unstable flavors of the `#[doc]` attribute.
85-
if attr.check_name(sym::doc) {
86-
for nested_meta in attr.meta_item_list().unwrap_or_default() {
87-
macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
88-
$(if nested_meta.check_name(sym::$name) {
89-
let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
90-
gate_feature!(cx, $feature, attr.span, msg);
91-
})*
92-
}}
93-
94-
gate_doc!(
95-
include => external_doc
96-
cfg => doc_cfg
97-
masked => doc_masked
98-
spotlight => doc_spotlight
99-
alias => doc_alias
100-
keyword => doc_keyword
101-
);
102-
}
103-
}
60+
PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
10461
}
10562

10663
fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
@@ -215,20 +172,21 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
215172
"unsized tuple coercion is not stable enough for use and is subject to change";
216173

217174
struct PostExpansionVisitor<'a> {
218-
context: &'a Context<'a>,
175+
parse_sess: &'a ParseSess,
176+
features: &'a Features,
219177
}
220178

221179
macro_rules! gate_feature_post {
222180
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
223181
let (cx, span) = ($cx, $span);
224182
if !span.allows_unstable(sym::$feature) {
225-
gate_feature!(cx.context, $feature, span, $explain)
183+
gate_feature!(cx, $feature, span, $explain)
226184
}
227185
}};
228186
($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
229187
let (cx, span) = ($cx, $span);
230188
if !span.allows_unstable(sym::$feature) {
231-
gate_feature!(cx.context, $feature, span, $explain, $level)
189+
gate_feature!(cx, $feature, span, $explain, $level)
232190
}
233191
}}
234192
}
@@ -292,15 +250,52 @@ impl<'a> PostExpansionVisitor<'a> {
292250

293251
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
294252
fn visit_attribute(&mut self, attr: &ast::Attribute) {
295-
check_attribute(attr, self.context.parse_sess, self.context.features);
253+
let attr_info =
254+
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
255+
// Check feature gates for built-in attributes.
256+
if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
257+
gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard);
258+
}
259+
// Check input tokens for built-in and key-value attributes.
260+
match attr_info {
261+
// `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
262+
Some((name, _, template, _)) if name != sym::rustc_dummy =>
263+
check_builtin_attribute(self.parse_sess, attr, name, template),
264+
_ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
265+
if token == token::Eq {
266+
// All key-value attributes are restricted to meta-item syntax.
267+
attr.parse_meta(self.parse_sess).map_err(|mut err| err.emit()).ok();
268+
}
269+
}
270+
}
271+
// Check unstable flavors of the `#[doc]` attribute.
272+
if attr.check_name(sym::doc) {
273+
for nested_meta in attr.meta_item_list().unwrap_or_default() {
274+
macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
275+
$(if nested_meta.check_name(sym::$name) {
276+
let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
277+
gate_feature!(self, $feature, attr.span, msg);
278+
})*
279+
}}
280+
281+
gate_doc!(
282+
include => external_doc
283+
cfg => doc_cfg
284+
masked => doc_masked
285+
spotlight => doc_spotlight
286+
alias => doc_alias
287+
keyword => doc_keyword
288+
);
289+
}
290+
}
296291
}
297292

298293
fn visit_name(&mut self, sp: Span, name: ast::Name) {
299294
if !name.as_str().is_ascii() {
300295
gate_feature_post!(
301296
&self,
302297
non_ascii_idents,
303-
self.context.parse_sess.source_map().def_span(sp),
298+
self.parse_sess.source_map().def_span(sp),
304299
"non-ascii idents are not fully supported"
305300
);
306301
}
@@ -356,12 +351,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
356351
}
357352
}
358353

359-
let has_feature = self.context.features.arbitrary_enum_discriminant;
354+
let has_feature = self.features.arbitrary_enum_discriminant;
360355
if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
361-
Parser::maybe_report_invalid_custom_discriminants(
362-
self.context.parse_sess,
363-
&variants,
364-
);
356+
Parser::maybe_report_invalid_custom_discriminants(self.parse_sess, &variants);
365357
}
366358
}
367359

@@ -471,7 +463,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
471463
ast::ExprKind::Type(..) => {
472464
// To avoid noise about type ascription in common syntax errors, only emit if it
473465
// is the *only* error.
474-
if self.context.parse_sess.span_diagnostic.err_count() == 0 {
466+
if self.parse_sess.span_diagnostic.err_count() == 0 {
475467
gate_feature_post!(&self, type_ascription, e.span,
476468
"type ascription is experimental");
477469
}
@@ -809,13 +801,13 @@ pub fn check_crate(krate: &ast::Crate,
809801
features: &Features,
810802
unstable: UnstableFeatures) {
811803
maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
812-
let ctx = Context { parse_sess, features };
804+
let mut visitor = PostExpansionVisitor { parse_sess, features };
813805

814806
macro_rules! gate_all {
815807
($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
816808
($spans:ident, $gate:ident, $msg:literal) => {
817809
for span in &*parse_sess.gated_spans.$spans.borrow() {
818-
gate_feature!(&ctx, $gate, *span, $msg);
810+
gate_feature!(&visitor, $gate, *span, $msg);
819811
}
820812
}
821813
}
@@ -826,7 +818,7 @@ pub fn check_crate(krate: &ast::Crate,
826818
gate_all!(yields, generators, "yield syntax is experimental");
827819
gate_all!(or_patterns, "or-patterns syntax is experimental");
828820

829-
visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate);
821+
visit::walk_crate(&mut visitor, krate);
830822
}
831823

832824
#[derive(Clone, Copy, Hash)]

0 commit comments

Comments
 (0)