]> git.lizzy.rs Git - rust.git/commitdiff
Move syntax_expand::config to rustc_parse::config
authorMark Rousskov <mark.simulacrum@gmail.com>
Wed, 20 Nov 2019 02:35:11 +0000 (21:35 -0500)
committerMark Rousskov <mark.simulacrum@gmail.com>
Wed, 20 Nov 2019 02:35:11 +0000 (21:35 -0500)
src/librustc_parse/config.rs [new file with mode: 0644]
src/librustc_parse/lib.rs
src/librustc_parse/parser/module.rs
src/libsyntax_expand/config.rs [deleted file]
src/libsyntax_expand/expand.rs
src/libsyntax_expand/lib.rs

diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs
new file mode 100644 (file)
index 0000000..7ce555e
--- /dev/null
@@ -0,0 +1,375 @@
+//! Process the potential `cfg` attributes on a module.
+//! Also determine if the module should be included in this configuration.
+//!
+//! This module properly belongs in syntax_expand, but for now it's tied into
+//! parsing, so we leave it here to avoid complicated out-of-line dependencies.
+//!
+//! A principled solution to this wrong location would be to implement [#64197].
+//!
+//! [#64197]: https://github.com/rust-lang/rust/issues/64197
+
+use crate::validate_attr;
+use syntax::attr::HasAttrs;
+use syntax::feature_gate::{
+    feature_err,
+    EXPLAIN_STMT_ATTR_SYNTAX,
+    Features,
+    get_features,
+    GateIssue,
+};
+use syntax::attr;
+use syntax::ast;
+use syntax::edition::Edition;
+use syntax::mut_visit::*;
+use syntax::ptr::P;
+use syntax::sess::ParseSess;
+use syntax::util::map_in_place::MapInPlace;
+use syntax_pos::symbol::sym;
+
+use errors::Applicability;
+use smallvec::SmallVec;
+
+/// A folder that strips out items that do not belong in the current configuration.
+pub struct StripUnconfigured<'a> {
+    pub sess: &'a ParseSess,
+    pub features: Option<&'a Features>,
+}
+
+// `cfg_attr`-process the crate's attributes and compute the crate's features.
+pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
+                allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
+    let features;
+    {
+        let mut strip_unconfigured = StripUnconfigured {
+            sess,
+            features: None,
+        };
+
+        let unconfigured_attrs = krate.attrs.clone();
+        let err_count = sess.span_diagnostic.err_count();
+        if let Some(attrs) = strip_unconfigured.configure(krate.attrs) {
+            krate.attrs = attrs;
+        } else { // the entire crate is unconfigured
+            krate.attrs = Vec::new();
+            krate.module.items = Vec::new();
+            return (krate, Features::new());
+        }
+
+        features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features);
+
+        // Avoid reconfiguring malformed `cfg_attr`s
+        if err_count == sess.span_diagnostic.err_count() {
+            strip_unconfigured.features = Some(&features);
+            strip_unconfigured.configure(unconfigured_attrs);
+        }
+    }
+
+    (krate, features)
+}
+
+#[macro_export]
+macro_rules! configure {
+    ($this:ident, $node:ident) => {
+        match $this.configure($node) {
+            Some(node) => node,
+            None => return Default::default(),
+        }
+    }
+}
+
+impl<'a> StripUnconfigured<'a> {
+    pub fn configure<T: HasAttrs>(&mut self, mut node: T) -> Option<T> {
+        self.process_cfg_attrs(&mut node);
+        if self.in_cfg(node.attrs()) { Some(node) } else { None }
+    }
+
+    /// Parse and expand all `cfg_attr` attributes into a list of attributes
+    /// that are within each `cfg_attr` that has a true configuration predicate.
+    ///
+    /// Gives compiler warnigns if any `cfg_attr` does not contain any
+    /// attributes and is in the original source code. Gives compiler errors if
+    /// the syntax of any `cfg_attr` is incorrect.
+    pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: &mut T) {
+        node.visit_attrs(|attrs| {
+            attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
+        });
+    }
+
+    /// Parse and expand a single `cfg_attr` attribute into a list of attributes
+    /// when the configuration predicate is true, or otherwise expand into an
+    /// empty list of attributes.
+    ///
+    /// Gives a compiler warning when the `cfg_attr` contains no attributes and
+    /// is in the original source file. Gives a compiler error if the syntax of
+    /// the attribute is incorrect.
+    fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
+        if !attr.has_name(sym::cfg_attr) {
+            return vec![attr];
+        }
+        if attr.get_normal_item().tokens.is_empty() {
+            self.sess.span_diagnostic
+                .struct_span_err(
+                    attr.span,
+                    "malformed `cfg_attr` attribute input",
+                ).span_suggestion(
+                    attr.span,
+                    "missing condition and attribute",
+                    "#[cfg_attr(condition, attribute, other_attribute, ...)]".to_owned(),
+                    Applicability::HasPlaceholders,
+                ).note("for more information, visit \
+                       <https://doc.rust-lang.org/reference/conditional-compilation.html\
+                       #the-cfg_attr-attribute>")
+                .emit();
+            return vec![];
+        }
+
+        let res = crate::parse_in_attr(self.sess, &attr, |p| p.parse_cfg_attr());
+        let (cfg_predicate, expanded_attrs) = match res {
+            Ok(result) => result,
+            Err(mut e) => {
+                e.emit();
+                return vec![];
+            }
+        };
+
+        // Lint on zero attributes in source.
+        if expanded_attrs.is_empty() {
+            return vec![attr];
+        }
+
+        // At this point we know the attribute is considered used.
+        attr::mark_used(&attr);
+
+        if attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
+            // We call `process_cfg_attr` recursively in case there's a
+            // `cfg_attr` inside of another `cfg_attr`. E.g.
+            //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
+            expanded_attrs.into_iter()
+            .flat_map(|(item, span)| self.process_cfg_attr(attr::mk_attr_from_item(
+                attr.style,
+                item,
+                span,
+            )))
+            .collect()
+        } else {
+            vec![]
+        }
+    }
+
+    /// Determines if a node with the given attributes should be included in this configuration.
+    pub fn in_cfg(&self, attrs: &[ast::Attribute]) -> bool {
+        attrs.iter().all(|attr| {
+            if !is_cfg(attr) {
+                return true;
+            }
+
+            let error = |span, msg, suggestion: &str| {
+                let mut err = self.sess.span_diagnostic.struct_span_err(span, msg);
+                if !suggestion.is_empty() {
+                    err.span_suggestion(
+                        span,
+                        "expected syntax is",
+                        suggestion.into(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                err.emit();
+                true
+            };
+
+            let meta_item = match validate_attr::parse_meta(self.sess, attr) {
+                Ok(meta_item) => meta_item,
+                Err(mut err) => { err.emit(); return true; }
+            };
+            let nested_meta_items = if let Some(nested_meta_items) = meta_item.meta_item_list() {
+                nested_meta_items
+            } else {
+                return error(meta_item.span, "`cfg` is not followed by parentheses",
+                                             "cfg(/* predicate */)");
+            };
+
+            if nested_meta_items.is_empty() {
+                return error(meta_item.span, "`cfg` predicate is not specified", "");
+            } else if nested_meta_items.len() > 1 {
+                return error(nested_meta_items.last().unwrap().span(),
+                             "multiple `cfg` predicates are specified", "");
+            }
+
+            match nested_meta_items[0].meta_item() {
+                Some(meta_item) => attr::cfg_matches(meta_item, self.sess, self.features),
+                None => error(nested_meta_items[0].span(),
+                              "`cfg` predicate key cannot be a literal", ""),
+            }
+        })
+    }
+
+    /// Visit attributes on expression and statements (but not attributes on items in blocks).
+    fn visit_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
+        // flag the offending attributes
+        for attr in attrs.iter() {
+            self.maybe_emit_expr_attr_err(attr);
+        }
+    }
+
+    /// If attributes are not allowed on expressions, emit an error for `attr`
+    pub fn maybe_emit_expr_attr_err(&self, attr: &ast::Attribute) {
+        if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) {
+            let mut err = feature_err(self.sess,
+                                      sym::stmt_expr_attributes,
+                                      attr.span,
+                                      GateIssue::Language,
+                                      EXPLAIN_STMT_ATTR_SYNTAX);
+
+            if attr.is_doc_comment() {
+                err.help("`///` is for documentation comments. For a plain comment, use `//`.");
+            }
+
+            err.emit();
+        }
+    }
+
+    pub fn configure_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
+        let ast::ForeignMod { abi: _, items } = foreign_mod;
+        items.flat_map_in_place(|item| self.configure(item));
+    }
+
+    pub fn configure_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) {
+        params.flat_map_in_place(|param| self.configure(param));
+    }
+
+    fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) {
+        match vdata {
+            ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) =>
+                fields.flat_map_in_place(|field| self.configure(field)),
+            ast::VariantData::Unit(_) => {}
+        }
+    }
+
+    pub fn configure_item_kind(&mut self, item: &mut ast::ItemKind) {
+        match item {
+            ast::ItemKind::Struct(def, _generics) |
+            ast::ItemKind::Union(def, _generics) => self.configure_variant_data(def),
+            ast::ItemKind::Enum(ast::EnumDef { variants }, _generics) => {
+                variants.flat_map_in_place(|variant| self.configure(variant));
+                for variant in variants {
+                    self.configure_variant_data(&mut variant.data);
+                }
+            }
+            _ => {}
+        }
+    }
+
+    pub fn configure_expr_kind(&mut self, expr_kind: &mut ast::ExprKind) {
+        match expr_kind {
+            ast::ExprKind::Match(_m, arms) => {
+                arms.flat_map_in_place(|arm| self.configure(arm));
+            }
+            ast::ExprKind::Struct(_path, fields, _base) => {
+                fields.flat_map_in_place(|field| self.configure(field));
+            }
+            _ => {}
+        }
+    }
+
+    pub fn configure_expr(&mut self, expr: &mut P<ast::Expr>) {
+        self.visit_expr_attrs(expr.attrs());
+
+        // If an expr is valid to cfg away it will have been removed by the
+        // outer stmt or expression folder before descending in here.
+        // Anything else is always required, and thus has to error out
+        // in case of a cfg attr.
+        //
+        // N.B., this is intentionally not part of the visit_expr() function
+        //     in order for filter_map_expr() to be able to avoid this check
+        if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
+            let msg = "removing an expression is not supported in this position";
+            self.sess.span_diagnostic.span_err(attr.span, msg);
+        }
+
+        self.process_cfg_attrs(expr)
+    }
+
+    pub fn configure_pat(&mut self, pat: &mut P<ast::Pat>) {
+        if let ast::PatKind::Struct(_path, fields, _etc) = &mut pat.kind {
+            fields.flat_map_in_place(|field| self.configure(field));
+        }
+    }
+
+    pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
+        fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
+    }
+}
+
+impl<'a> MutVisitor for StripUnconfigured<'a> {
+    fn visit_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
+        self.configure_foreign_mod(foreign_mod);
+        noop_visit_foreign_mod(foreign_mod, self);
+    }
+
+    fn visit_item_kind(&mut self, item: &mut ast::ItemKind) {
+        self.configure_item_kind(item);
+        noop_visit_item_kind(item, self);
+    }
+
+    fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
+        self.configure_expr(expr);
+        self.configure_expr_kind(&mut expr.kind);
+        noop_visit_expr(expr, self);
+    }
+
+    fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
+        let mut expr = configure!(self, expr);
+        self.configure_expr_kind(&mut expr.kind);
+        noop_visit_expr(&mut expr, self);
+        Some(expr)
+    }
+
+    fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
+        noop_flat_map_stmt(configure!(self, stmt), self)
+    }
+
+    fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
+        noop_flat_map_item(configure!(self, item), self)
+    }
+
+    fn flat_map_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
+        noop_flat_map_impl_item(configure!(self, item), self)
+    }
+
+    fn flat_map_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
+        noop_flat_map_trait_item(configure!(self, item), self)
+    }
+
+    fn visit_mac(&mut self, _mac: &mut ast::Mac) {
+        // Don't configure interpolated AST (cf. issue #34171).
+        // Interpolated AST will get configured once the surrounding tokens are parsed.
+    }
+
+    fn visit_pat(&mut self, pat: &mut P<ast::Pat>) {
+        self.configure_pat(pat);
+        noop_visit_pat(pat, self)
+    }
+
+    fn visit_fn_decl(&mut self, mut fn_decl: &mut P<ast::FnDecl>) {
+        self.configure_fn_decl(&mut fn_decl);
+        noop_visit_fn_decl(fn_decl, self);
+    }
+}
+
+fn is_cfg(attr: &ast::Attribute) -> bool {
+    attr.check_name(sym::cfg)
+}
+
+/// Process the potential `cfg` attributes on a module.
+/// Also determine if the module should be included in this configuration.
+pub fn process_configure_mod(
+    sess: &ParseSess,
+    cfg_mods: bool,
+    attrs: &[ast::Attribute],
+) -> (bool, Vec<ast::Attribute>) {
+    // Don't perform gated feature checking.
+    let mut strip_unconfigured = StripUnconfigured { sess, features: None };
+    let mut attrs = attrs.to_owned();
+    strip_unconfigured.process_cfg_attrs(&mut attrs);
+    (!cfg_mods || strip_unconfigured.in_cfg(&attrs), attrs)
+}
index 3a983404220a4a60fbbd154c1efb4fd23477ef40..1215c7a199a98816d90e73fb3ef5f57f31d78764 100644 (file)
@@ -25,6 +25,8 @@
 use parser::{Parser, emit_unclosed_delims, make_unclosed_delims_error};
 pub mod lexer;
 pub mod validate_attr;
