about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJohn Renner <john@jrenner.net>2018-08-30 13:39:32 -0700
committerJohn Renner <john@jrenner.net>2018-09-04 22:33:10 -0700
commit08ea5b7c78a864da0b1a348c3c3425e8611cef76 (patch)
treeafcb455d2ddfb8931930f1adfad8101774893e42 /src
parent9b27de41d4e00cb6c23df270572472fd4c6f47f8 (diff)
downloadrust-08ea5b7c78a864da0b1a348c3c3425e8611cef76.tar.gz
rust-08ea5b7c78a864da0b1a348c3c3425e8611cef76.zip
Fix #[test] shadowing in macro_prelude
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_resolve/macros.rs23
-rw-r--r--src/libsyntax/ext/base.rs3
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax_ext/lib.rs14
-rw-r--r--src/test/ui/test-shadowing/auxiliary/test_macro.rs14
-rw-r--r--src/test/ui/test-shadowing/test-cant-be-shadowed.rs18
7 files changed, 70 insertions, 6 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 0f6a9742309..65fe01ff96a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1412,6 +1412,7 @@ pub struct Resolver<'a, 'b: 'a> {
     crate_loader: &'a mut CrateLoader<'b>,
     macro_names: FxHashSet<Ident>,
     macro_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
+    unshadowable_attrs: FxHashMap<Name, &'a NameBinding<'a>>,
     pub all_macros: FxHashMap<Name, Def>,
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
     macro_defs: FxHashMap<Mark, DefId>,
@@ -1729,6 +1730,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             crate_loader,
             macro_names: FxHashSet(),
             macro_prelude: FxHashMap(),
+            unshadowable_attrs: FxHashMap(),
             all_macros: FxHashMap(),
             macro_map: FxHashMap(),
             invocations,
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 0d3e615b446..4cc8d348667 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -207,6 +207,23 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
         self.macro_prelude.insert(ident.name, binding);
     }
 
+    fn add_unshadowable_attr(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
+        let def_id = DefId {
+            krate: BUILTIN_MACROS_CRATE,
+            index: DefIndex::from_array_index(self.macro_map.len(),
+                                              DefIndexAddressSpace::Low),
+        };
+        let kind = ext.kind();
+        self.macro_map.insert(def_id, ext);
+        let binding = self.arenas.alloc_name_binding(NameBinding {
+            kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
+            span: DUMMY_SP,
+            vis: ty::Visibility::Invisible,
+            expansion: Mark::root(),
+        });
+        self.unshadowable_attrs.insert(ident.name, binding);
+    }
+
     fn resolve_imports(&mut self) {
         ImportResolver { resolver: self }.resolve_imports()
     }
@@ -462,8 +479,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
             return def;
         }
 
-        if kind == MacroKind::Attr && *&path[0].as_str() == "test" {
-            return Ok(self.macro_prelude.get(&path[0].name).unwrap().def())
+        if kind == MacroKind::Attr && path.len() == 1 {
+            if let Some(ext) = self.unshadowable_attrs.get(&path[0].name) {
+                return Ok(ext.def());
+            }
         }
 
         let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false);
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index e8a68b6d767..0e059bc4a6c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -721,6 +721,7 @@ pub trait Resolver {
     fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
                                             derives: &[Mark]);
     fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
+    fn add_unshadowable_attr(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
 
     fn resolve_imports(&mut self);
     // Resolves attribute and derive legacy macros from `#![plugin(..)]`.
@@ -729,6 +730,7 @@ pub trait Resolver {
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, scope: Mark, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Determinacy>;
+
     fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, scope: Mark,
                           derives_in_scope: &[ast::Path], force: bool)
                           -> Result<Lrc<SyntaxExtension>, Determinacy>;
@@ -759,6 +761,7 @@ impl Resolver for DummyResolver {
     fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
                                             _derives: &[Mark]) {}
     fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
+    fn add_unshadowable_attr(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
 
     fn resolve_imports(&mut self) {}
     fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>, _allow_derive: bool)
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 35cb5aa5475..c94c7874a05 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -769,8 +769,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
     ("cfg_attr", Normal, Ungated),
     ("main", Normal, Ungated),
     ("start", Normal, Ungated),
-    ("test", Normal, Ungated),
-    ("bench", Normal, Ungated),
     ("repr", Normal, Ungated),
     ("path", Normal, Ungated),
     ("abi", Normal, Ungated),
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index bbbf338c4f3..a9990cdeabf 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -71,6 +71,18 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
                          enable_quotes: bool) {
     deriving::register_builtin_derives(resolver);
 
+    {
+        let mut register_unshadowable = |name, ext| {
+            resolver.add_unshadowable_attr(ast::Ident::with_empty_ctxt(name), Lrc::new(ext));
+        };
+
+        register_unshadowable(Symbol::intern("test"),
+            MultiModifier(Box::new(test::expand_test)));
+
+        register_unshadowable(Symbol::intern("bench"),
+            MultiModifier(Box::new(test::expand_bench)));
+    }
+
     let mut register = |name, ext| {
         resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Lrc::new(ext));
     };
@@ -133,8 +145,6 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
         assert: assert::expand_assert,
     }
 
-    register(Symbol::intern("test"), MultiModifier(Box::new(test::expand_test)));
-    register(Symbol::intern("bench"), MultiModifier(Box::new(test::expand_bench)));
 
     // format_args uses `unstable` things internally.
     register(Symbol::intern("format_args"),
diff --git a/src/test/ui/test-shadowing/auxiliary/test_macro.rs b/src/test/ui/test-shadowing/auxiliary/test_macro.rs
new file mode 100644
index 00000000000..ba7ed73b822
--- /dev/null
+++ b/src/test/ui/test-shadowing/auxiliary/test_macro.rs
@@ -0,0 +1,14 @@
+// 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.
+
+#[macro_export]
+macro_rules! test {
+    () => {};
+}
\ No newline at end of file
diff --git a/src/test/ui/test-shadowing/test-cant-be-shadowed.rs b/src/test/ui/test-shadowing/test-cant-be-shadowed.rs
new file mode 100644
index 00000000000..4ae8b7ffe8b
--- /dev/null
+++ b/src/test/ui/test-shadowing/test-cant-be-shadowed.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// compile-pass
+// aux-build:test_macro.rs
+// compile-flags:--test
+
+#[macro_use] extern crate test_macro;
+
+#[test]
+fn foo(){}
\ No newline at end of file