diff options
| -rw-r--r-- | src/librustc_resolve/build_reduced_graph.rs | 3 | ||||
| -rw-r--r-- | src/librustc_resolve/lib.rs | 22 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 39 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax_pos/hygiene.rs | 2 |
5 files changed, 72 insertions, 4 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 9a794ade729..5a3b768301c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -126,7 +126,8 @@ impl<'a> Resolver<'a> { crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> { let def_id = match self.macro_defs.get(&expn_id) { Some(def_id) => *def_id, - None => return self.graph_root, + None => return self.ast_transform_scopes.get(&expn_id) + .unwrap_or(&self.graph_root), }; if let Some(id) = self.definitions.as_local_node_id(def_id) { self.local_macro_def_scopes[&id] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 875ae449d94..b12bf4521e0 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -879,6 +879,10 @@ pub struct Resolver<'a> { /// There will be an anonymous module created around `g` with the ID of the /// entry block for `f`. block_map: NodeMap<Module<'a>>, + /// A fake module that contains no definition and no prelude. Used so that + /// some AST passes can generate identifiers that only resolve to local or + /// language items. + empty_module: Module<'a>, module_map: FxHashMap<DefId, Module<'a>>, extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>, binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>, @@ -913,6 +917,7 @@ pub struct Resolver<'a> { non_macro_attrs: [Lrc<SyntaxExtension>; 2], macro_defs: FxHashMap<ExpnId, DefId>, local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>, + ast_transform_scopes: FxHashMap<ExpnId, Module<'a>>, unused_macros: NodeMap<Span>, proc_macro_stubs: NodeSet, /// Traces collected during macro resolution and validated when it's complete. @@ -1080,6 +1085,21 @@ impl<'a> Resolver<'a> { no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude), ..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span) }); + let empty_module_kind = ModuleKind::Def( + DefKind::Mod, + root_def_id, + kw::Invalid, + ); + let empty_module = arenas.alloc_module(ModuleData { + no_implicit_prelude: true, + ..ModuleData::new( + Some(graph_root), + empty_module_kind, + root_def_id, + ExpnId::root(), + DUMMY_SP, + ) + }); let mut module_map = FxHashMap::default(); module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root); @@ -1139,10 +1159,12 @@ impl<'a> Resolver<'a> { label_res_map: Default::default(), export_map: FxHashMap::default(), trait_map: Default::default(), + empty_module, module_map, block_map: Default::default(), extern_module_map: FxHashMap::default(), binding_parent_modules: FxHashMap::default(), + ast_transform_scopes: FxHashMap::default(), glob_map: Default::default(), diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 719167eb057..fe7eae91945 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -8,6 +8,7 @@ use crate::{ModuleOrUniformRoot, KNOWN_TOOLS}; use crate::Namespace::*; use crate::resolve_imports::ImportResolver; use rustc::hir::def::{self, DefKind, NonMacroAttrKind}; +use rustc::hir::def_id; use rustc::middle::stability; use rustc::{ty, lint, span_bug}; use syntax::ast::{self, NodeId, Ident}; @@ -16,7 +17,7 @@ use syntax::edition::Edition; use syntax::ext::base::{self, Indeterminate, SpecialDerives}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; -use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind}; +use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind, Transparency}; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name}; use syntax::feature_gate::GateIssue; @@ -25,6 +26,7 @@ use syntax_pos::{Span, DUMMY_SP}; use std::{mem, ptr}; use rustc_data_structures::sync::Lrc; +use syntax_pos::hygiene::AstPass; type Res = def::Res<NodeId>; @@ -136,6 +138,41 @@ impl<'a> base::Resolver for Resolver<'a> { } } + // Create a Span with modern hygiene with a definition site of the provided + // module, or a fake empty `#[no_implicit_prelude]` module if no module is + // provided. + fn span_for_ast_pass( + &mut self, + base_span: Span, + pass: AstPass, + features: &[Symbol], + parent_module_id: Option<NodeId>, + ) -> Span { + let span = base_span.fresh_expansion_with_transparency( + ExpnData::allow_unstable( + ExpnKind::AstPass(pass), + base_span, + self.session.edition(), + features.into(), + ), + Transparency::Opaque, + ); + let expn_id = span.ctxt().outer_expn(); + let parent_scope = if let Some(module_id) = parent_module_id { + let parent_def_id = self.definitions.local_def_id(module_id); + self.definitions.add_parent_module_of_macro_def(expn_id, parent_def_id); + self.module_map[&parent_def_id] + } else { + self.definitions.add_parent_module_of_macro_def( + expn_id, + def_id::DefId::local(def_id::CRATE_DEF_INDEX), + ); + self.empty_module + }; + self.ast_transform_scopes.insert(expn_id, parent_scope); + span + } + fn resolve_imports(&mut self) { ImportResolver { r: self }.resolve_imports() } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a63c4181d5e..3d274af9908 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree}; use errors::{DiagnosticBuilder, DiagnosticId}; use smallvec::{smallvec, SmallVec}; use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnData, ExpnKind}; +use syntax_pos::hygiene::{AstPass, ExpnData, ExpnKind}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{self, Lrc}; @@ -660,6 +660,14 @@ pub trait Resolver { extra_placeholders: &[NodeId]); fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension); + fn span_for_ast_pass( + &mut self, + span: Span, + pass: AstPass, + features: &[Symbol], + parent_module_id: Option<NodeId>, + ) -> Span; + fn resolve_imports(&mut self); fn resolve_macro_invocation( diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 237a02f2f66..99afe57ef54 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -550,7 +550,7 @@ impl Span { /// The returned span belongs to the created expansion and has the new properties, /// but its location is inherited from the current span. pub fn fresh_expansion(self, expn_data: ExpnData) -> Span { - self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent) + self.fresh_expansion_with_transparency(expn_data, Transparency::Transparent) } pub fn fresh_expansion_with_transparency( |
