]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax_expand/expand.rs
Simplify Cache wrapper to single type, impl Deref on it, fix all compilation errors...
[rust.git] / src / libsyntax_expand / expand.rs
index 2532bbc0fe240d47294bd60362a2cda7e62d9f7c..a6ced1439c5d95c5e07800899cd4f8980872fa9c 100644 (file)
@@ -4,16 +4,17 @@
 use crate::mbe::macro_rules::annotate_err_with_kind;
 use crate::placeholders::{placeholder, PlaceholderExpander};
 use crate::config::StripUnconfigured;
-use rustc_parse::configure;
 
+use rustc_feature::Features;
+use rustc_parse::configure;
 use rustc_parse::DirectoryOwnership;
 use rustc_parse::parser::Parser;
 use rustc_parse::validate_attr;
 use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
 use syntax::ast::{MacStmtStyle, StmtKind, ItemKind};
-use syntax::attr::{self, HasAttrs};
+use syntax::attr::{self, HasAttrs, is_builtin_attr};
 use syntax::source_map::respan;
-use syntax::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
+use syntax::feature_gate::{self, feature_err};
 use syntax::mut_visit::*;
 use syntax::print::pprust;
 use syntax::ptr::P;
@@ -86,7 +87,7 @@ pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
                         // mention some macro variable from those arguments even if it's not used.
                         #[cfg_attr(bootstrap, allow(unused_macros))]
                         macro _repeating($flat_map_ast_elt) {}
-                        placeholder(AstFragmentKind::$Kind, *id).$make_ast()
+                        placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
                     })),)?)*
                     _ => panic!("unexpected AST fragment kind")
                 }
@@ -275,6 +276,23 @@ pub enum InvocationKind {
     },
 }
 
+impl InvocationKind {
+    fn placeholder_visibility(&self) -> Option<ast::Visibility> {
+        // HACK: For unnamed fields placeholders should have the same visibility as the actual
+        // fields because for tuple structs/variants resolve determines visibilities of their
+        // constructor using these field visibilities before attributes on them are are expanded.
+        // The assumption is that the attribute expansion cannot change field visibilities,
+        // and it holds because only inert attributes are supported in this position.
+        match self {
+            InvocationKind::Attr { item: Annotatable::StructField(field), .. } |
+            InvocationKind::Derive { item: Annotatable::StructField(field), .. } |
+            InvocationKind::DeriveContainer { item: Annotatable::StructField(field), .. }
+                if field.ident.is_none() => Some(field.vis.clone()),
+            _ => None,
+        }
+    }
+}
+
 impl Invocation {
     pub fn span(&self) -> Span {
         match &self.kind {
@@ -709,13 +727,13 @@ fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
         if self.cx.ecfg.proc_macro_hygiene() {
             return
         }
-        emit_feature_err(
+        feature_err(
             self.cx.parse_sess,
             sym::proc_macro_hygiene,
             span,
-            GateIssue::Language,
             &format!("custom attributes cannot be applied to {}", kind),
-        );
+        )
+        .emit();
     }
 
     fn gate_proc_macro_input(&self, annotatable: &Annotatable) {
@@ -727,13 +745,13 @@ impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
             fn visit_item(&mut self, item: &'ast ast::Item) {
                 match &item.kind {
                     ast::ItemKind::Mod(module) if !module.inline => {
-                        emit_feature_err(
+                        feature_err(
                             self.parse_sess,
                             sym::proc_macro_hygiene,
                             item.span,
-                            GateIssue::Language,
                             "non-inline modules in proc macro input are unstable",
-                        );
+                        )
+                        .emit();
                     }
                     _ => {}
                 }
@@ -772,13 +790,13 @@ fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) {
         if self.cx.ecfg.proc_macro_hygiene() {
             return
         }
-        emit_feature_err(
+        feature_err(
             self.cx.parse_sess,
             sym::proc_macro_hygiene,
             span,
-            GateIssue::Language,
             &format!("procedural macros cannot be expanded to {}", kind),
-        );
+        )
+        .emit();
     }
 
     fn parse_ast_fragment(
@@ -931,6 +949,7 @@ fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> A
             _ => None,
         };
         let expn_id = ExpnId::fresh(expn_data);
+        let vis = kind.placeholder_visibility();
         self.invocations.push(Invocation {
             kind,
             fragment_kind,
@@ -940,7 +959,7 @@ fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> A
                 ..self.cx.current_expansion.clone()
             },
         });
-        placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id))
+        placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
     }
 
     fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: AstFragmentKind) -> AstFragment {
@@ -973,9 +992,11 @@ fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, after_derive: &mut bo
         if let Some(attr) = &attr {
             if !self.cx.ecfg.custom_inner_attributes() &&
                attr.style == ast::AttrStyle::Inner && !attr.has_name(sym::test) {
-                emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
-                                 attr.span, GateIssue::Language,
-                                 "non-builtin inner attributes are unstable");
+                feature_err(
+                    &self.cx.parse_sess, sym::custom_inner_attributes, attr.span,
+                    "non-builtin inner attributes are unstable"
+                )
+                .emit();
             }
         }
         attr