Skip to content

Commit 49de80d

Browse files
committed
Refactor away the prelude injection pass
1 parent 0f37edb commit 49de80d

File tree

5 files changed

+79
-145
lines changed

5 files changed

+79
-145
lines changed

src/librustc_driver/driver.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
601601
})?;
602602

603603
krate = time(time_passes, "crate injection", || {
604-
syntax::std_inject::maybe_inject_crates_ref(krate, sess.opts.alt_std_name.clone())
604+
let alt_std_name = sess.opts.alt_std_name.clone();
605+
syntax::std_inject::maybe_inject_crates_ref(&sess.parse_sess, krate, alt_std_name)
605606
});
606607

607608
let macros = time(time_passes,
@@ -720,10 +721,6 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
720721
sess.diagnostic())
721722
});
722723

723-
krate = time(time_passes,
724-
"prelude injection",
725-
|| syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate));
726-
727724
time(time_passes,
728725
"checking for inline asm in case the target doesn't support it",
729726
|| no_asm::check_crate(sess, &krate));

src/librustc_resolve/build_reduced_graph.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
2727
use rustc::ty::{self, VariantKind};
2828

2929
use syntax::ast::Name;
30-
use syntax::attr::AttrMetaMethods;
30+
use syntax::attr;
3131
use syntax::parse::token;
3232
use syntax::codemap::{Span, DUMMY_SP};
3333

