Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor away the prelude injection fold #34108

Merged
merged 3 commits into from
Jun 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 macros = time(time_passes,
Expand Down Expand Up @@ -720,10 +721,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 @@ -1818,7 +1818,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