Skip to content

Commit 24526cc

Browse files
committed
Auto merge of #34108 - jseyfried:refactor_prelude_injection, r=nrc
Refactor away the prelude injection fold Instead, just inject `#[prelude_import] use [core|std]::prelude::v1::*;` at the crate root while injecting `extern crate [core|std];` and process `#[no_implicit_prelude]` attributes in `resolve`. r? @nrc
2 parents dc77c5e + 970e15d commit 24526cc

File tree

6 files changed

+98
-173
lines changed

6 files changed

+98
-173
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 mut addl_plugins = Some(addl_plugins);
@@ -729,10 +730,6 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
729730
sess.diagnostic())
730731
});
731732

732-
krate = time(time_passes,
733-
"prelude injection",
734-
|| syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate));
735-
736733
time(time_passes,
737734
"checking for inline asm in case the target doesn't support it",
738735
|| 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

+35-30
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ enum ResolutionError<'a> {
126126
/// error E0413: cannot be named the same as an enum variant or unit-like struct in scope
127127
DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
128128
/// error E0414: only irrefutable patterns allowed here
129-
ConstantForIrrefutableBinding(Name),
129+
ConstantForIrrefutableBinding(Name, &'a NameBinding<'a>),
130130
/// error E0415: identifier is bound more than once in this parameter list
131131
IdentifierBoundMoreThanOnceInParameterList(&'a str),
132132
/// error E0416: identifier is bound more than once in the same pattern
@@ -317,19 +317,15 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
317317
&format!("has same name as enum variant or unit-like struct"));
318318
err
319319
}
320-
ResolutionError::ConstantForIrrefutableBinding(name) => {
320+
ResolutionError::ConstantForIrrefutableBinding(name, binding) => {
321321
let mut err = struct_span_err!(resolver.session,
322322
span,
323323
E0414,
324324
"let variables cannot be named the same as const variables");
325325
err.span_label(span,
326326
&format!("cannot be named the same as a const variable"));
327-
if let Some(binding) = resolver.current_module
328-
.resolve_name_in_lexical_scope(name, ValueNS) {
329-
let participle = if binding.is_import() { "imported" } else { "defined" };
330-
err.span_label(binding.span, &format!("a constant `{}` is {} here",
331-
name, participle));
332-
}
327+
let participle = if binding.is_import() { "imported" } else { "defined" };
328+
err.span_label(binding.span, &format!("a constant `{}` is {} here", name, participle));
333329
err
334330
}
335331
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
@@ -714,9 +710,9 @@ enum AssocItemResolveResult {
714710
}
715711

716712
#[derive(Copy, Clone)]
717-
enum BareIdentifierPatternResolution {
713+
enum BareIdentifierPatternResolution<'a> {
718714
FoundStructOrEnumVariant(Def),
719-
FoundConst(Def, Name),
715+
FoundConst(&'a NameBinding<'a>, Name),
720716
BareIdentifierPatternUnresolved,
721717
}
722718

@@ -792,7 +788,7 @@ pub struct ModuleS<'a> {
792788
resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
793789
unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
794790

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

797793
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
798794
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
@@ -821,7 +817,7 @@ impl<'a> ModuleS<'a> {
821817
extern_crate_id: None,
822818
resolutions: RefCell::new(HashMap::new()),
823819
unresolved_imports: RefCell::new(Vec::new()),
824-
prelude: RefCell::new(None),
820+
no_implicit_prelude: Cell::new(false),
825821
glob_importers: RefCell::new(Vec::new()),
826822
globs: RefCell::new((Vec::new())),
827823
traits: RefCell::new(None),
@@ -985,6 +981,8 @@ pub struct Resolver<'a> {
985981

986982
graph_root: Module<'a>,
987983

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

990988
structs: FnvHashMap<DefId, Vec<Name>>,
@@ -1174,6 +1172,7 @@ impl<'a> Resolver<'a> {
11741172
// The outermost module has def ID 0; this is not reflected in the
11751173
// AST.
11761174
graph_root: graph_root,
1175+
prelude: None,
11771176

11781177
trait_item_map: FnvHashMap(),
11791178
structs: FnvHashMap(),
@@ -1456,7 +1455,15 @@ impl<'a> Resolver<'a> {
14561455
}
14571456

14581457
// We can only see through anonymous modules
1459-
if module.def.is_some() { return None; }
1458+
if module.def.is_some() {
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+
};
1466+
}
14601467
}
14611468
}
14621469

