]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #53270 - petrochenkov:macuse-regr, r=alexcrichton
authorbors <bors@rust-lang.org>
Mon, 13 Aug 2018 17:10:04 +0000 (17:10 +0000)
committerbors <bors@rust-lang.org>
Mon, 13 Aug 2018 17:10:04 +0000 (17:10 +0000)
Fix a few regressions from enabling macro modularization

The first commit restores the old behavior for some minor unstable stuff (`rustc_*` and `derive_*` attributes) and adds a new feature gate for arbitrary tokens in non-macro attributes.

The second commit fixes https://github.com/rust-lang/rust/issues/53205

The third commit fixes https://github.com/rust-lang/rust/issues/53144.
Same technique is used as for other things blocking expansion progress - if something causes indeterminacy too often, then prohibit it.
In this case referring to crate-local macro-expanded `#[macro_export]` macros via module-relative paths is prohibited, see comments in code for more details.

cc https://github.com/rust-lang/rust/pull/50911

24 files changed:
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/libsyntax/feature_gate.rs
src/test/compile-fail-fulldeps/proc-macro/proc-macro-attributes.rs
src/test/compile-fail/gated-attr-literals.rs
src/test/compile-fail/macro-attribute.rs
src/test/parse-fail/attr-bad-meta.rs
src/test/run-pass-fulldeps/proc-macro/derive-b.rs
src/test/ui/feature-gate-rustc-attrs-1.rs [new file with mode: 0644]
src/test/ui/feature-gate-rustc-attrs-1.stderr [new file with mode: 0644]
src/test/ui/feature-gate-rustc-attrs.rs
src/test/ui/feature-gate-rustc-attrs.stderr
src/test/ui/feature-gate-unrestricted-attribute-tokens.rs [new file with mode: 0644]
src/test/ui/feature-gate-unrestricted-attribute-tokens.stderr [new file with mode: 0644]
src/test/ui/imports/local-modularized-tricky-fail-3.rs [new file with mode: 0644]
src/test/ui/imports/local-modularized-tricky-fail-3.stderr [new file with mode: 0644]
src/test/ui/issue-11692-2.rs
src/test/ui/issue-11692-2.stderr
src/test/ui/macro-path-prelude-fail-3.rs
src/test/ui/macro-path-prelude-fail-3.stderr
src/test/ui/macro-path-prelude-shadowing.rs
src/test/ui/macro-path-prelude-shadowing.stderr

index 0be1bf3011e78dcc21801915fce229c0b22fc322..bf87b00c14969b667eb863136ed5ff4e9597bb53 100644 (file)
@@ -789,7 +789,6 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> {
     fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
         let mark = id.placeholder_to_mark();
         self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark);
-        self.resolver.unresolved_invocations_macro_export.insert(mark);
         let invocation = self.resolver.invocations[&mark];
         invocation.module.set(self.resolver.current_module);
         invocation.legacy_scope.set(self.legacy_scope);
index 8ff44834929064e7661e9a69382caa98caffb4f9..e31e2cc1dff59ee919e992991f273bf2f650136e 100644 (file)
@@ -1385,6 +1385,8 @@ pub struct Resolver<'a, 'b: 'a> {
     use_injections: Vec<UseError<'a>>,
     /// `use` injections for proc macros wrongly imported with #[macro_use]
     proc_mac_errors: Vec<macros::ProcMacError>,
+    /// crate-local macro expanded `macro_export` referred to by a module-relative path
+    macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
 
     gated_errors: FxHashSet<Span>,
     disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
@@ -1432,9 +1434,6 @@ pub struct Resolver<'a, 'b: 'a> {
 
     /// Only supposed to be used by rustdoc, otherwise should be false.
     pub ignore_extern_prelude_feature: bool,
-
-    /// Macro invocations in the whole crate that can expand into a `#[macro_export] macro_rules`.
-    unresolved_invocations_macro_export: FxHashSet<Mark>,
 }
 
 /// Nothing really interesting here, it just provides memory for the rest of the crate.
