diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index baed8bb9919e..8654fa19c28a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -19,7 +19,7 @@ use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport}; use resolve_imports::ImportResolution; use Module; use Namespace::{self, TypeNS, ValueNS}; -use {NameBinding, DefOrModule}; +use {NameBinding, NameBindingKind}; use {names_to_string, module_to_string}; use ParentLink::{ModuleParentLink, BlockParentLink}; use Resolver; @@ -82,8 +82,8 @@ impl<'a> ToNameBinding<'a> for (Module<'a>, Span) { impl<'a> ToNameBinding<'a> for (Def, Span, DefModifiers) { fn to_name_binding(self) -> NameBinding<'a> { - let def = DefOrModule::Def(self.0); - NameBinding { modifiers: self.2, def_or_module: def, span: Some(self.1) } + let kind = NameBindingKind::Def(self.0); + NameBinding { modifiers: self.2, kind: kind, span: Some(self.1) } } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 528209d5854c..37cedb75ec52 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -951,21 +951,26 @@ bitflags! { // We need to track them to prohibit reexports like `pub use PrivEnum::Variant`. const PRIVATE_VARIANT = 1 << 2, const PRELUDE = 1 << 3, + const GLOB_IMPORTED = 1 << 4, } } // Records a possibly-private value, type, or module definition. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct NameBinding<'a> { - modifiers: DefModifiers, // see note in ImportResolution about how to use this - def_or_module: DefOrModule<'a>, + modifiers: DefModifiers, + kind: NameBindingKind<'a>, span: Option, } -#[derive(Clone, Debug)] -enum DefOrModule<'a> { +#[derive(Debug)] +enum NameBindingKind<'a> { Def(Def), Module(Module<'a>), + Import { + binding: &'a NameBinding<'a>, + id: NodeId, + }, } impl<'a> NameBinding<'a> { @@ -976,20 +981,22 @@ impl<'a> NameBinding<'a> { DefModifiers::empty() } | DefModifiers::IMPORTABLE; - NameBinding { modifiers: modifiers, def_or_module: DefOrModule::Module(module), span: span } + NameBinding { modifiers: modifiers, kind: NameBindingKind::Module(module), span: span } } fn module(&self) -> Option> { - match self.def_or_module { - DefOrModule::Module(ref module) => Some(module), - DefOrModule::Def(_) => None, + match self.kind { + NameBindingKind::Module(module) => Some(module), + NameBindingKind::Def(_) => None, + NameBindingKind::Import { binding, .. } => binding.module(), } } fn def(&self) -> Option { - match self.def_or_module { - DefOrModule::Def(def) => Some(def), - DefOrModule::Module(ref module) => module.def, + match self.kind { + NameBindingKind::Def(def) => Some(def), + NameBindingKind::Module(module) => module.def, + NameBindingKind::Import { binding, .. } => binding.def(), } } @@ -1009,6 +1016,13 @@ impl<'a> NameBinding<'a> { fn is_extern_crate(&self) -> bool { self.module().map(|module| module.is_extern_crate).unwrap_or(false) } + + fn is_import(&self) -> bool { + match self.kind { + NameBindingKind::Import { .. } => true, + _ => false, + } + } } /// Interns the names of the primitive types. diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 015b07a7ebf0..9f0e9e107521 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,10 +11,9 @@ use self::ImportDirectiveSubclass::*; use DefModifiers; -use DefOrModule; use Module; use Namespace::{self, TypeNS, ValueNS}; -use NameBinding; +use {NameBinding, NameBindingKind}; use ResolveResult; use ResolveResult::*; use Resolver; @@ -82,11 +81,22 @@ impl ImportDirective { // Given the binding to which this directive resolves in a particular namespace, // this returns the binding for the name this directive defines in that namespace. fn import<'a>(&self, binding: &'a NameBinding<'a>) -> NameBinding<'a> { - let mut binding = binding.clone(); - if self.shadowable == Shadowable::Always { - binding.modifiers = binding.modifiers | DefModifiers::PRELUDE; + let mut modifiers = match self.is_public { + true => DefModifiers::PUBLIC | DefModifiers::IMPORTABLE, + false => DefModifiers::empty(), + }; + if let GlobImport = self.subclass { + modifiers = modifiers | DefModifiers::GLOB_IMPORTED; + } + if self.shadowable == Shadowable::Always { + modifiers = modifiers | DefModifiers::PRELUDE; + } + + NameBinding { + kind: NameBindingKind::Import { binding: binding, id: self.id }, + span: Some(self.span), + modifiers: modifiers, } - binding } } @@ -216,7 +226,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let dummy_binding = self.resolver.new_name_binding(NameBinding { modifiers: DefModifiers::IMPORTABLE, - def_or_module: DefOrModule::Def(Def::Err), + kind: NameBindingKind::Def(Def::Err), span: None, });