Skip to content

Commit d5281ef

Browse files
committed
Merge branch 'persistent_macro_scopes' into cleanup_expanded_macro_use_scopes
2 parents a7bfb1a + 6808b0a commit d5281ef

File tree

11 files changed

+282
-199
lines changed

11 files changed

+282
-199
lines changed

src/librustc/hir/lowering.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,7 @@ pub fn lower_crate(sess: &Session,
9595
let _ignore = sess.dep_graph.in_ignore();
9696

9797
LoweringContext {
98-
crate_root: if std_inject::no_core(krate) {
99-
None
100-
} else if std_inject::no_std(krate) {
101-
Some("core")
102-
} else {
103-
Some("std")
104-
},
98+
crate_root: std_inject::injected_crate_name(krate),
10599
sess: sess,
106100
parent_def: None,
107101
resolver: resolver,

src/librustc_driver/driver.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
649649
let resolver_arenas = Resolver::arenas();
650650
let mut resolver =
651651
Resolver::new(sess, &krate, make_glob_map, &mut crate_loader, &resolver_arenas);
652-
syntax_ext::register_builtins(&mut resolver, sess.features.borrow().quote);
652+
syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features.borrow().quote);
653653

654654
krate = time(time_passes, "expansion", || {
655655
// Windows dlls do not have rpaths, so they don't know how to find their
@@ -686,11 +686,17 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
686686
..syntax::ext::expand::ExpansionConfig::default(crate_name.to_string())
687687
};
688688
let mut ecx = ExtCtxt::new(&sess.parse_sess, krate.config.clone(), cfg, &mut resolver);
689-
let ret = syntax::ext::expand::expand_crate(&mut ecx, syntax_exts, krate);
689+
let err_count = ecx.parse_sess.span_diagnostic.err_count();
690+
691+
let krate = ecx.monotonic_expander().expand_crate(krate);
692+
693+
if ecx.parse_sess.span_diagnostic.err_count() - ecx.resolve_err_count > err_count {
694+
ecx.parse_sess.span_diagnostic.abort_if_errors();
695+
}
690696
if cfg!(windows) {
691697
env::set_var("PATH", &old_path);
692698
}
693-
ret
699+
krate
694700
});
695701

696702
krate.exported_macros = mem::replace(&mut resolver.exported_macros, Vec::new());

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! Here we build the "reduced graph": the graph of the module tree without
1414
//! any imports resolved.
1515
16-
use macros;
16+
use macros::{InvocationData, LegacyImports, LegacyScope};
1717
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
1818
use {Module, ModuleS, ModuleKind};
1919
use Namespace::{self, TypeNS, ValueNS};
@@ -84,7 +84,7 @@ impl<'b> Resolver<'b> {
8484
}
8585

8686
/// Constructs the reduced graph for one item.
87-
fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
87+
fn build_reduced_graph_for_item(&mut self, item: &Item, legacy_imports: &mut LegacyImports) {
8888
let parent = self.current_module;
8989
let name = item.ident.name;
9090
let sp = item.span;
@@ -200,16 +200,9 @@ impl<'b> Resolver<'b> {
200200
LoadedMacroKind::Def(mut def) => {
201201
let name = def.ident.name;
202202
if def.use_locally {
203-
let ext = macro_rules::compile(&self.session.parse_sess, &def);
204-
let shadowing =
205-
self.resolve_macro_name(Mark::root(), name, false).is_some();
206-
self.expansion_data[&Mark::root()].module.macros.borrow_mut()
207-
.insert(name, macros::NameBinding {
208-
ext: Rc::new(ext),
209-
expansion: expansion,
210-
shadowing: shadowing,
211-
span: loaded_macro.import_site,
212-
});
203+
let ext =
204+
Rc::new(macro_rules::compile(&self.session.parse_sess, &def));
205+
legacy_imports.insert(name, (ext, loaded_macro.import_site));
213206
self.macro_names.insert(name);
214207
}
215208
if def.export {
@@ -250,7 +243,6 @@ impl<'b> Resolver<'b> {
250243
attr::contains_name(&item.attrs, "no_implicit_prelude")
251244
},
252245
normal_ancestor_id: Some(item.id),
253-
macros_escape: self.contains_macro_use(&item.attrs),
254246
..ModuleS::new(Some(parent), ModuleKind::Def(def, name))
255247
});
256248
self.define(parent, name, TypeNS, (module, sp, vis));
@@ -520,45 +512,62 @@ impl<'b> Resolver<'b> {
520512

521513
pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
522514
pub resolver: &'a mut Resolver<'b>,
523-
pub expansion: Mark,
515+
pub legacy_scope: LegacyScope<'b>,
516+
pub legacy_imports: LegacyImports,
524517
}
525518

526519
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
527-
fn visit_invoc(&mut self, id: ast::NodeId) {
528-
self.resolver.expansion_data.get_mut(&Mark::from_placeholder_id(id)).unwrap().module =
529-
self.resolver.current_module;
520+
fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
521+
let invocation = self.resolver.invocations[&Mark::from_placeholder_id(id)];
522+
invocation.module.set(self.resolver.current_module);
523+
invocation.legacy_scope.set(self.legacy_scope);
524+
invocation
530525
}
531526
}
532527

533528
macro_rules! method {
534529
($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
535530
fn $visit(&mut self, node: &$ty) {
536-
match node.node {
537-
$invoc(..) => self.visit_invoc(node.id),
538-
_ => visit::$walk(self, node),
531+
if let $invoc(..) = node.node {
532+
self.visit_invoc(node.id);
533+
} else {
534+
visit::$walk(self, node);
539535
}
540536
}
541537
}
542538
}
543539

544540
impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
545541
method!(visit_impl_item: ast::ImplItem, ast::ImplItemKind::Macro, walk_impl_item);
546-
method!(visit_stmt: ast::Stmt, ast::StmtKind::Mac, walk_stmt);
547542
method!(visit_expr: ast::Expr, ast::ExprKind::Mac, walk_expr);
548543
method!(visit_pat: ast::Pat, ast::PatKind::Mac, walk_pat);
549544
method!(visit_ty: ast::Ty, ast::TyKind::Mac, walk_ty);
550545

551546
fn visit_item(&mut self, item: &Item) {
552-
match item.node {
547+
let macro_use = match item.node {
553548
ItemKind::Mac(..) if item.id == ast::DUMMY_NODE_ID => return, // Scope placeholder
554-
ItemKind::Mac(..) => return self.visit_invoc(item.id),
555-
_ => {}
556-
}
549+
ItemKind::Mac(..) => {
550+
return self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
551+
}
552+
ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs),
553+
_ => false,
554+
};
557555

558-
let parent = self.resolver.current_module;
559-
self.resolver.build_reduced_graph_for_item(item, self.expansion);
556+
let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope);
557+
self.resolver.build_reduced_graph_for_item(item, &mut self.legacy_imports);
560558
visit::walk_item(self, item);
561559
self.resolver.current_module = parent;
560+
if !macro_use {
561+
self.legacy_scope = legacy_scope;
562+
}
563+
}
564+
565+
fn visit_stmt(&mut self, stmt: &ast::Stmt) {
566+
if let ast::StmtKind::Mac(..) = stmt.node {
567+
self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(stmt.id));
568+
} else {
569+
visit::walk_stmt(self, stmt);
570+
}
562571
}
563572

