Auto merge of #32167 - jseyfried:refactor_prelude, r=nikomatsakis
resolve: Refactor how the prelude is handled This PR refactors how the prelude is handled in `resolve`. Instead of importing names from the prelude into each module's `resolutions`, this PR adds a new field `prelude: RefCell<Option<Module>>` to `ModuleS` that is set during import resolution but used only when resolving in a lexical scope (i.e. the scope of an initial segment of a relative path). r? @nikomatsakis
This commit is contained in:
commit
a1e29daf1a
|
@ -22,7 +22,6 @@ use {NameBinding, NameBindingKind};
|
||||||
use module_to_string;
|
use module_to_string;
|
||||||
use ParentLink::{ModuleParentLink, BlockParentLink};
|
use ParentLink::{ModuleParentLink, BlockParentLink};
|
||||||
use Resolver;
|
use Resolver;
|
||||||
use resolve_imports::Shadowable;
|
|
||||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
use {resolve_error, resolve_struct_error, ResolutionError};
|
||||||
|
|
||||||
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef, DlField, DlImpl};
|
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef, DlField, DlImpl};
|
||||||
|
@ -161,14 +160,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build up the import directives.
|
// Build up the import directives.
|
||||||
let shadowable = item.attrs.iter().any(|attr| {
|
let is_prelude = item.attrs.iter().any(|attr| {
|
||||||
attr.name() == special_idents::prelude_import.name.as_str()
|
attr.name() == special_idents::prelude_import.name.as_str()
|
||||||
});
|
});
|
||||||
let shadowable = if shadowable {
|
|
||||||
Shadowable::Always
|
|
||||||
} else {
|
|
||||||
Shadowable::Never
|
|
||||||
};
|
|
||||||
|
|
||||||
match view_path.node {
|
match view_path.node {
|
||||||
ViewPathSimple(binding, ref full_path) => {
|
ViewPathSimple(binding, ref full_path) => {
|
||||||
|
@ -186,7 +180,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
view_path.span,
|
view_path.span,
|
||||||
item.id,
|
item.id,
|
||||||
is_public,
|
is_public,
|
||||||
shadowable);
|
is_prelude);
|
||||||
}
|
}
|
||||||
ViewPathList(_, ref source_items) => {
|
ViewPathList(_, ref source_items) => {
|
||||||
// Make sure there's at most one `mod` import in the list.
|
// Make sure there's at most one `mod` import in the list.
|
||||||
|
@ -237,7 +231,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
source_item.span,
|
source_item.span,
|
||||||
source_item.node.id(),
|
source_item.node.id(),
|
||||||
is_public,
|
is_public,
|
||||||
shadowable);
|
is_prelude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ViewPathGlob(_) => {
|
ViewPathGlob(_) => {
|
||||||
|
@ -247,7 +241,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
view_path.span,
|
view_path.span,
|
||||||
item.id,
|
item.id,
|
||||||
is_public,
|
is_public,
|
||||||
shadowable);
|
is_prelude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parent
|
parent
|
||||||
|
@ -631,7 +625,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
shadowable: Shadowable) {
|
is_prelude: bool) {
|
||||||
// Bump the reference count on the name. Or, if this is a glob, set
|
// Bump the reference count on the name. Or, if this is a glob, set
|
||||||
// the appropriate flag.
|
// the appropriate flag.
|
||||||
|
|
||||||
|
@ -640,15 +634,18 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||||
module_.increment_outstanding_references_for(target, ValueNS, is_public);
|
module_.increment_outstanding_references_for(target, ValueNS, is_public);
|
||||||
module_.increment_outstanding_references_for(target, TypeNS, is_public);
|
module_.increment_outstanding_references_for(target, TypeNS, is_public);
|
||||||
}
|
}
|
||||||
GlobImport => {
|
GlobImport if !is_prelude => {
|
||||||
// Set the glob flag. This tells us that we don't know the
|
// Set the glob flag. This tells us that we don't know the
|
||||||
// module's exports ahead of time.
|
// module's exports ahead of time.
|
||||||
module_.inc_glob_count(is_public)
|
module_.inc_glob_count(is_public)
|
||||||
}
|
}
|
||||||
|
// Prelude imports are not included in the glob counts since they do not get added to
|
||||||
|
// `resolved_globs` -- they are handled separately in `resolve_imports`.
|
||||||
|
GlobImport => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let directive =
|
let directive =
|
||||||
ImportDirective::new(module_path, subclass, span, id, is_public, shadowable);
|
ImportDirective::new(module_path, subclass, span, id, is_public, is_prelude);
|
||||||
module_.add_import_directive(directive);
|
module_.add_import_directive(directive);
|
||||||
self.unresolved_imports += 1;
|
self.unresolved_imports += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,8 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
|
||||||
if let Some(sp) = resolver.ast_map.span_if_local(did) {
|
if let Some(sp) = resolver.ast_map.span_if_local(did) {
|
||||||
err.span_note(sp, "constant defined here");
|
err.span_note(sp, "constant defined here");
|
||||||
}
|
}
|
||||||
if let Success(binding) = resolver.current_module.resolve_name(name, ValueNS, true) {
|
if let Some(binding) = resolver.current_module
|
||||||
|
.resolve_name_in_lexical_scope(name, ValueNS) {
|
||||||
if binding.is_import() {
|
if binding.is_import() {
|
||||||
err.span_note(binding.span.unwrap(), "constant imported here");
|
err.span_note(binding.span.unwrap(), "constant imported here");
|
||||||
}
|
}
|
||||||
|
@ -820,7 +821,7 @@ pub struct ModuleS<'a> {
|
||||||
// entry block for `f`.
|
// entry block for `f`.
|
||||||
module_children: RefCell<NodeMap<Module<'a>>>,
|
module_children: RefCell<NodeMap<Module<'a>>>,
|
||||||
|
|
||||||
shadowed_traits: RefCell<Vec<&'a NameBinding<'a>>>,
|
prelude: RefCell<Option<Module<'a>>>,
|
||||||
|
|
||||||
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective)>>,
|
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective)>>,
|
||||||
resolved_globs: RefCell<(Vec<Module<'a>> /* public */, Vec<Module<'a>> /* private */)>,
|
resolved_globs: RefCell<(Vec<Module<'a>> /* public */, Vec<Module<'a>> /* private */)>,
|
||||||
|
@ -855,7 +856,7 @@ impl<'a> ModuleS<'a> {
|
||||||
resolutions: RefCell::new(HashMap::new()),
|
resolutions: RefCell::new(HashMap::new()),
|
||||||
unresolved_imports: RefCell::new(Vec::new()),
|
unresolved_imports: RefCell::new(Vec::new()),
|
||||||
module_children: RefCell::new(NodeMap()),
|
module_children: RefCell::new(NodeMap()),
|
||||||
shadowed_traits: RefCell::new(Vec::new()),
|
prelude: RefCell::new(None),
|
||||||
glob_importers: RefCell::new(Vec::new()),
|
glob_importers: RefCell::new(Vec::new()),
|
||||||
resolved_globs: RefCell::new((Vec::new(), Vec::new())),
|
resolved_globs: RefCell::new((Vec::new(), Vec::new())),
|
||||||
public_glob_count: Cell::new(0),
|
public_glob_count: Cell::new(0),
|
||||||
|
@ -932,8 +933,7 @@ bitflags! {
|
||||||
// Variants are considered `PUBLIC`, but some of them live in private enums.
|
// Variants are considered `PUBLIC`, but some of them live in private enums.
|
||||||
// We need to track them to prohibit reexports like `pub use PrivEnum::Variant`.
|
// We need to track them to prohibit reexports like `pub use PrivEnum::Variant`.
|
||||||
const PRIVATE_VARIANT = 1 << 2,
|
const PRIVATE_VARIANT = 1 << 2,
|
||||||
const PRELUDE = 1 << 3,
|
const GLOB_IMPORTED = 1 << 3,
|
||||||
const GLOB_IMPORTED = 1 << 4,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1537,13 +1537,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
module: Module<'a>,
|
module: Module<'a>,
|
||||||
name: Name,
|
name: Name,
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
allow_private_imports: bool,
|
use_lexical_scope: bool,
|
||||||
record_used: bool)
|
record_used: bool)
|
||||||
-> ResolveResult<&'a NameBinding<'a>> {
|
-> ResolveResult<&'a NameBinding<'a>> {
|
||||||
debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
|
debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
|
||||||
|
|
||||||
build_reduced_graph::populate_module_if_necessary(self, module);
|
build_reduced_graph::populate_module_if_necessary(self, module);
|
||||||
module.resolve_name(name, namespace, allow_private_imports).and_then(|binding| {
|
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| {
|
||||||
if record_used {
|
if record_used {
|
||||||
self.record_use(name, namespace, binding);
|
self.record_use(name, namespace, binding);
|
||||||
}
|
}
|
||||||
|
@ -2962,7 +2966,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
if name_path.len() == 1 {
|
if name_path.len() == 1 {
|
||||||
match this.primitive_type_table.primitive_types.get(last_name) {
|
match this.primitive_type_table.primitive_types.get(last_name) {
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => this.current_module.resolve_name(*last_name, TypeNS, true).success()
|
None => this.current_module.resolve_name_in_lexical_scope(*last_name, TypeNS)
|
||||||
.and_then(NameBinding::module)
|
.and_then(NameBinding::module)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -3019,7 +3023,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
// Look for a method in the current self type's impl module.
|
// Look for a method in the current self type's impl module.
|
||||||
if let Some(module) = get_module(self, path.span, &name_path) {
|
if let Some(module) = get_module(self, path.span, &name_path) {
|
||||||
if let Success(binding) = module.resolve_name(name, ValueNS, true) {
|
if let Some(binding) = module.resolve_name_in_lexical_scope(name, ValueNS) {
|
||||||
if let Some(Def::Method(did)) = binding.def() {
|
if let Some(Def::Method(did)) = binding.def() {
|
||||||
if is_static_method(self, did) {
|
if is_static_method(self, did) {
|
||||||
return StaticMethod(path_names_to_string(&path, 0));
|
return StaticMethod(path_names_to_string(&path, 0));
|
||||||
|
@ -3336,33 +3340,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for trait children.
|
// Look for trait children.
|
||||||
build_reduced_graph::populate_module_if_necessary(self, &search_module);
|
let mut search_in_module = |module: Module<'a>| module.for_each_child(|_, ns, binding| {
|
||||||
|
|
||||||
search_module.for_each_child(|_, ns, name_binding| {
|
|
||||||
if ns != TypeNS { return }
|
if ns != TypeNS { return }
|
||||||
let trait_def_id = match name_binding.def() {
|
let trait_def_id = match binding.def() {
|
||||||
Some(Def::Trait(trait_def_id)) => trait_def_id,
|
Some(Def::Trait(trait_def_id)) => trait_def_id,
|
||||||
Some(..) | None => return,
|
Some(..) | None => return,
|
||||||
};
|
};
|
||||||
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
|
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
|
||||||
add_trait_info(&mut found_traits, trait_def_id, name);
|
add_trait_info(&mut found_traits, trait_def_id, name);
|
||||||
let trait_name = self.get_trait_name(trait_def_id);
|
let trait_name = self.get_trait_name(trait_def_id);
|
||||||
self.record_use(trait_name, TypeNS, name_binding);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Look for shadowed traits.
|
|
||||||
for binding in search_module.shadowed_traits.borrow().iter() {
|
|
||||||
let did = binding.def().unwrap().def_id();
|
|
||||||
if self.trait_item_map.contains_key(&(name, did)) {
|
|
||||||
add_trait_info(&mut found_traits, did, name);
|
|
||||||
let trait_name = self.get_trait_name(did);
|
|
||||||
self.record_use(trait_name, TypeNS, binding);
|
self.record_use(trait_name, TypeNS, binding);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
search_in_module(search_module);
|
||||||
|
|
||||||
match search_module.parent_link {
|
match search_module.parent_link {
|
||||||
NoParentLink | ModuleParentLink(..) => break,
|
NoParentLink | ModuleParentLink(..) => {
|
||||||
|
search_module.prelude.borrow().map(search_in_module);
|
||||||
|
break;
|
||||||
|
}
|
||||||
BlockParentLink(parent_module, _) => {
|
BlockParentLink(parent_module, _) => {
|
||||||
search_module = parent_module;
|
search_module = parent_module;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,13 +57,6 @@ impl ImportDirectiveSubclass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether an import can be shadowed by another import.
|
|
||||||
#[derive(Debug,PartialEq,Clone,Copy)]
|
|
||||||
pub enum Shadowable {
|
|
||||||
Always,
|
|
||||||
Never,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// One import directive.
|
/// One import directive.
|
||||||
#[derive(Debug,Clone)]
|
#[derive(Debug,Clone)]
|
||||||
pub struct ImportDirective {
|
pub struct ImportDirective {
|
||||||
|
@ -72,7 +65,7 @@ pub struct ImportDirective {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub is_public: bool, // see note in ImportResolutionPerNamespace about how to use this
|
pub is_public: bool, // see note in ImportResolutionPerNamespace about how to use this
|
||||||
pub shadowable: Shadowable,
|
pub is_prelude: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportDirective {
|
impl ImportDirective {
|
||||||
|
@ -81,7 +74,7 @@ impl ImportDirective {
|
||||||
span: Span,
|
span: Span,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
shadowable: Shadowable)
|
is_prelude: bool)
|
||||||
-> ImportDirective {
|
-> ImportDirective {
|
||||||
ImportDirective {
|
ImportDirective {
|
||||||
module_path: module_path,
|
module_path: module_path,
|
||||||
|
@ -89,7 +82,7 @@ impl ImportDirective {
|
||||||
span: span,
|
span: span,
|
||||||
id: id,
|
id: id,
|
||||||
is_public: is_public,
|
is_public: is_public,
|
||||||
shadowable: shadowable,
|
is_prelude: is_prelude,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,9 +98,6 @@ impl ImportDirective {
|
||||||
if let GlobImport = self.subclass {
|
if let GlobImport = self.subclass {
|
||||||
modifiers = modifiers | DefModifiers::GLOB_IMPORTED;
|
modifiers = modifiers | DefModifiers::GLOB_IMPORTED;
|
||||||
}
|
}
|
||||||
if self.shadowable == Shadowable::Always {
|
|
||||||
modifiers = modifiers | DefModifiers::PRELUDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NameBinding {
|
NameBinding {
|
||||||
kind: NameBindingKind::Import {
|
kind: NameBindingKind::Import {
|
||||||
|
@ -135,44 +125,36 @@ pub struct NameResolution<'a> {
|
||||||
|
|
||||||
impl<'a> NameResolution<'a> {
|
impl<'a> NameResolution<'a> {
|
||||||
fn try_define(&mut self, binding: &'a NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> {
|
fn try_define(&mut self, binding: &'a NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> {
|
||||||
match self.binding {
|
if let Some(old_binding) = self.binding {
|
||||||
Some(old_binding) if !old_binding.defined_with(DefModifiers::PRELUDE) => {
|
if binding.defined_with(DefModifiers::GLOB_IMPORTED) {
|
||||||
if binding.defined_with(DefModifiers::GLOB_IMPORTED) {
|
self.duplicate_globs.push(binding);
|
||||||
self.duplicate_globs.push(binding);
|
} else if old_binding.defined_with(DefModifiers::GLOB_IMPORTED) {
|
||||||
} else if old_binding.defined_with(DefModifiers::GLOB_IMPORTED) {
|
self.duplicate_globs.push(old_binding);
|
||||||
self.duplicate_globs.push(old_binding);
|
self.binding = Some(binding);
|
||||||
self.binding = Some(binding);
|
} else {
|
||||||
} else {
|
return Err(old_binding);
|
||||||
return Err(old_binding);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => self.binding = Some(binding),
|
} else {
|
||||||
|
self.binding = Some(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the resolution of the name assuming no more globs will define it.
|
|
||||||
fn result(&self, allow_private_imports: bool) -> ResolveResult<&'a NameBinding<'a>> {
|
|
||||||
match self.binding {
|
|
||||||
Some(binding) if !binding.defined_with(DefModifiers::GLOB_IMPORTED) => Success(binding),
|
|
||||||
// If we don't allow private imports and no public imports can define the name, fail.
|
|
||||||
_ if !allow_private_imports && self.pub_outstanding_references == 0 &&
|
|
||||||
!self.binding.map(NameBinding::is_public).unwrap_or(false) => Failed(None),
|
|
||||||
_ if self.outstanding_references > 0 => Indeterminate,
|
|
||||||
Some(binding) => Success(binding),
|
|
||||||
None => Failed(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns Some(the resolution of the name), or None if the resolution depends
|
// Returns Some(the resolution of the name), or None if the resolution depends
|
||||||
// on whether more globs can define the name.
|
// on whether more globs can define the name.
|
||||||
fn try_result(&self, allow_private_imports: bool)
|
fn try_result(&self, allow_private_imports: bool)
|
||||||
-> Option<ResolveResult<&'a NameBinding<'a>>> {
|
-> Option<ResolveResult<&'a NameBinding<'a>>> {
|
||||||
match self.result(allow_private_imports) {
|
match self.binding {
|
||||||
Success(binding) if binding.defined_with(DefModifiers::PRELUDE) => None,
|
Some(binding) if !binding.defined_with(DefModifiers::GLOB_IMPORTED) =>
|
||||||
Failed(_) => None,
|
Some(Success(binding)),
|
||||||
result @ _ => Some(result),
|
// If (1) we don't allow private imports, (2) no public single import can define the
|
||||||
|
// name, and (3) no public glob has defined the name, the resolution depends on globs.
|
||||||
|
_ if !allow_private_imports && self.pub_outstanding_references == 0 &&
|
||||||
|
!self.binding.map(NameBinding::is_public).unwrap_or(false) => None,
|
||||||
|
_ if self.outstanding_references > 0 => Some(Indeterminate),
|
||||||
|
Some(binding) => Some(Success(binding)),
|
||||||
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,8 +184,6 @@ impl<'a> NameResolution<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
for duplicate_glob in self.duplicate_globs.iter() {
|
for duplicate_glob in self.duplicate_globs.iter() {
|
||||||
if duplicate_glob.defined_with(DefModifiers::PRELUDE) { continue }
|
|
||||||
|
|
||||||
// FIXME #31337: We currently allow items to shadow glob-imported re-exports.
|
// FIXME #31337: We currently allow items to shadow glob-imported re-exports.
|
||||||
if !binding.is_import() {
|
if !binding.is_import() {
|
||||||
if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
|
if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
|
||||||
|
@ -259,7 +239,16 @@ impl<'a> ::ModuleS<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolution.result(true)
|
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.resolutions.borrow().get(&(name, ns)).and_then(|resolution| resolution.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.
|
// Define the name or return the existing binding if there is a collision.
|
||||||
|
@ -369,7 +358,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||||
// resolution for it so that later resolve stages won't complain.
|
// resolution for it so that later resolve stages won't complain.
|
||||||
if let SingleImport { target, .. } = e.import_directive.subclass {
|
if let SingleImport { target, .. } = e.import_directive.subclass {
|
||||||
let dummy_binding = self.resolver.arenas.alloc_name_binding(NameBinding {
|
let dummy_binding = self.resolver.arenas.alloc_name_binding(NameBinding {
|
||||||
modifiers: DefModifiers::PRELUDE,
|
modifiers: DefModifiers::GLOB_IMPORTED,
|
||||||
kind: NameBindingKind::Def(Def::Err),
|
kind: NameBindingKind::Def(Def::Err),
|
||||||
span: None,
|
span: None,
|
||||||
});
|
});
|
||||||
|
@ -623,6 +612,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
build_reduced_graph::populate_module_if_necessary(self.resolver, target_module);
|
build_reduced_graph::populate_module_if_necessary(self.resolver, target_module);
|
||||||
|
|
||||||
|
if directive.is_prelude {
|
||||||
|
*module_.prelude.borrow_mut() = Some(target_module);
|
||||||
|
return Success(());
|
||||||
|
}
|
||||||
|
|
||||||
// Add to target_module's glob_importers and module_'s resolved_globs
|
// Add to target_module's glob_importers and module_'s resolved_globs
|
||||||
target_module.glob_importers.borrow_mut().push((module_, directive));
|
target_module.glob_importers.borrow_mut().push((module_, directive));
|
||||||
match *module_.resolved_globs.borrow_mut() {
|
match *module_.resolved_globs.borrow_mut() {
|
||||||
|
@ -685,13 +679,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||||
self.resolver.session.add_lint(lint, id, binding.span.unwrap(), msg);
|
self.resolver.session.add_lint(lint, id, binding.span.unwrap(), msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can always use methods from the prelude traits
|
|
||||||
for glob_binding in resolution.duplicate_globs.iter() {
|
|
||||||
if glob_binding.defined_with(DefModifiers::PRELUDE) {
|
|
||||||
module.shadowed_traits.borrow_mut().push(glob_binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if reexports.len() > 0 {
|
if reexports.len() > 0 {
|
||||||
|
|
Loading…
Reference in New Issue