]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/macros.rs
Rollup merge of #66789 - eddyb:mir-source-scope-local-data, r=oli-obk
[rust.git] / src / librustc_resolve / macros.rs
index 4f687b5ba92006a9ab379b2cf61ef65824c00dac..9e7098da49f32b111ec027252583458df462f7f6 100644 (file)
 use rustc::session::Session;
 use rustc::util::nodemap::FxHashSet;
 use rustc::{ty, lint, span_bug};
+use rustc_feature::is_builtin_attr_name;
 use syntax::ast::{self, NodeId, Ident};
 use syntax::attr::{self, StabilityLevel};
 use syntax::edition::Edition;
-use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
-use syntax::feature_gate::GateIssue;
+use syntax::feature_gate::feature_err;
 use syntax::print::pprust;
-use syntax::symbol::{Symbol, kw, sym};
 use syntax_expand::base::{self, InvocationRes, Indeterminate};
 use syntax_expand::base::SyntaxExtension;
 use syntax_expand::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
 use syntax_expand::compile_declarative_macro;
 use syntax_pos::hygiene::{self, ExpnId, ExpnData, ExpnKind};
+use syntax_pos::symbol::{Symbol, kw, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
 use std::{mem, ptr};
@@ -346,13 +346,8 @@ fn smart_resolve_macro_path(
                segment.ident.as_str().starts_with("rustc") {
                 let msg =
                     "attributes starting with `rustc` are reserved for use by the `rustc` compiler";
-                emit_feature_err(
-                    &self.session.parse_sess,
-                    sym::rustc_attrs,
-                    segment.ident.span,
-                    GateIssue::Language,
-                    msg,
-                );
+                feature_err(&self.session.parse_sess, sym::rustc_attrs, segment.ident.span, msg)
+                    .emit();
             }
         }
 
@@ -466,11 +461,12 @@ pub fn resolve_macro_path(
     ) -> Result<&'a NameBinding<'a>, Determinacy> {
         bitflags::bitflags! {
             struct Flags: u8 {
-                const MACRO_RULES        = 1 << 0;
-                const MODULE             = 1 << 1;
-                const MISC_SUGGEST_CRATE = 1 << 2;
-                const MISC_SUGGEST_SELF  = 1 << 3;
-                const MISC_FROM_PRELUDE  = 1 << 4;
+                const MACRO_RULES          = 1 << 0;
+                const MODULE               = 1 << 1;
+                const DERIVE_HELPER_COMPAT = 1 << 2;
+                const MISC_SUGGEST_CRATE   = 1 << 3;
+                const MISC_SUGGEST_SELF    = 1 << 4;
+                const MISC_FROM_PRELUDE    = 1 << 5;
             }
         }
 
@@ -528,8 +524,10 @@ struct Flags: u8 {
                         match this.resolve_macro_path(derive, Some(MacroKind::Derive),
                                                       parent_scope, true, force) {
                             Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
-                                let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
-                                result = ok(res, derive.span, this.arenas);
+                                let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
+                                               ty::Visibility::Public, derive.span, ExpnId::root())
+                                               .to_name_binding(this.arenas);
+                                result = Ok((binding, Flags::DERIVE_HELPER_COMPAT));
                                 break;
                             }
                             Ok(_) | Err(Determinacy::Determined) => {}
@@ -659,13 +657,17 @@ struct Flags: u8 {
                         let (res, innermost_res) = (binding.res(), innermost_binding.res());
                         if res != innermost_res {
                             let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
-                            let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
+                            let is_derive_helper_compat = |res, flags: Flags| {
+                                res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper) &&
+                                flags.contains(Flags::DERIVE_HELPER_COMPAT)
+                            };
 
                             let ambiguity_error_kind = if is_import {
                                 Some(AmbiguityKind::Import)
                             } else if innermost_res == builtin || res == builtin {
                                 Some(AmbiguityKind::BuiltinAttr)
-                            } else if innermost_res == derive_helper || res == derive_helper {
+                            } else if is_derive_helper_compat(innermost_res, innermost_flags) ||
+                                      is_derive_helper_compat(res, flags) {
                                 Some(AmbiguityKind::DeriveHelper)
                             } else if innermost_flags.contains(Flags::MACRO_RULES) &&
                                       flags.contains(Flags::MODULE) &&
@@ -873,8 +875,8 @@ fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>
         }
     }
 
-    /// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined
-    /// extension partially or entirely for built-in macros and legacy plugin macros.
+    /// Compile the macro into a `SyntaxExtension` and possibly replace
+    /// its expander to a pre-defined one for built-in macros.
     crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension {
         let mut result = compile_declarative_macro(
             &self.session.parse_sess, self.session.features_untracked(), item, edition
@@ -883,14 +885,9 @@ fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>
         if result.is_builtin {
             // The macro was marked with `#[rustc_builtin_macro]`.
             if let Some(ext) = self.builtin_macros.remove(&item.ident.name) {
-                if ext.is_builtin {
-                    // The macro is a built-in, replace only the expander function.
-                    result.kind = ext.kind;
-                } else {
-                    // The macro is from a plugin, the in-source definition is dummy,
-                    // take all the data from the resolver.
-                    result = ext;
-                }
+                // The macro is a built-in, replace its expander function
+                // while still taking everything else from the source code.
+                result.kind = ext.kind;
             } else {
                 let msg = format!("cannot find a built-in macro with name `{}`", item.ident);
                 self.session.span_err(item.span, &msg);