564573
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
@@ -567,18 +576,20 @@ impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
567576
}
568577

569578
fn visit_block(&mut self, block: &Block) {
570-
let parent = self.resolver.current_module;
579+
let (parent, legacy_scope) = (self.resolver.current_module, self.legacy_scope);
571580
self.resolver.build_reduced_graph_for_block(block);
572581
visit::walk_block(self, block);
573582
self.resolver.current_module = parent;
583+
self.legacy_scope = legacy_scope;
574584
}
575585

576586
fn visit_trait_item(&mut self, item: &TraitItem) {
577587
let parent = self.resolver.current_module;
578588
let def_id = parent.def_id().unwrap();
579589

580590
if let TraitItemKind::Macro(_) = item.node {
581-
return self.visit_invoc(item.id);
591+
self.visit_invoc(item.id);
592+
return
582593
}
583594

584595
// Add the item to the trait info.

src/librustc_resolve/lib.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ use syntax::ext::base::MultiItemModifier;
5757
use syntax::ext::hygiene::Mark;
5858
use syntax::ast::{self, FloatTy};
5959
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, IntTy, UintTy};
60+
use syntax::ext::base::SyntaxExtension;
6061
use syntax::parse::token::{self, keywords};
6162
use syntax::util::lev_distance::find_best_match_for_name;
6263

@@ -77,6 +78,7 @@ use std::mem::replace;
7778
use std::rc::Rc;
7879

7980
use resolve_imports::{ImportDirective, NameResolution};
81+
use macros::{InvocationData, LegacyBinding, LegacyScope};
8082

8183
// NB: This module needs to be declared first so diagnostics are
8284
// registered before they are used.
@@ -791,9 +793,6 @@ pub struct ModuleS<'a> {
791793
// access the children must be preceded with a
792794
// `populate_module_if_necessary` call.
793795
populated: Cell<bool>,
794-
795-
macros: RefCell<FnvHashMap<Name, macros::NameBinding>>,
796-
macros_escape: bool,
797796
}
798797

799798
pub type Module<'a> = &'a ModuleS<'a>;
@@ -811,8 +810,6 @@ impl<'a> ModuleS<'a> {
811810
globs: RefCell::new((Vec::new())),
812811
traits: RefCell::new(None),
813812
populated: Cell::new(true),
814-
macros: RefCell::new(FnvHashMap()),
815-
macros_escape: false,
816813
}
817814
}
818815

@@ -1076,7 +1073,7 @@ pub struct Resolver<'a> {
10761073

