mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
Allow ast passes to create hygienic spans
This commit is contained in:
parent
0133941f47
commit
4082cd95a8
@ -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]
|
||||
|
@ -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(),
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user