Fix #[test] shadowing in macro_prelude

This commit is contained in:
John Renner 2018-08-30 13:39:32 -07:00
parent 9b27de41d4
commit 08ea5b7c78
7 changed files with 70 additions and 6 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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),

View File

@ -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"),

View File

@ -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 {
() => {};
}

View File

@ -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(){}