10771074
privacy_errors: Vec<PrivacyError<'a>>,
10781075
ambiguity_errors: Vec<AmbiguityError<'a>>,
1079-
macro_shadowing_errors: FnvHashSet<Span>,
1076+
disallowed_shadowing: Vec<(Name, Span, LegacyScope<'a>)>,
10801077

10811078
arenas: &'a ResolverArenas<'a>,
10821079
dummy_binding: &'a NameBinding<'a>,
@@ -1086,9 +1083,10 @@ pub struct Resolver<'a> {
10861083
pub derive_modes: FnvHashMap<Name, Rc<MultiItemModifier>>,
10871084
crate_loader: &'a mut CrateLoader,
10881085
macro_names: FnvHashSet<Name>,
1086+
builtin_macros: FnvHashMap<Name, Rc<SyntaxExtension>>,
10891087

10901088
// Maps the `Mark` of an expansion to its containing module or block.
1091-
expansion_data: FnvHashMap<Mark, macros::ExpansionData<'a>>,
1089+
invocations: FnvHashMap<Mark, &'a InvocationData<'a>>,
10921090
}
10931091

10941092
pub struct ResolverArenas<'a> {
@@ -1097,6 +1095,8 @@ pub struct ResolverArenas<'a> {
10971095
name_bindings: arena::TypedArena<NameBinding<'a>>,
10981096
import_directives: arena::TypedArena<ImportDirective<'a>>,
10991097
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1098+
invocation_data: arena::TypedArena<InvocationData<'a>>,
1099+
legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
11001100
}
11011101

11021102
impl<'a> ResolverArenas<'a> {
@@ -1120,6 +1120,13 @@ impl<'a> ResolverArenas<'a> {
11201120
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
11211121
self.name_resolutions.alloc(Default::default())
11221122
}
1123+
fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>)
1124+
-> &'a InvocationData<'a> {
1125+
self.invocation_data.alloc(expansion_data)
1126+
}
1127+
fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
1128+
self.legacy_bindings.alloc(binding)
1129+
}
11231130
}
11241131

11251132
impl<'a> ty::NodeIdTree for Resolver<'a> {
@@ -1205,8 +1212,9 @@ impl<'a> Resolver<'a> {
12051212
let mut definitions = Definitions::new();
12061213
DefCollector::new(&mut definitions).collect_root();
12071214

1208-
let mut expansion_data = FnvHashMap();
1209-
expansion_data.insert(Mark::root(), macros::ExpansionData::root(graph_root));
1215+
let mut invocations = FnvHashMap();
1216+
invocations.insert(Mark::root(),
1217+
arenas.alloc_invocation_data(InvocationData::root(graph_root)));
12101218

12111219
Resolver {
12121220
session: session,
@@ -1252,7 +1260,7 @@ impl<'a> Resolver<'a> {
12521260

12531261
privacy_errors: Vec::new(),
12541262
ambiguity_errors: Vec::new(),
1255-
macro_shadowing_errors: FnvHashSet(),
1263+
disallowed_shadowing: Vec::new(),
12561264

12571265
arenas: arenas,
12581266
dummy_binding: arenas.alloc_name_binding(NameBinding {
@@ -1266,7 +1274,8 @@ impl<'a> Resolver<'a> {
12661274
derive_modes: FnvHashMap(),
12671275
crate_loader: crate_loader,
12681276
macro_names: FnvHashSet(),
1269-
expansion_data: expansion_data,
1277+
builtin_macros: FnvHashMap(),
1278+
invocations: invocations,
12701279
}
12711280
}
12721281

@@ -1277,6 +1286,8 @@ impl<'a> Resolver<'a> {
12771286
name_bindings: arena::TypedArena::new(),
12781287
import_directives: arena::TypedArena::new(),
12791288
name_resolutions: arena::TypedArena::new(),
1289+
invocation_data: arena::TypedArena::new(),
1290+
legacy_bindings: arena::TypedArena::new(),
12801291
}
12811292
}
12821293

@@ -3342,7 +3353,8 @@ impl<'a> Resolver<'a> {
33423353
vis.is_accessible_from(module.normal_ancestor_id.unwrap(), self)
33433354
}
33443355

3345-
fn report_errors(&self) {
3356+
fn report_errors(&mut self) {
3357+
self.report_shadowing_errors();
33463358
let mut reported_spans = FnvHashSet();
33473359

33483360
for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors {
@@ -3370,6 +3382,20 @@ impl<'a> Resolver<'a> {
33703382
}
33713383
}
33723384

3385+
fn report_shadowing_errors(&mut self) {
3386+
let mut reported_errors = FnvHashSet();
3387+
for (name, span, scope) in replace(&mut self.disallowed_shadowing, Vec::new()) {
3388+
if self.resolve_macro_name(scope, name, false).is_some() &&
3389+
reported_errors.insert((name, span)) {
3390+
let msg = format!("`{}` is already in scope", name);
3391+
self.session.struct_span_err(span, &msg)
3392+
.note("macro-expanded `macro_rules!`s and `#[macro_use]`s \
3393+
may not shadow existing macros (see RFC 1560)")
3394+
.emit();
3395+
}
3396+
}
3397+
}
3398+
33733399
fn report_conflict(&self,
33743400
parent: Module,
33753401
name: Name,

0 commit comments

Comments
 (0)