+#[macro_use]
+pub mod config;
 
 #[derive(Clone)]
 pub struct Directory<'a> {
index 3110f15e80b6ed80a49693dbc14b6ca66f99855c..1621c9ffc02c314532dee3f611e6327a776c5870 100644 (file)
@@ -41,7 +41,7 @@ pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
     /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
     pub(super) fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
         // HACK(Centril): See documentation on `ParseSess::process_cfg_mod`.
-        let (in_cfg, outer_attrs) = (self.sess.process_cfg_mod)(
+        let (in_cfg, outer_attrs) = crate::config::process_configure_mod(
             self.sess,
             self.cfg_mods,
             outer_attrs,
diff --git a/src/libsyntax_expand/config.rs b/src/libsyntax_expand/config.rs
deleted file mode 100644 (file)
index 7b927fb..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-use rustc_parse::validate_attr;
-use syntax::attr::HasAttrs;
-use syntax::feature_gate::{
-    feature_err,
-    EXPLAIN_STMT_ATTR_SYNTAX,
-    Features,
-    get_features,
-    GateIssue,
-};
-use syntax::attr;
-use syntax::ast;
-use syntax::edition::Edition;
-use syntax::mut_visit::*;
-use syntax::ptr::P;
-use syntax::sess::ParseSess;
-use syntax::util::map_in_place::MapInPlace;
-use syntax_pos::symbol::sym;
-
-use errors::Applicability;
-use smallvec::SmallVec;
-
-/// A folder that strips out items that do not belong in the current configuration.
-pub struct StripUnconfigured<'a> {
-    pub sess: &'a ParseSess,
-    pub features: Option<&'a Features>,
-}
-
-// `cfg_attr`-process the crate's attributes and compute the crate's features.
-pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
-                allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
-    let features;
-    {
-        let mut strip_unconfigured = StripUnconfigured {
-            sess,
-            features: None,
-        };
-
-        let unconfigured_attrs = krate.attrs.clone();
-        let err_count = sess.span_diagnostic.err_count();
-        if let Some(attrs) = strip_unconfigured.configure(krate.attrs) {
-            krate.attrs = attrs;
-        } else { // the entire crate is unconfigured
-            krate.attrs = Vec::new();
-            krate.module.items = Vec::new();
-            return (krate, Features::new());
-        }
-
-        features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features);
-
-        // Avoid reconfiguring malformed `cfg_attr`s
-        if err_count == sess.span_diagnostic.err_count() {
-            strip_unconfigured.features = Some(&features);
-            strip_unconfigured.configure(unconfigured_attrs);
-        }
-    }
-
-    (krate, features)
-}
-
-#[macro_export]
-macro_rules! configure {
-    ($this:ident, $node:ident) => {
-        match $this.configure($node) {
-            Some(node) => node,
-            None => return Default::default(),
-        }
-    }
-}
-
-impl<'a> StripUnconfigured<'a> {
-    pub fn configure<T: HasAttrs>(&mut self, mut node: T) -> Option<T> {
-        self.process_cfg_attrs(&mut node);
-        if self.in_cfg(node.attrs()) { Some(node) } else { None }
-    }
-
-    /// Parse and expand all `cfg_attr` attributes into a list of attributes
-    /// that are within each `cfg_attr` that has a true configuration predicate.
-    ///
-    /// Gives compiler warnigns if any `cfg_attr` does not contain any
-    /// attributes and is in the original source code. Gives compiler errors if
-    /// the syntax of any `cfg_attr` is incorrect.
-    pub fn process_cfg_attrs<T: HasAttrs>(&mut self, node: &mut T) {
-        node.visit_attrs(|attrs| {
-            attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
-        });
-    }
-
-    /// Parse and expand a single `cfg_attr` attribute into a list of attributes
-    /// when the configuration predicate is true, or otherwise expand into an
-    /// empty list of attributes.
-    ///
-    /// Gives a compiler warning when the `cfg_attr` contains no attributes and
-    /// is in the original source file. Gives a compiler error if the syntax of
-    /// the attribute is incorrect.
-    fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
-        if !attr.has_name(sym::cfg_attr) {
-            return vec![attr];
-        }
-        if attr.get_normal_item().tokens.is_empty() {
-            self.sess.span_diagnostic
-                .struct_span_err(
-                    attr.span,
-                    "malformed `cfg_attr` attribute input",
-                ).span_suggestion(
-                    attr.span,
-                    "missing condition and attribute",
-                    "#[cfg_attr(condition, attribute, other_attribute, ...)]".to_owned(),
-                    Applicability::HasPlaceholders,
-                ).note("for more information, visit \
-                       <https://doc.rust-lang.org/reference/conditional-compilation.html\
-                       #the-cfg_attr-attribute>")
-                .emit();
-            return vec![];
-        }
-
-        let res = rustc_parse::parse_in_attr(self.sess, &attr, |p| p.parse_cfg_attr());
-        let (cfg_predicate, expanded_attrs) = match res {
-            Ok(result) => result,
-            Err(mut e) => {
-                e.emit();
-                return vec![];
-            }
-        };
-
-        // Lint on zero attributes in source.
-        if expanded_attrs.is_empty() {
-            return vec![attr];
-        }
-
-        // At this point we know the attribute is considered used.
-        attr::mark_used(&attr);
-
-        if attr::cfg_matches(&cfg_predicate, self.sess, self.features) {
-            // We call `process_cfg_attr` recursively in case there's a
-            // `cfg_attr` inside of another `cfg_attr`. E.g.
-            //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
-            expanded_attrs.into_iter()
-            .flat_map(|(item, span)| self.process_cfg_attr(attr::mk_attr_from_item(
-                attr.style,
-                item,
-                span,
-            )))
-            .collect()
-        } else {
-            vec![]
-        }
-    }
-
-    /// Determines if a node with the given attributes should be included in this configuration.
-    pub fn in_cfg(&self, attrs: &[ast::Attribute]) -> bool {
-        attrs.iter().all(|attr| {
-            if !is_cfg(attr) {
-                return true;
-            }
-
-            let error = |span, msg, suggestion: &str| {
-                let mut err = self.sess.span_diagnostic.struct_span_err(span, msg);
-                if !suggestion.is_empty() {
-                    err.span_suggestion(
-                        span,
-                        "expected syntax is",
-                        suggestion.into(),
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                err.emit();
-                true
-            };
-
-            let meta_item = match validate_attr::parse_meta(self.sess, attr) {
-                Ok(meta_item) => meta_item,
-                Err(mut err) => { err.emit(); return true; }
-            };
-            let nested_meta_items = if let Some(nested_meta_items) = meta_item.meta_item_list() {
-                nested_meta_items
-            } else {
-                return error(meta_item.span, "`cfg` is not followed by parentheses",
-                                             "cfg(/* predicate */)");
-            };
-
-            if nested_meta_items.is_empty() {
-                return error(meta_item.span, "`cfg` predicate is not specified", "");
-            } else if nested_meta_items.len() > 1 {
-                return error(nested_meta_items.last().unwrap().span(),
-                             "multiple `cfg` predicates are specified", "");
-            }
-
-            match nested_meta_items[0].meta_item() {
-                Some(meta_item) => attr::cfg_matches(meta_item, self.sess, self.features),
-                None => error(nested_meta_items[0].span(),
-                              "`cfg` predicate key cannot be a literal", ""),
-            }
-        })
-    }
-
-    /// Visit attributes on expression and statements (but not attributes on items in blocks).
-    fn visit_expr_attrs(&mut self, attrs: &[ast::Attribute]) {
-        // flag the offending attributes
-        for attr in attrs.iter() {
-            self.maybe_emit_expr_attr_err(attr);
-        }
-    }
-
-    /// If attributes are not allowed on expressions, emit an error for `attr`
-    pub fn maybe_emit_expr_attr_err(&self, attr: &ast::Attribute) {
-        if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) {
-            let mut err = feature_err(self.sess,
-                                      sym::stmt_expr_attributes,
-                                      attr.span,
-                                      GateIssue::Language,
-                                      EXPLAIN_STMT_ATTR_SYNTAX);
-
-            if attr.is_doc_comment() {
-                err.help("`///` is for documentation comments. For a plain comment, use `//`.");
-            }
-
-            err.emit();
-        }
-    }
-
-    pub fn configure_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
-        let ast::ForeignMod { abi: _, items } = foreign_mod;
-        items.flat_map_in_place(|item| self.configure(item));
-    }
-
-    pub fn configure_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) {
-        params.flat_map_in_place(|param| self.configure(param));
-    }
-
-    fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) {
-        match vdata {
-            ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) =>
-                fields.flat_map_in_place(|field| self.configure(field)),
-            ast::VariantData::Unit(_) => {}
-        }
-    }
-
-    pub fn configure_item_kind(&mut self, item: &mut ast::ItemKind) {
-        match item {
-            ast::ItemKind::Struct(def, _generics) |
-            ast::ItemKind::Union(def, _generics) => self.configure_variant_data(def),
-            ast::ItemKind::Enum(ast::EnumDef { variants }, _generics) => {
-                variants.flat_map_in_place(|variant| self.configure(variant));
-                for variant in variants {
-                    self.configure_variant_data(&mut variant.data);
-                }
-            }
-            _ => {}
-        }
-    }
-
-    pub fn configure_expr_kind(&mut self, expr_kind: &mut ast::ExprKind) {
-        match expr_kind {
-            ast::ExprKind::Match(_m, arms) => {
-                arms.flat_map_in_place(|arm| self.configure(arm));
-            }
-            ast::ExprKind::Struct(_path, fields, _base) => {
-                fields.flat_map_in_place(|field| self.configure(field));
-            }
-            _ => {}
-        }
-    }
-
-    pub fn configure_expr(&mut self, expr: &mut P<ast::Expr>) {
-        self.visit_expr_attrs(expr.attrs());
-
-        // If an expr is valid to cfg away it will have been removed by the
-        // outer stmt or expression folder before descending in here.
-        // Anything else is always required, and thus has to error out
-        // in case of a cfg attr.
-        //
-        // N.B., this is intentionally not part of the visit_expr() function
-        //     in order for filter_map_expr() to be able to avoid this check
-        if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
-            let msg = "removing an expression is not supported in this position";
-            self.sess.span_diagnostic.span_err(attr.span, msg);
-        }
-
-        self.process_cfg_attrs(expr)
-    }
-
-    pub fn configure_pat(&mut self, pat: &mut P<ast::Pat>) {
-        if let ast::PatKind::Struct(_path, fields, _etc) = &mut pat.kind {
-            fields.flat_map_in_place(|field| self.configure(field));
-        }
-    }
-
-    pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
-        fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
-    }
-}
-
-impl<'a> MutVisitor for StripUnconfigured<'a> {
-    fn visit_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
-        self.configure_foreign_mod(foreign_mod);
-        noop_visit_foreign_mod(foreign_mod, self);
-    }
-
-    fn visit_item_kind(&mut self, item: &mut ast::ItemKind) {
-        self.configure_item_kind(item);
-        noop_visit_item_kind(item, self);
-    }
-
-    fn visit_expr(&mut self, expr: &mut P<ast::Expr>) {
-        self.configure_expr(expr);
-        self.configure_expr_kind(&mut expr.kind);
-        noop_visit_expr(expr, self);
-    }
-
-    fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
-        let mut expr = configure!(self, expr);
-        self.configure_expr_kind(&mut expr.kind);
-        noop_visit_expr(&mut expr, self);
-        Some(expr)
-    }
-
-    fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
-        noop_flat_map_stmt(configure!(self, stmt), self)
-    }
-
-    fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
-        noop_flat_map_item(configure!(self, item), self)
-    }
-
-    fn flat_map_impl_item(&mut self, item: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
-        noop_flat_map_impl_item(configure!(self, item), self)
-    }
-
-    fn flat_map_trait_item(&mut self, item: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
-        noop_flat_map_trait_item(configure!(self, item), self)
-    }
-
-    fn visit_mac(&mut self, _mac: &mut ast::Mac) {
-        // Don't configure interpolated AST (cf. issue #34171).
-        // Interpolated AST will get configured once the surrounding tokens are parsed.
-    }
-
-    fn visit_pat(&mut self, pat: &mut P<ast::Pat>) {
-        self.configure_pat(pat);
-        noop_visit_pat(pat, self)
-    }
-
-    fn visit_fn_decl(&mut self, mut fn_decl: &mut P<ast::FnDecl>) {
-        self.configure_fn_decl(&mut fn_decl);
-        noop_visit_fn_decl(fn_decl, self);
-    }
-}
-
-fn is_cfg(attr: &ast::Attribute) -> bool {
-    attr.check_name(sym::cfg)
-}
-
-/// Process the potential `cfg` attributes on a module.
-/// Also determine if the module should be included in this configuration.
-pub fn process_configure_mod(
-    sess: &ParseSess,
-    cfg_mods: bool,
-    attrs: &[ast::Attribute],
-) -> (bool, Vec<ast::Attribute>) {
-    // Don't perform gated feature checking.
-    let mut strip_unconfigured = StripUnconfigured { sess, features: None };
-    let mut attrs = attrs.to_owned();
-    strip_unconfigured.process_cfg_attrs(&mut attrs);
-    (!cfg_mods || strip_unconfigured.in_cfg(&attrs), attrs)
-}
index 06aa5deb6e0184dd74231c0dd08aac951cd9a005..2532bbc0fe240d47294bd60362a2cda7e62d9f7c 100644 (file)
@@ -4,7 +4,7 @@
 use crate::mbe::macro_rules::annotate_err_with_kind;
 use crate::placeholders::{placeholder, PlaceholderExpander};
 use crate::config::StripUnconfigured;
-use crate::configure;
+use rustc_parse::configure;
 
 use rustc_parse::DirectoryOwnership;
 use rustc_parse::parser::Parser;
index 46d59dd249c3197b9198ddca30222b345faa3405..0aa34af7a762d32708429d2236d988d9e8f31517 100644 (file)
@@ -33,7 +33,7 @@ macro_rules! panictry {
 pub mod base;
 pub mod build;
 pub mod expand;
-#[macro_use] pub mod config;
+pub use rustc_parse::config;
 pub mod proc_macro;
 
 crate mod mbe;