Skip to content

Commit 4082cd9

Browse files
committed
Allow ast passes to create hygienic spans
1 parent 0133941 commit 4082cd9

File tree

5 files changed

+72
-4
lines changed

5 files changed

+72
-4
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ impl<'a> Resolver<'a> {
126126
crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
127127
let def_id = match self.macro_defs.get(&expn_id) {
128128
Some(def_id) => *def_id,
129-
None => return self.graph_root,
129+
None => return self.ast_transform_scopes.get(&expn_id)
130+
.unwrap_or(&self.graph_root),
130131
};
131132
if let Some(id) = self.definitions.as_local_node_id(def_id) {
132133
self.local_macro_def_scopes[&id]

src/librustc_resolve/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,10 @@ pub struct Resolver<'a> {
879879
/// There will be an anonymous module created around `g` with the ID of the
880880
/// entry block for `f`.
881881
block_map: NodeMap<Module<'a>>,
882+
/// A fake module that contains no definition and no prelude. Used so that
883+
/// some AST passes can generate identifiers that only resolve to local or
884+
/// language items.
885+
empty_module: Module<'a>,
882886
module_map: FxHashMap<DefId, Module<'a>>,
883887
extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
884888
binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>,
@@ -913,6 +917,7 @@ pub struct Resolver<'a> {
913917
non_macro_attrs: [Lrc<SyntaxExtension>; 2],
914918
macro_defs: FxHashMap<ExpnId, DefId>,
915919
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
920+
ast_transform_scopes: FxHashMap<ExpnId, Module<'a>>,
916921
unused_macros: NodeMap<Span>,
917922
proc_macro_stubs: NodeSet,
918923
/// Traces collected during macro resolution and validated when it's complete.
@@ -1080,6 +1085,21 @@ impl<'a> Resolver<'a> {
10801085
no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
10811086
..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
10821087
});
1088+
let empty_module_kind = ModuleKind::Def(
1089+
DefKind::Mod,
1090+
root_def_id,
1091+
kw::Invalid,
1092+
);
1093+
let empty_module = arenas.alloc_module(ModuleData {
1094+
no_implicit_prelude: true,
1095+
..ModuleData::new(
1096+
Some(graph_root),
1097+
empty_module_kind,
1098+
root_def_id,
1099+
ExpnId::root(),
1100+
DUMMY_SP,
1101+
)
1102+
});
10831103
let mut module_map = FxHashMap::default();
10841104
module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
10851105

@@ -1139,10 +1159,12 @@ impl<'a> Resolver<'a> {
11391159
label_res_map: Default::default(),
11401160
export_map: FxHashMap::default(),
11411161
trait_map: Default::default(),
1162+
empty_module,
11421163
module_map,
11431164
block_map: Default::default(),
11441165
extern_module_map: FxHashMap::default(),
11451166
binding_parent_modules: FxHashMap::default(),
1167+
ast_transform_scopes: FxHashMap::default(),
11461168

11471169
glob_map: Default::default(),
11481170

src/librustc_resolve/macros.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
88
use crate::Namespace::*;
99
use crate::resolve_imports::ImportResolver;
1010
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
11+
use rustc::hir::def_id;
1112
use rustc::middle::stability;
1213
use rustc::{ty, lint, span_bug};
1314
use syntax::ast::{self, NodeId, Ident};
@@ -16,7 +17,7 @@ use syntax::edition::Edition;
1617
use syntax::ext::base::{self, Indeterminate, SpecialDerives};
1718
use syntax::ext::base::{MacroKind, SyntaxExtension};
1819
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
19-
use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
20+
use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind, Transparency};
2021
use syntax::ext::tt::macro_rules;
2122
use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
2223
use syntax::feature_gate::GateIssue;
@@ -25,6 +26,7 @@ use syntax_pos::{Span, DUMMY_SP};
2526

2627
use std::{mem, ptr};
2728
use rustc_data_structures::sync::Lrc;
29+
use syntax_pos::hygiene::AstPass;
2830

2931
type Res = def::Res<NodeId>;
3032

@@ -136,6 +138,41 @@ impl<'a> base::Resolver for Resolver<'a> {
136138
}
137139
}
138140

141+
// Create a Span with modern hygiene with a definition site of the provided
142+
// module, or a fake empty `#[no_implicit_prelude]` module if no module is
143+
// provided.
144+
fn span_for_ast_pass(
145+
&mut self,
146+
base_span: Span,
147+
pass: AstPass,
148+
features: &[Symbol],
149+
parent_module_id: Option<NodeId>,
150+
) -> Span {
151+
let span = base_span.fresh_expansion_with_transparency(
152+
ExpnData::allow_unstable(
153+
ExpnKind::AstPass(pass),
154+
base_span,
155+
self.session.edition(),
156+
features.into(),
157+
),
158+
Transparency::Opaque,
159+
);
160+
let expn_id = span.ctxt().outer_expn();
161+
let parent_scope = if let Some(module_id) = parent_module_id {
162+
let parent_def_id = self.definitions.local_def_id(module_id);
163+
self.definitions.add_parent_module_of_macro_def(expn_id, parent_def_id);
164+
self.module_map[&parent_def_id]
165+
} else {
166+
self.definitions.add_parent_module_of_macro_def(
167+
expn_id,
168+
def_id::DefId::local(def_id::CRATE_DEF_INDEX),
169+
);
170+
self.empty_module
171+
};
172+
self.ast_transform_scopes.insert(expn_id, parent_scope);
173+
span
174+
}
175+
139176
fn resolve_imports(&mut self) {
140177
ImportResolver { r: self }.resolve_imports()
141178
}

src/libsyntax/ext/base.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
1515
use errors::{DiagnosticBuilder, DiagnosticId};
1616
use smallvec::{smallvec, SmallVec};
1717
use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP};
18-
use syntax_pos::hygiene::{ExpnData, ExpnKind};
18+
use syntax_pos::hygiene::{AstPass, ExpnData, ExpnKind};
1919

2020
use rustc_data_structures::fx::FxHashMap;
2121
use rustc_data_structures::sync::{self, Lrc};
@@ -660,6 +660,14 @@ pub trait Resolver {
660660
extra_placeholders: &[NodeId]);
661661
fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
662662

663+
fn span_for_ast_pass(
664+
&mut self,
665+
span: Span,
666+
pass: AstPass,
667+
features: &[Symbol],
668+
parent_module_id: Option<NodeId>,
669+
) -> Span;
670+
663671
fn resolve_imports(&mut self);
664672

665673
fn resolve_macro_invocation(

src/libsyntax_pos/hygiene.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ impl Span {
550550
/// The returned span belongs to the created expansion and has the new properties,
551551
/// but its location is inherited from the current span.
552552
pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
553-
self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
553+
self.fresh_expansion_with_transparency(expn_data, Transparency::Transparent)
554554
}
555555

556556
pub fn fresh_expansion_with_transparency(

0 commit comments

Comments
 (0)