Skip to content

Commit

Permalink
Auto merge of #34108 - jseyfried:refactor_prelude_injection, r=nrc
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jun 9, 2016
2 parents dc77c5e + 970e15d commit 24526cc
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 173 deletions.
7 changes: 2 additions & 5 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,8 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
})?;

krate = time(time_passes, "crate injection", || {
syntax::std_inject::maybe_inject_crates_ref(krate, sess.opts.alt_std_name.clone())
let alt_std_name = sess.opts.alt_std_name.clone();
syntax::std_inject::maybe_inject_crates_ref(&sess.parse_sess, krate, alt_std_name)
});

let mut addl_plugins = Some(addl_plugins);
Expand Down Expand Up @@ -729,10 +730,6 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
sess.diagnostic())
});

krate = time(time_passes,
"prelude injection",
|| syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate));

time(time_passes,
"checking for inline asm in case the target doesn't support it",
|| no_asm::check_crate(sess, &krate));
Expand Down
11 changes: 9 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::ty::{self, VariantKind};

use syntax::ast::Name;
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::parse::token;
use syntax::codemap::{Span, DUMMY_SP};

Expand Down Expand Up @@ -57,6 +57,9 @@ impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) {
impl<'b> Resolver<'b> {
/// Constructs the reduced graph for the entire crate.
pub fn build_reduced_graph(&mut self, krate: &Crate) {
let no_implicit_prelude = attr::contains_name(&krate.attrs, "no_implicit_prelude");
self.graph_root.no_implicit_prelude.set(no_implicit_prelude);

let mut visitor = BuildReducedGraphVisitor {
parent: self.graph_root,
resolver: self,
Expand Down Expand Up @@ -128,7 +131,7 @@ impl<'b> Resolver<'b> {
};

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

match view_path.node {
ViewPathSimple(binding, ref full_path) => {
Expand Down Expand Up @@ -221,6 +224,10 @@ impl<'b> Resolver<'b> {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(self.definitions.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), false);
module.no_implicit_prelude.set({
parent.no_implicit_prelude.get() ||
attr::contains_name(&item.attrs, "no_implicit_prelude")
});
self.define(parent, name, TypeNS, (module, sp, vis));
self.module_map.insert(item.id, module);
*parent_ref = module;
Expand Down
65 changes: 35 additions & 30 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ enum ResolutionError<'a> {
/// error E0413: cannot be named the same as an enum variant or unit-like struct in scope
DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
/// error E0414: only irrefutable patterns allowed here
ConstantForIrrefutableBinding(Name),
ConstantForIrrefutableBinding(Name, &'a NameBinding<'a>),
/// error E0415: identifier is bound more than once in this parameter list
IdentifierBoundMoreThanOnceInParameterList(&'a str),
/// error E0416: identifier is bound more than once in the same pattern
Expand Down Expand Up @@ -317,19 +317,15 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
&format!("has same name as enum variant or unit-like struct"));
err
}
ResolutionError::ConstantForIrrefutableBinding(name) => {
ResolutionError::ConstantForIrrefutableBinding(name, binding) => {
let mut err = struct_span_err!(resolver.session,
span,
E0414,
"let variables cannot be named the same as const variables");
err.span_label(span,
&format!("cannot be named the same as a const variable"));
if let Some(binding) = resolver.current_module
.resolve_name_in_lexical_scope(name, ValueNS) {
let participle = if binding.is_import() { "imported" } else { "defined" };
err.span_label(binding.span, &format!("a constant `{}` is {} here",
name, participle));
}
let participle = if binding.is_import() { "imported" } else { "defined" };
err.span_label(binding.span, &format!("a constant `{}` is {} here", name, participle));
err
}
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
Expand Down Expand Up @@ -714,9 +710,9 @@ enum AssocItemResolveResult {
}

#[derive(Copy, Clone)]
enum BareIdentifierPatternResolution {
enum BareIdentifierPatternResolution<'a> {
FoundStructOrEnumVariant(Def),
FoundConst(Def, Name),
FoundConst(&'a NameBinding<'a>, Name),
BareIdentifierPatternUnresolved,
}

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

prelude: RefCell<Option<Module<'a>>>,
no_implicit_prelude: Cell<bool>,

glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
Expand Down Expand Up @@ -821,7 +817,7 @@ impl<'a> ModuleS<'a> {
extern_crate_id: None,
resolutions: RefCell::new(HashMap::new()),
unresolved_imports: RefCell::new(Vec::new()),
prelude: RefCell::new(None),
no_implicit_prelude: Cell::new(false),
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new((Vec::new())),
traits: RefCell::new(None),
Expand Down Expand Up @@ -985,6 +981,8 @@ pub struct Resolver<'a> {

graph_root: Module<'a>,

prelude: Option<Module<'a>>,

trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,

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

trait_item_map: FnvHashMap(),
structs: FnvHashMap(),
Expand Down Expand Up @@ -1456,7 +1455,15 @@ impl<'a> Resolver<'a> {
}

// We can only see through anonymous modules
if module.def.is_some() { return None; }
if module.def.is_some() {
return match self.prelude {
Some(prelude) if !module.no_implicit_prelude.get() => {
prelude.resolve_name(name, ns, false).success()
.map(LexicalScopeBinding::Item)
}
_ => None,
};
}
}
}

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

self.populate_module_if_necessary(module);
match use_lexical_scope {
true => module.resolve_name_in_lexical_scope(name, namespace)
.map(Success).unwrap_or(Failed(None)),
false => module.resolve_name(name, namespace, false),
}.and_then(|binding| {
module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
if record_used {
if let NameBindingKind::Import { directive, .. } = binding.kind {
self.used_imports.insert((directive.id, namespace));
Expand Down Expand Up @@ -2289,21 +2292,21 @@ impl<'a> Resolver<'a> {
);
self.record_def(pattern.id, err_path_resolution());
}
FoundConst(def, _) if const_ok => {
FoundConst(binding, _) if const_ok => {
debug!("(resolving pattern) resolving `{}` to constant", renamed);

self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
self.record_def(pattern.id,
PathResolution {
base_def: def,
base_def: binding.def().unwrap(),
depth: 0,
});
}
FoundConst(_, name) => {
FoundConst(binding, name) => {
resolve_error(
self,
pattern.span,
ResolutionError::ConstantForIrrefutableBinding(name)
ResolutionError::ConstantForIrrefutableBinding(name, binding)
);
self.record_def(pattern.id, err_path_resolution());
}
Expand Down Expand Up @@ -2526,7 +2529,7 @@ impl<'a> Resolver<'a> {
}

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

match def {
Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def),
Def::Const(..) | Def::AssociatedConst(..) => FoundConst(def, ident.name),
Def::Const(..) | Def::AssociatedConst(..) => FoundConst(binding, ident.name),
Def::Static(..) => {
let error = ResolutionError::StaticVariableReference(binding);
resolve_error(self, span, error);
Expand Down Expand Up @@ -3264,7 +3267,7 @@ impl<'a> Resolver<'a> {
let mut search_module = self.current_module;
loop {
// Look for trait children.
let mut search_in_module = |module: Module<'a>| {
let mut search_in_module = |this: &mut Self, module: Module<'a>| {
let mut traits = module.traits.borrow_mut();
if traits.is_none() {
let mut collected_traits = Vec::new();
Expand All @@ -3279,23 +3282,25 @@ impl<'a> Resolver<'a> {

for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
let trait_def_id = binding.def().unwrap().def_id();
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
if this.trait_item_map.contains_key(&(name, trait_def_id)) {
let mut import_id = None;
if let NameBindingKind::Import { directive, .. } = binding.kind {
let id = directive.id;
self.maybe_unused_trait_imports.insert(id);
this.maybe_unused_trait_imports.insert(id);
import_id = Some(id);
}
add_trait_info(&mut found_traits, trait_def_id, import_id, name);
self.record_use(trait_name, binding);
this.record_use(trait_name, binding);
}
}
};
search_in_module(search_module);
search_in_module(self, search_module);

match search_module.parent_link {
NoParentLink | ModuleParentLink(..) => {
search_module.prelude.borrow().map(search_in_module);
if !search_module.no_implicit_prelude.get() {
self.prelude.map(|prelude| search_in_module(self, prelude));
}
break;
}
BlockParentLink(parent_module, _) => {
Expand Down
11 changes: 1 addition & 10 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,6 @@ impl<'a> ::ModuleS<'a> {
Failed(None)
}

// Invariant: this may not be called until import resolution is complete.
pub fn resolve_name_in_lexical_scope(&self, name: Name, ns: Namespace)
-> Option<&'a NameBinding<'a>> {
self.resolution(name, ns).borrow().binding
.or_else(|| self.prelude.borrow().and_then(|prelude| {
prelude.resolve_name(name, ns, false).success()
}))
}

// Define the name or return the existing binding if there is a collision.
pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
-> Result<(), &'a NameBinding<'a>> {
Expand Down Expand Up @@ -633,7 +624,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
self.resolver.populate_module_if_necessary(target_module);

if let GlobImport { is_prelude: true } = directive.subclass {
*module_.prelude.borrow_mut() = Some(target_module);
self.resolver.prelude = Some(target_module);
return Success(());
}

Expand Down
5 changes: 4 additions & 1 deletion src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1820,7 +1820,10 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
}
}

write!(w, "</table>")
if curty.is_some() {
write!(w, "</table>")?;
}
Ok(())
}

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

0 comments on commit 24526cc

Please sign in to comment.