@@ -1706,6 +1705,7 @@ pub fn new(session: &'a Session,
             proc_mac_errors: Vec::new(),
             gated_errors: FxHashSet(),
             disallowed_shadowing: Vec::new(),
+            macro_expanded_macro_export_errors: BTreeSet::new(),
 
             arenas,
             dummy_binding: arenas.alloc_name_binding(NameBinding {
@@ -1737,7 +1737,6 @@ pub fn new(session: &'a Session,
             current_type_ascription: Vec::new(),
             injected_crate: None,
             ignore_extern_prelude_feature: false,
-            unresolved_invocations_macro_export: FxHashSet(),
         }
     }
 
@@ -4126,6 +4125,7 @@ fn get_traits_in_module_containing_item(&mut self,
                                             ns: Namespace,
                                             module: Module<'a>,
                                             found_traits: &mut Vec<TraitCandidate>) {
+        assert!(ns == TypeNS || ns == ValueNS);
         let mut traits = module.traits.borrow_mut();
         if traits.is_none() {
             let mut collected_traits = Vec::new();
@@ -4371,6 +4371,14 @@ fn report_errors(&mut self, krate: &Crate) {
         self.report_proc_macro_import(krate);
         let mut reported_spans = FxHashSet();
 
+        for &(span_use, span_def) in &self.macro_expanded_macro_export_errors {
+            let msg = "macro-expanded `macro_export` macros from the current crate \
+                       cannot be referred to by absolute paths";
+            self.session.struct_span_err(span_use, msg)
+                        .span_note(span_def, "the macro is defined here")
+                        .emit();
+        }
+
         for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
             if !reported_spans.insert(span) { continue }
             let participle = |binding: &NameBinding| {
index d680b2d9f7d745112bdaede946922cf5f4ae3aec..fe9d3c7eb998268bcdf7ae683e7817acdb4f3ce0 100644 (file)
@@ -28,6 +28,7 @@
 use syntax::ext::hygiene::{self, Mark};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{self, feature_err, emit_feature_err, is_builtin_attr_name, GateIssue};
+use syntax::feature_gate::EXPLAIN_DERIVE_UNDERSCORE;
 use syntax::fold::{self, Folder};
 use syntax::parse::parser::PathStyle;
 use syntax::parse::token::{self, Token};
@@ -195,9 +196,7 @@ fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFra
 
         self.current_module = invocation.module.get();
         self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
-        self.unresolved_invocations_macro_export.remove(&mark);
         self.current_module.unresolved_invocations.borrow_mut().extend(derives);
-        self.unresolved_invocations_macro_export.extend(derives);
         for &derive in derives {
             self.invocations.insert(derive, invocation);
         }
@@ -338,19 +337,37 @@ fn resolve_invoc(&mut self, invoc: &Invocation, scope: Mark, force: bool)
             match attr_kind {
                 NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper |
                 NonMacroAttrKind::Custom if is_attr_invoc => {
+                    let features = self.session.features_untracked();
                     if attr_kind == NonMacroAttrKind::Tool &&
-                       !self.session.features_untracked().tool_attributes {
+                       !features.tool_attributes {
                         feature_err(&self.session.parse_sess, "tool_attributes",
                                     invoc.span(), GateIssue::Language,
                                     "tool attributes are unstable").emit();
                     }
-                    if attr_kind == NonMacroAttrKind::Custom &&
-                       !self.session.features_untracked().custom_attribute {
-                        let msg = format!("The attribute `{}` is currently unknown to the compiler \
-                                           and may have meaning added to it in the future", path);
-                        feature_err(&self.session.parse_sess, "custom_attribute", invoc.span(),
-                                    GateIssue::Language, &msg).emit();
+                    if attr_kind == NonMacroAttrKind::Custom {
+                        assert!(path.segments.len() == 1);
+                        let name = path.segments[0].ident.name.as_str();
+                        if name.starts_with("rustc_") {
+                            if !features.rustc_attrs {
+                                let msg = "unless otherwise specified, attributes with the prefix \
+                                        `rustc_` are reserved for internal compiler diagnostics";
+                                feature_err(&self.session.parse_sess, "rustc_attrs", invoc.span(),
+                                            GateIssue::Language, &msg).emit();
+                            }
+                        } else if name.starts_with("derive_") {
+                            if !features.custom_derive {
+                                feature_err(&self.session.parse_sess, "custom_derive", invoc.span(),
+                                            GateIssue::Language, EXPLAIN_DERIVE_UNDERSCORE).emit();
+                            }
+                        } else if !features.custom_attribute {
+                            let msg = format!("The attribute `{}` is currently unknown to the \
+                                               compiler and may have meaning added to it in the \
+                                               future", path);
+                            feature_err(&self.session.parse_sess, "custom_attribute", invoc.span(),
+                                        GateIssue::Language, &msg).emit();
+                        }
                     }
+
                     return Ok(Some(Lrc::new(SyntaxExtension::NonMacroAttr {
                         mark_used: attr_kind == NonMacroAttrKind::Tool,
                     })));
@@ -650,7 +667,10 @@ enum WhereToResolve<'a> {
                     }
                 }
                 WhereToResolve::BuiltinAttrs => {
-                    if is_builtin_attr_name(ident.name) {
+                    // FIXME: Only built-in attributes are not considered as candidates for
+                    // non-attributes to fight off regressions on stable channel (#53205).
+                    // We need to come up with some more principled approach instead.
+                    if is_attr && is_builtin_attr_name(ident.name) {
                         let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
                                        ty::Visibility::Public, ident.span, Mark::root())
                                        .to_name_binding(self.arenas);
index a3a9b938bbd6fd859b962bf12b2c942f321d1519..715292bc11622891508a833f5d8636ad08e7177f 100644 (file)
@@ -146,6 +146,14 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
             .try_borrow_mut()
             .map_err(|_| Determined)?; // This happens when there is a cycle of imports
 
+        if let Some(binding) = resolution.binding {
+            if !restricted_shadowing && binding.expansion != Mark::root() {
+                if let NameBindingKind::Def(_, true) = binding.kind {
+                    self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
+                }
+            }
+        }
+
         if record_used {
             if let Some(binding) = resolution.binding {
                 if let Some(shadowed_glob) = resolution.shadowed_glob {
@@ -211,9 +219,15 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
         // if it cannot be shadowed by some new item/import expanded from a macro.
         // This happens either if there are no unexpanded macros, or expanded names cannot
         // shadow globs (that happens in macro namespace or with restricted shadowing).
-        let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty() ||
-                                (ns == MacroNS && ptr::eq(module, self.graph_root) &&
-                                 !self.unresolved_invocations_macro_export.is_empty());
+        //
+        // Additionally, any macro in any module can plant names in the root module if it creates
+        // `macro_export` macros, so the root module effectively has unresolved invocations if any
+        // module has unresolved invocations.
+        // However, it causes resolution/expansion to stuck too often (#53144), so, to make
+        // progress, we have to ignore those potential unresolved invocations from other modules
+        // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
+        // shadowing is enabled, see `macro_expanded_macro_export_errors`).
+        let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty();
         if let Some(binding) = resolution.binding {
             if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
                 return check_usable(self, binding);
index 976708ae788161e97b4de6e18f81d9596b2ffbbf..b779b2eb689e8aabbba8d55aea9ddde481115859 100644 (file)
@@ -90,7 +90,7 @@ pub fn use_extern_macros(&self) -> bool {
                 self.macros_in_extern || self.proc_macro_path_invoc ||
                 self.proc_macro_mod || self.proc_macro_expr ||
                 self.proc_macro_non_items || self.proc_macro_gen ||
-                self.stmt_expr_attributes
+                self.stmt_expr_attributes || self.unrestricted_attribute_tokens
             }
         }
     };
@@ -504,6 +504,9 @@ pub fn use_extern_macros(&self) -> bool {
     // impl<I:Iterator> Iterator for &mut Iterator
     // impl Debug for Foo<'_>
     (active, impl_header_lifetime_elision, "1.30.0", Some(15872), Some(Edition::Edition2018)),
+
+    // Support for arbitrary delimited token streams in non-macro attributes.
+    (active, unrestricted_attribute_tokens, "1.30.0", Some(44690), None),
 );
 
 declare_features! (
@@ -721,8 +724,7 @@ pub fn is_builtin_attr_name(name: ast::Name) -> bool {
 }
 
 pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
-    BUILTIN_ATTRIBUTES.iter().any(|&(builtin_name, _, _)| attr.path == builtin_name) ||
-    attr.name().as_str().starts_with("rustc_")
+    BUILTIN_ATTRIBUTES.iter().any(|&(builtin_name, _, _)| attr.path == builtin_name)
 }
 
 // Attributes that have a special meaning to rustc or rustdoc
@@ -1521,25 +1523,27 @@ fn visit_attribute(&mut self, attr: &ast::Attribute) {
             }
         }
 
-        // allow attr_literals in #[repr(align(x))] and #[repr(packed(n))]
-        let mut allow_attr_literal = false;
-        if attr.path == "repr" {
-            if let Some(content) = attr.meta_item_list() {
-                allow_attr_literal = content.iter().any(
-                    |c| c.check_name("align") || c.check_name("packed"));
-            }
-        }
-
-        if self.context.features.use_extern_macros() && attr::is_known(attr) {
-            return
-        }
+        match attr.parse_meta(self.context.parse_sess) {
+            Ok(meta) => {
+                // allow attr_literals in #[repr(align(x))] and #[repr(packed(n))]
+                let mut allow_attr_literal = false;
+                if attr.path == "repr" {
+                    if let Some(content) = meta.meta_item_list() {
+                        allow_attr_literal = content.iter().any(
+                            |c| c.check_name("align") || c.check_name("packed"));
+                    }
+                }
 
-        if !allow_attr_literal {
-            let meta = panictry!(attr.parse_meta(self.context.parse_sess));
-            if contains_novel_literal(&meta) {
-                gate_feature_post!(&self, attr_literals, attr.span,
-                                   "non-string literals in attributes, or string \
-                                   literals in top-level positions, are experimental");
+                if !allow_attr_literal && contains_novel_literal(&meta) {
+                    gate_feature_post!(&self, attr_literals, attr.span,
+                                    "non-string literals in attributes, or string \
+                                    literals in top-level positions, are experimental");
+                }
+            }
+            Err(mut err) => {
+                err.cancel();
+                gate_feature_post!(&self, unrestricted_attribute_tokens, attr.span,
+                                    "arbitrary tokens in non-macro attributes are unstable");
             }
         }
     }
index 153e4dd05717a42f6ae0933ccc31ec88a938af7c..8d53699c0640e0bb2ce3088491c9329cc8d73ce2 100644 (file)
@@ -21,7 +21,7 @@
 #[C] //~ ERROR: The attribute `C` is currently unknown to the compiler
 #[B(D)]
 #[B(E = "foo")]
-#[B arbitrary tokens] //~ expected one of `(` or `=`, found `arbitrary`
+#[B arbitrary tokens] //~ ERROR arbitrary tokens in non-macro attributes are unstable
 struct B;
 
 fn main() {}
index b500bfc3c21390aa3255c242544a2b951844a7f1..8d36745116b65b3b7e229833e9bd2a8cdcb123d0 100644 (file)
 // Check that literals in attributes don't parse without the feature gate.
 
 // gate-test-attr_literals
-// gate-test-custom_attribute
 
-#![feature(rustc_attrs)]
-#![allow(dead_code)]
-#![allow(unused_variables)]
+#![feature(custom_attribute)]
 
-#[fake_attr] //~ ERROR attribute `fake_attr` is currently unknown
-#[fake_attr(100)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr] // OK
+#[fake_attr(100)]
     //~^ ERROR non-string literals in attributes
-#[fake_attr(1, 2, 3)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(1, 2, 3)]
     //~^ ERROR non-string literals in attributes
-#[fake_attr("hello")] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr("hello")]
     //~^ ERROR string literals in top-level positions, are experimental
-#[fake_attr(name = "hello")] //~ ERROR attribute `fake_attr` is currently unknown
-#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(name = "hello")] // OK
+#[fake_attr(1, "hi", key = 12, true, false)]
     //~^ ERROR non-string literals in attributes, or string literals in top-level positions
-#[fake_attr(key = "hello", val = 10)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(key = "hello", val = 10)]
     //~^ ERROR non-string literals in attributes
-#[fake_attr(key("hello"), val(10))] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(key("hello"), val(10))]
     //~^ ERROR non-string literals in attributes, or string literals in top-level positions
-#[fake_attr(enabled = true, disabled = false)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(enabled = true, disabled = false)]
     //~^ ERROR non-string literals in attributes
-#[fake_attr(true)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(true)]
     //~^ ERROR non-string literals in attributes
-#[fake_attr(pi = 3.14159)] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(pi = 3.14159)]
     //~^ ERROR non-string literals in attributes
-#[fake_attr(b"hi")] //~ ERROR attribute `fake_attr` is currently unknown
+#[fake_attr(b"hi")]
     //~^ ERROR string literals in top-level positions, are experimental
-#[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown
+#[fake_doc(r"doc")]
     //~^ ERROR string literals in top-level positions, are experimental
 struct Q {  }
 
-#[rustc_error]
 fn main() { }
index 52f867fe913b8af0a3de2bcc19a46ecfcf443b66..a77b172487600fa30accb038d043a483d2b8fe98 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[doc = $not_there] //~ error: unexpected token: `$`
+#[doc = $not_there] //~ ERROR arbitrary tokens in non-macro attributes are unstable
 fn main() { }
index d57a813311b5ab509f35fe980da31c47624fbdf2..41db88121cb5292ef9adc410391404a7d7dfcbbc 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 // asterisk is bogus
-#[path*] //~ ERROR expected one of `(` or `=`
+#[path*] //~ ERROR arbitrary tokens in non-macro attributes are unstable
 mod m {}
index 4a7c8f3e8343baa79f95ecadde8255fe28df7233..918d2c17123e88b427106040538b454fd8a6b529 100644 (file)
@@ -11,7 +11,7 @@
 // aux-build:derive-b.rs
 // ignore-stage1
 
-#![feature(proc_macro_path_invoc)]
+#![feature(proc_macro_path_invoc, unrestricted_attribute_tokens)]
 
 extern crate derive_b;
 
diff --git a/src/test/ui/feature-gate-rustc-attrs-1.rs b/src/test/ui/feature-gate-rustc-attrs-1.rs
new file mode 100644 (file)
index 0000000..7295de8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+
+// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.
+
+#[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
+#[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
+
+fn main() {}
diff --git a/src/test/ui/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gate-rustc-attrs-1.stderr
new file mode 100644 (file)
index 0000000..54a580c
--- /dev/null
@@ -0,0 +1,19 @@
+error[E0658]: the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable (see issue #29642)
+  --> $DIR/feature-gate-rustc-attrs-1.rs:15:1
+   |
+LL | #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
+
+error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable (see issue #29642)
+  --> $DIR/feature-gate-rustc-attrs-1.rs:16:1
+   |
+LL | #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
+   | ^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
index 8cfd3e020c69a47da7d3eeb1cf1eb8be261a62fa..99bc51b69c6cbebf31df08a19d9e539dbcb50e7d 100644 (file)
@@ -12,8 +12,6 @@
 
 // Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.
 
-#[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
-#[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
 #[rustc_foo]
 //~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
 
index fda95a5b97a57ba7a7b70f4c4db84d07ef26839d..52a4d3664ce23388b658411fef00c7e4be3460d9 100644 (file)
@@ -1,27 +1,11 @@
-error[E0658]: the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable (see issue #29642)
-  --> $DIR/feature-gate-rustc-attrs.rs:15:1
-   |
-LL | #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
-
-error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable (see issue #29642)
-  --> $DIR/feature-gate-rustc-attrs.rs:16:1
-   |
-LL | #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
-   | ^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(rustc_attrs)] to the crate attributes to enable
-
 error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
-  --> $DIR/feature-gate-rustc-attrs.rs:17:1
+  --> $DIR/feature-gate-rustc-attrs.rs:15:1
    |
 LL | #[rustc_foo]
    | ^^^^^^^^^^^^
    |
    = help: add #![feature(rustc_attrs)] to the crate attributes to enable
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-unrestricted-attribute-tokens.rs b/src/test/ui/feature-gate-unrestricted-attribute-tokens.rs
new file mode 100644 (file)
index 0000000..daebbe6
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(custom_attribute)]
+
+#[my_attr(a b c d)]
+//~^ ERROR expected one of `(`, `)`, `,`, `::`, or `=`, found `b`
+//~| ERROR expected one of `(`, `)`, `,`, `::`, or `=`, found `c`
+//~| ERROR expected one of `(`, `)`, `,`, `::`, or `=`, found `d`
+fn main() {}
diff --git a/src/test/ui/feature-gate-unrestricted-attribute-tokens.stderr b/src/test/ui/feature-gate-unrestricted-attribute-tokens.stderr
new file mode 100644 (file)
index 0000000..cc5694b
--- /dev/null
@@ -0,0 +1,20 @@
+error: expected one of `(`, `)`, `,`, `::`, or `=`, found `b`
+  --> $DIR/feature-gate-unrestricted-attribute-tokens.rs:13:13
+   |
+LL | #[my_attr(a b c d)]
+   |             ^ expected one of `(`, `)`, `,`, `::`, or `=` here
+
+error: expected one of `(`, `)`, `,`, `::`, or `=`, found `c`
+  --> $DIR/feature-gate-unrestricted-attribute-tokens.rs:13:15
+   |
+LL | #[my_attr(a b c d)]
+   |               ^ expected one of `(`, `)`, `,`, `::`, or `=` here
+
+error: expected one of `(`, `)`, `,`, `::`, or `=`, found `d`
+  --> $DIR/feature-gate-unrestricted-attribute-tokens.rs:13:17
+   |
+LL | #[my_attr(a b c d)]
+   |                 ^ expected one of `(`, `)`, `,`, `::`, or `=` here
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/imports/local-modularized-tricky-fail-3.rs b/src/test/ui/imports/local-modularized-tricky-fail-3.rs
new file mode 100644 (file)
index 0000000..ab1f312
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Crate-local macro expanded `macro_export` macros cannot be accessed with module-relative paths.
+
+#![feature(use_extern_macros)]
+
+macro_rules! define_exported { () => {
+    #[macro_export]
+    macro_rules! exported {
+        () => ()
+    }
+}}
+
+define_exported!();
+
+mod m {
+    use exported;
+    //~^ ERROR macro-expanded `macro_export` macros from the current crate cannot
+}
+
+fn main() {
+    ::exported!();
+    //~^ ERROR macro-expanded `macro_export` macros from the current crate cannot
+}
diff --git a/src/test/ui/imports/local-modularized-tricky-fail-3.stderr b/src/test/ui/imports/local-modularized-tricky-fail-3.stderr
new file mode 100644 (file)
index 0000000..6da5284
--- /dev/null
@@ -0,0 +1,36 @@
+error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
+  --> $DIR/local-modularized-tricky-fail-3.rs:25:9
+   |
+LL |     use exported;
+   |         ^^^^^^^^
+   |
+note: the macro is defined here
+  --> $DIR/local-modularized-tricky-fail-3.rs:17:5
+   |
+LL | /     macro_rules! exported {
+LL | |         () => ()
+LL | |     }
+   | |_____^
+...
+LL |   define_exported!();
+   |   ------------------- in this macro invocation
+
+error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
+  --> $DIR/local-modularized-tricky-fail-3.rs:30:5
+   |
+LL |     ::exported!();
+   |     ^^^^^^^^^^
+   |
+note: the macro is defined here
+  --> $DIR/local-modularized-tricky-fail-3.rs:17:5
+   |
+LL | /     macro_rules! exported {
+LL | |         () => ()
+LL | |     }
+   | |_____^
+...
+LL |   define_exported!();
+   |   ------------------- in this macro invocation
+
+error: aborting due to 2 previous errors
+
index 50525e03acf50cebfe0db56e82262cbdf6ddc9c9..acac2d151fe9ad5ef8008d3caf10f1a5de111bf7 100644 (file)
@@ -10,5 +10,5 @@
 
 fn main() {
     concat!(test!());
-    //~^ ERROR expected a macro, found built-in attribute
+    //~^ ERROR cannot find macro `test!` in this scope
 }
index 0c130943fd873e789d5d828bc21f1eb228f3791a..51d6041e92220e356b6f873a9ec54c9c8e5ca952 100644 (file)
@@ -1,4 +1,4 @@
-error: expected a macro, found built-in attribute
+error: cannot find macro `test!` in this scope
   --> $DIR/issue-11692-2.rs:12:13
    |
 LL |     concat!(test!());
index bdbc7bd660fcdaf0f9cdbbfd8adfd0f91834733f..d325b0460015c7f18660ce555e42aa0136757b44 100644 (file)
@@ -10,9 +10,9 @@
 
 #![feature(use_extern_macros)]
 
-#[derive(inline)] //~ ERROR expected a macro, found built-in attribute
+#[derive(inline)] //~ ERROR cannot find derive macro `inline` in this scope
 struct S;
 
 fn main() {
-    inline!(); //~ ERROR expected a macro, found built-in attribute
+    inline!(); //~ ERROR cannot find macro `inline!` in this scope
 }
index 396bba2408f32231b07f5630100810ff18167b63..c9af4b66427516df4a674b863d0a2c7b5e68d057 100644 (file)
@@ -1,14 +1,14 @@
-error: expected a macro, found built-in attribute
+error: cannot find derive macro `inline` in this scope
   --> $DIR/macro-path-prelude-fail-3.rs:13:10
    |
-LL | #[derive(inline)] //~ ERROR expected a macro, found built-in attribute
+LL | #[derive(inline)] //~ ERROR cannot find derive macro `inline` in this scope
    |          ^^^^^^
 
-error: expected a macro, found built-in attribute
+error: cannot find macro `inline!` in this scope
   --> $DIR/macro-path-prelude-fail-3.rs:17:5
    |
-LL |     inline!(); //~ ERROR expected a macro, found built-in attribute
-   |     ^^^^^^
+LL |     inline!(); //~ ERROR cannot find macro `inline!` in this scope
+   |     ^^^^^^ help: you could try the macro: `line`
 
 error: aborting due to 2 previous errors
 
index 1aff7777ef7b1d306e8ffc632a3093af75851267..6831cd81d7daebffc0291d15a21f65ca8a21d74b 100644 (file)
@@ -21,7 +21,9 @@ macro_rules! add_macro_expanded_things_to_macro_prelude {() => {
 
 mod m1 {
     fn check() {
-        inline!(); //~ ERROR `inline` is ambiguous
+        inline!(); // OK. Theoretically ambiguous, but we do not consider built-in attributes
+                   // as candidates for non-attribute macro invocations to avoid regressions
+                   // on stable channel
     }
 }
 
index 0e1b9a985a3c378d8cfc86ab144bdb6eaa06d582..c0892f97376e32fd0ccbacdfb5824f824395957a 100644 (file)
@@ -1,42 +1,21 @@
-error[E0659]: `inline` is ambiguous
-  --> $DIR/macro-path-prelude-shadowing.rs:24:9
-   |
-LL |         inline!(); //~ ERROR `inline` is ambiguous
-   |         ^^^^^^
-   |
-note: `inline` could refer to the name imported here
-  --> $DIR/macro-path-prelude-shadowing.rs:16:5
-   |
-LL |     #[macro_use]
-   |     ^^^^^^^^^^^^
-...
-LL | add_macro_expanded_things_to_macro_prelude!();
-   | ---------------------------------------------- in this macro invocation
-note: `inline` could also refer to the name defined here
-  --> $DIR/macro-path-prelude-shadowing.rs:24:9
-   |
-LL |         inline!(); //~ ERROR `inline` is ambiguous
-   |         ^^^^^^
-   = note: macro-expanded macro imports do not shadow
-
 error[E0659]: `std` is ambiguous
-  --> $DIR/macro-path-prelude-shadowing.rs:37:9
+  --> $DIR/macro-path-prelude-shadowing.rs:39:9
    |
 LL |         std::panic!(); //~ ERROR `std` is ambiguous
    |         ^^^^^^^^^^
    |
 note: `std` could refer to the name imported here
-  --> $DIR/macro-path-prelude-shadowing.rs:35:9
+  --> $DIR/macro-path-prelude-shadowing.rs:37:9
    |
 LL |     use m2::*; // glob-import user-defined `std`
    |         ^^^^^
 note: `std` could also refer to the name defined here
-  --> $DIR/macro-path-prelude-shadowing.rs:37:9
+  --> $DIR/macro-path-prelude-shadowing.rs:39:9
    |
 LL |         std::panic!(); //~ ERROR `std` is ambiguous
    |         ^^^
    = note: consider adding an explicit import of `std` to disambiguate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0659`.