@@ -1543,11 +1550,7 @@ impl<'a> Resolver<'a> {
15431550
debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
15441551

15451552
self.populate_module_if_necessary(module);
1546-
match use_lexical_scope {
1547-
true => module.resolve_name_in_lexical_scope(name, namespace)
1548-
.map(Success).unwrap_or(Failed(None)),
1549-
false => module.resolve_name(name, namespace, false),
1550-
}.and_then(|binding| {
1553+
module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
15511554
if record_used {
15521555
if let NameBindingKind::Import { directive, .. } = binding.kind {
15531556
self.used_imports.insert((directive.id, namespace));
@@ -2289,21 +2292,21 @@ impl<'a> Resolver<'a> {
22892292
);
22902293
self.record_def(pattern.id, err_path_resolution());
22912294
}
2292-
FoundConst(def, _) if const_ok => {
2295+
FoundConst(binding, _) if const_ok => {
22932296
debug!("(resolving pattern) resolving `{}` to constant", renamed);
22942297

22952298
self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
22962299
self.record_def(pattern.id,
22972300
PathResolution {
2298-
base_def: def,
2301+
base_def: binding.def().unwrap(),
22992302
depth: 0,
23002303
});
23012304
}
2302-
FoundConst(_, name) => {
2305+
FoundConst(binding, name) => {
23032306
resolve_error(
23042307
self,
23052308
pattern.span,
2306-
ResolutionError::ConstantForIrrefutableBinding(name)
2309+
ResolutionError::ConstantForIrrefutableBinding(name, binding)
23072310
);
23082311
self.record_def(pattern.id, err_path_resolution());
23092312
}
@@ -2526,7 +2529,7 @@ impl<'a> Resolver<'a> {
25262529
}
25272530

25282531
fn resolve_bare_identifier_pattern(&mut self, ident: ast::Ident, span: Span)
2529-
-> BareIdentifierPatternResolution {
2532+
-> BareIdentifierPatternResolution<'a> {
25302533
let binding = match self.resolve_ident_in_lexical_scope(ident, ValueNS, true) {
25312534
Some(LexicalScopeBinding::Item(binding)) => binding,
25322535
_ => return BareIdentifierPatternUnresolved,
@@ -2535,7 +2538,7 @@ impl<'a> Resolver<'a> {
25352538

25362539
match def {
25372540
Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def),
2538-
Def::Const(..) | Def::AssociatedConst(..) => FoundConst(def, ident.name),
2541+
Def::Const(..) | Def::AssociatedConst(..) => FoundConst(binding, ident.name),
25392542
Def::Static(..) => {
25402543
let error = ResolutionError::StaticVariableReference(binding);
25412544
resolve_error(self, span, error);
@@ -3264,7 +3267,7 @@ impl<'a> Resolver<'a> {
32643267
let mut search_module = self.current_module;
32653268
loop {
32663269
// Look for trait children.
3267-
let mut search_in_module = |module: Module<'a>| {
3270+
let mut search_in_module = |this: &mut Self, module: Module<'a>| {
32683271
let mut traits = module.traits.borrow_mut();
32693272
if traits.is_none() {
32703273
let mut collected_traits = Vec::new();
@@ -3279,23 +3282,25 @@ impl<'a> Resolver<'a> {
32793282

32803283
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
32813284
let trait_def_id = binding.def().unwrap().def_id();
3282-
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3285+
if this.trait_item_map.contains_key(&(name, trait_def_id)) {
32833286
let mut import_id = None;
32843287
if let NameBindingKind::Import { directive, .. } = binding.kind {
32853288
let id = directive.id;
3286-
self.maybe_unused_trait_imports.insert(id);
3289+
this.maybe_unused_trait_imports.insert(id);
32873290
import_id = Some(id);
32883291
}
32893292
add_trait_info(&mut found_traits, trait_def_id, import_id, name);
3290-
self.record_use(trait_name, binding);
3293+
this.record_use(trait_name, binding);
32913294
}
32923295
}
32933296
};
3294-
search_in_module(search_module);
3297+
search_in_module(self, search_module);
32953298

32963299
match search_module.parent_link {
32973300
NoParentLink | ModuleParentLink(..) => {
3298-
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+
}
32993304
break;
33003305
}
33013306
BlockParentLink(parent_module, _) => {

src/librustc_resolve/resolve_imports.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,6 @@ impl<'a> ::ModuleS<'a> {
257257
Failed(None)
258258
}
259259

260-
// Invariant: this may not be called until import resolution is complete.
261-
pub fn resolve_name_in_lexical_scope(&self, name: Name, ns: Namespace)
262-
-> Option<&'a NameBinding<'a>> {
263-
self.resolution(name, ns).borrow().binding
264-
.or_else(|| self.prelude.borrow().and_then(|prelude| {
265-
prelude.resolve_name(name, ns, false).success()
266-
}))
267-
}
268-
269260
// Define the name or return the existing binding if there is a collision.
270261
pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
271262
-> Result<(), &'a NameBinding<'a>> {
@@ -633,7 +624,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
633624
self.resolver.populate_module_if_necessary(target_module);
634625

635626
if let GlobImport { is_prelude: true } = directive.subclass {
636-
*module_.prelude.borrow_mut() = Some(target_module);
627+
self.resolver.prelude = Some(target_module);
637628
return Success(());
638629
}
639630

src/librustdoc/html/render.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,10 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
18201820
}
18211821
}
18221822

1823-
write!(w, "</table>")
1823+
if curty.is_some() {
1824+
write!(w, "</table>")?;
1825+
}
1826+
Ok(())
18241827
}
18251828

18261829
fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {

0 commit comments

Comments
 (0)