mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Expand NameBinding to better represent bindings from imports
This commit is contained in:
parent
22e189ed57
commit
2e24c7410f
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Span>,
|
||||
}
|
||||
|
||||
#[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<Module<'a>> {
|
||||
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<Def> {
|
||||
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.
|
||||
|
@ -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,
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user