@@ -57,6 +57,9 @@ impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) {
5757
impl<'b> Resolver<'b> {
5858
/// Constructs the reduced graph for the entire crate.
5959
pub fn build_reduced_graph(&mut self, krate: &Crate) {
60+
let no_implicit_prelude = attr::contains_name(&krate.attrs, "no_implicit_prelude");
61+
self.graph_root.no_implicit_prelude.set(no_implicit_prelude);
62+
6063
let mut visitor = BuildReducedGraphVisitor {
6164
parent: self.graph_root,
6265
resolver: self,
@@ -128,7 +131,7 @@ impl<'b> Resolver<'b> {
128131
};
129132

130133
// Build up the import directives.
131-
let is_prelude = item.attrs.iter().any(|attr| attr.name() == "prelude_import");
134+
let is_prelude = attr::contains_name(&item.attrs, "prelude_import");
132135

133136
match view_path.node {
134137
ViewPathSimple(binding, ref full_path) => {
@@ -221,6 +224,10 @@ impl<'b> Resolver<'b> {
221224
let parent_link = ModuleParentLink(parent, name);
222225
let def = Def::Mod(self.definitions.local_def_id(item.id));
223226
let module = self.new_module(parent_link, Some(def), false);
227+
module.no_implicit_prelude.set({
228+
parent.no_implicit_prelude.get() ||
229+
attr::contains_name(&item.attrs, "no_implicit_prelude")
230+
});
224231
self.define(parent, name, TypeNS, (module, sp, vis));
225232
self.module_map.insert(item.id, module);
226233
*parent_ref = module;

src/librustc_resolve/lib.rs

+20-12
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ pub struct ModuleS<'a> {
788788
resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
789789
unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
790790

791-
prelude: RefCell<Option<Module<'a>>>,
791+
no_implicit_prelude: Cell<bool>,
792792

793793
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
794794
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
@@ -817,7 +817,7 @@ impl<'a> ModuleS<'a> {
817817
extern_crate_id: None,
818818
resolutions: RefCell::new(HashMap::new()),
819819
unresolved_imports: RefCell::new(Vec::new()),
820-
prelude: RefCell::new(None),
820+
no_implicit_prelude: Cell::new(false),
821821
glob_importers: RefCell::new(Vec::new()),
822822
globs: RefCell::new((Vec::new())),
823823
traits: RefCell::new(None),
@@ -981,6 +981,8 @@ pub struct Resolver<'a> {
981981

982982
graph_root: Module<'a>,
983983

984+
prelude: Option<Module<'a>>,
985+
984986
trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
985987

986988
structs: FnvHashMap<DefId, Vec<Name>>,
@@ -1170,6 +1172,7 @@ impl<'a> Resolver<'a> {
11701172
// The outermost module has def ID 0; this is not reflected in the
11711173
// AST.
11721174
graph_root: graph_root,
1175+
prelude: None,
11731176

11741177
trait_item_map: FnvHashMap(),
11751178
structs: FnvHashMap(),
@@ -1453,10 +1456,13 @@ impl<'a> Resolver<'a> {
14531456

14541457
// We can only see through anonymous modules
14551458
if module.def.is_some() {
1456-
return module.prelude.borrow().and_then(|module| {
1457-
module.resolve_name(name, ns, false)
1458-
.success().map(LexicalScopeBinding::Item)
1459-
});
1459+
return match self.prelude {
1460+
Some(prelude) if !module.no_implicit_prelude.get() => {
1461+
prelude.resolve_name(name, ns, false).success()
1462+
.map(LexicalScopeBinding::Item)
1463+
}
1464+
_ => None,
1465+
};
14601466
}
14611467
}
14621468
}
@@ -3261,7 +3267,7 @@ impl<'a> Resolver<'a> {
32613267
let mut search_module = self.current_module;
32623268
loop {
32633269
// Look for trait children.
3264-
let mut search_in_module = |module: Module<'a>| {
3270+
let mut search_in_module = |this: &mut Self, module: Module<'a>| {
32653271
let mut traits = module.traits.borrow_mut();
32663272
if traits.is_none() {
32673273
let mut collected_traits = Vec::new();
@@ -3276,23 +3282,25 @@ impl<'a> Resolver<'a> {
32763282

32773283
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
32783284
let trait_def_id = binding.def().unwrap().def_id();
3279-
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3285+
if this.trait_item_map.contains_key(&(name, trait_def_id)) {
32803286
let mut import_id = None;
32813287
if let NameBindingKind::Import { directive, .. } = binding.kind {
32823288
let id = directive.id;
3283-
self.maybe_unused_trait_imports.insert(id);
3289+
this.maybe_unused_trait_imports.insert(id);
32843290
import_id = Some(id);
32853291
}
32863292
add_trait_info(&mut found_traits, trait_def_id, import_id, name);
3287-
self.record_use(trait_name, binding);
3293+
this.record_use(trait_name, binding);
32883294
}
32893295
}
32903296
};
3291-
search_in_module(search_module);
3297+
search_in_module(self, search_module);
32923298

32933299
match search_module.parent_link {
32943300
NoParentLink | ModuleParentLink(..) => {
3295-
search_module.prelude.borrow().map(search_in_module);
3301+
if !search_module.no_implicit_prelude.get() {
3302+
self.prelude.map(|prelude| search_in_module(self, prelude));
3303+
}
32963304
break;
32973305
}
32983306
BlockParentLink(parent_module, _) => {

src/librustc_resolve/resolve_imports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
624624
self.resolver.populate_module_if_necessary(target_module);
625625

626626
if let GlobImport { is_prelude: true } = directive.subclass {
627-
*module_.prelude.borrow_mut() = Some(target_module);
627+
self.resolver.prelude = Some(target_module);
628628
return Success(());
629629
}
630630

src/libsyntax/std_inject.rs

+47-125
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@ use ast;
1212
use attr;
1313
use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
1414
use codemap;
15-
use fold::Folder;
16-
use fold;
1715
use parse::token::{intern, InternedString, keywords};
1816
use parse::{token, ParseSess};
1917
use ptr::P;
20-
use util::small_vector::SmallVector;
2118

2219
/// Craft a span that will be ignored by the stability lint's
2320
/// call to codemap's is_internal check.
@@ -37,33 +34,6 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span {
3734
return sp;
3835
}
3936

40-
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
41-
-> ast::Crate {
42-
if no_core(&krate) {
43-
krate
44-
} else {
45-
let name = if no_std(&krate) {"core"} else {"std"};
46-
let mut fold = CrateInjector {
47-
item_name: token::str_to_ident(name),
48-
crate_name: token::intern(&alt_std_name.unwrap_or(name.to_string())),
49-
};
50-
fold.fold_crate(krate)
51-
}
52-
}
53-
54-
pub fn maybe_inject_prelude(sess: &ParseSess, krate: ast::Crate) -> ast::Crate {
55-
if no_core(&krate) {
56-
krate
57-
} else {
58-
let name = if no_std(&krate) {"core"} else {"std"};
59-
let mut fold = PreludeInjector {
60-
span: ignored_span(sess, DUMMY_SP),
61-
crate_identifier: token::str_to_ident(name),
62-
};
63-
fold.fold_crate(krate)
64-
}
65-
}
66-
6737
pub fn no_core(krate: &ast::Crate) -> bool {
6838
attr::contains_name(&krate.attrs, "no_core")
6939
}
@@ -72,102 +42,54 @@ pub fn no_std(krate: &ast::Crate) -> bool {
7242
attr::contains_name(&krate.attrs, "no_std") || no_core(krate)
7343
}
7444

75-
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
76-
attr::contains_name(attrs, "no_implicit_prelude")
77-
}
78-
79-
struct CrateInjector {
80-
item_name: ast::Ident,
81-
crate_name: ast::Name,
82-
}
83-
84-
impl fold::Folder for CrateInjector {
85-
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
86-
krate.module.items.insert(0, P(ast::Item {
87-
id: ast::DUMMY_NODE_ID,
88-
ident: self.item_name,
89-
attrs: vec!(
90-
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
91-
InternedString::new("macro_use")))),
92-
node: ast::ItemKind::ExternCrate(Some(self.crate_name)),
93-
vis: ast::Visibility::Inherited,
94-
span: DUMMY_SP
95-
}));
96-
97-
krate
98-
}
99-
}
100-
101-
struct PreludeInjector {
102-
span: Span,
103-
crate_identifier: ast::Ident,
104-
}
105-
106-
impl fold::Folder for PreludeInjector {
107-
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
108-
// only add `use std::prelude::*;` if there wasn't a
109-
// `#![no_implicit_prelude]` at the crate level.
110-
// fold_mod() will insert glob path.
111-
if !no_prelude(&krate.attrs) {
112-
krate.module = self.fold_mod(krate.module);
113-
}
114-
krate
115-
}
116-
117-
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
118-
if !no_prelude(&item.attrs) {
119-
// only recur if there wasn't `#![no_implicit_prelude]`
120-
// on this item, i.e. this means that the prelude is not
121-
// implicitly imported though the whole subtree
122-
fold::noop_fold_item(item, self)
123-
} else {
124-
SmallVector::one(item)
125-
}
45+
pub fn maybe_inject_crates_ref(sess: &ParseSess,
46+
mut krate: ast::Crate,
47+
alt_std_name: Option<String>)
48+
-> ast::Crate {
49+
if no_core(&krate) {
50+
return krate;
12651
}
12752

128-
fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
129-
let prelude_path = ast::Path {
130-
span: self.span,
53+
let name = if no_std(&krate) { "core" } else { "std" };
54+
let crate_name = token::intern(&alt_std_name.unwrap_or(name.to_string()));
55+
56+
krate.module.items.insert(0, P(ast::Item {
57+
attrs: vec![attr::mk_attr_outer(attr::mk_attr_id(),
58+
attr::mk_word_item(InternedString::new("macro_use")))],
59+
vis: ast::Visibility::Inherited,
60+
node: ast::ItemKind::ExternCrate(Some(crate_name)),
61+
ident: token::str_to_ident(name),
62+
id: ast::DUMMY_NODE_ID,
63+
span: DUMMY_SP,
64+
}));
65+
66+
let span = ignored_span(sess, DUMMY_SP);
67+
krate.module.items.insert(0, P(ast::Item {
68+
attrs: vec![ast::Attribute {
69+
node: ast::Attribute_ {
70+
style: ast::AttrStyle::Outer,
71+
value: P(ast::MetaItem {
72+
node: ast::MetaItemKind::Word(token::intern_and_get_ident("prelude_import")),
73+
span: span,
74+
}),
75+
id: attr::mk_attr_id(),
76+
is_sugared_doc: false,
77+
},
78+
span: span,
79+
}],
80+
vis: ast::Visibility::Inherited,
81+
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
13182
global: false,
132-
segments: vec![
133-
ast::PathSegment {
134-
identifier: self.crate_identifier,
135-
parameters: ast::PathParameters::none(),
136-
},
137-
ast::PathSegment {
138-
identifier: token::str_to_ident("prelude"),
139-
parameters: ast::PathParameters::none(),
140-
},
141-
ast::PathSegment {
142-
identifier: token::str_to_ident("v1"),
143-
parameters: ast::PathParameters::none(),
144-
},
145-
],
146-
};
147-
148-
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
149-
mod_.items.insert(0, P(ast::Item {
150-
id: ast::DUMMY_NODE_ID,
151-
ident: keywords::Invalid.ident(),
152-
node: ast::ItemKind::Use(vp),
153-
attrs: vec![ast::Attribute {
154-
span: self.span,
155-
node: ast::Attribute_ {
156-
id: attr::mk_attr_id(),
157-
style: ast::AttrStyle::Outer,
158-
value: P(ast::MetaItem {
159-
span: self.span,
160-
node: ast::MetaItemKind::Word(
161-
token::intern_and_get_ident("prelude_import")
162-
),
163-
}),
164-
is_sugared_doc: false,
165-
},
166-
}],
167-
vis: ast::Visibility::Inherited,
168-
span: self.span,
169-
}));
170-
171-
fold::noop_fold_mod(mod_, self)
172-
}
83+
segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
84+
identifier: token::str_to_ident(name),
85+
parameters: ast::PathParameters::none(),
86+
}).collect(),
87+
span: span,
88+
})))),
89+
id: ast::DUMMY_NODE_ID,
90+
ident: keywords::Invalid.ident(),
91+
span: span,
92+
}));
93+
94+
krate
17395
}

0 commit comments

Comments
 (0)