First stage of enum namespacing changes

This commit is contained in:
Steven Fackler 2014-10-18 23:46:08 -07:00
parent 88b6e93d35
commit d7ff7da65a
17 changed files with 584 additions and 94 deletions

View File

@ -15,6 +15,7 @@
use metadata::common::*;
use metadata::cstore;
use metadata::decoder;
use middle::def;
use middle::lang_items;
use middle::resolve;
use middle::ty;
@ -114,6 +115,12 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId,
decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item)
}
pub fn get_enum_variant_defs(cstore: &cstore::CStore, enum_id: ast::DefId)
-> Vec<(def::Def, ast::Name, ast::Visibility)> {
let cdata = cstore.get_crate_data(enum_id.krate);
decoder::get_enum_variant_defs(&*cstore.intr, &*cdata, enum_id.node)
}
pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
-> Vec<Rc<ty::VariantInfo>> {
let cstore = &tcx.sess.cstore;

View File

@ -659,6 +659,24 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
}
}
pub fn get_enum_variant_defs(intr: &IdentInterner,
cdata: Cmd,
id: ast::NodeId)
-> Vec<(def::Def, ast::Name, ast::Visibility)> {
let data = cdata.data();
let items = reader::get_doc(rbml::Doc::new(data), tag_items);
let item = find_item(id, items);
enum_variant_ids(item, cdata).iter().map(|did| {
let item = find_item(did.node, items);
let name = item_name(intr, item);
let visibility = item_visibility(item);
match item_to_def_like(item, *did, cdata.cnum) {
DlDef(def @ def::DefVariant(..)) => (def, name, visibility),
_ => unreachable!()
}
}).collect()
}
pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> {
let data = cdata.data();

View File

@ -492,6 +492,7 @@ enum ModuleKind {
NormalModuleKind,
TraitModuleKind,
ImplModuleKind,
EnumModuleKind,
AnonymousModuleKind,
}
@ -568,10 +569,19 @@ impl Module {
}
}
bitflags! {
#[deriving(Show)]
flags DefModifiers: u8 {
const PUBLIC = 0b0000_0001,
const IMPORTABLE = 0b0000_0010,
const ENUM_STAGING_HACK = 0b0000_0100,
}
}
// Records a possibly-private type definition.
#[deriving(Clone)]
struct TypeNsDef {
is_public: bool, // see note in ImportResolution about how to use this
modifiers: DefModifiers, // see note in ImportResolution about how to use this
module_def: Option<Rc<Module>>,
type_def: Option<Def>,
type_span: Option<Span>
@ -580,7 +590,7 @@ struct TypeNsDef {
// Records a possibly-private value definition.
#[deriving(Clone, Show)]
struct ValueNsDef {
is_public: bool, // see note in ImportResolution about how to use this
modifiers: DefModifiers, // see note in ImportResolution about how to use this
def: Def,
value_span: Option<Span>,
}
@ -616,13 +626,14 @@ impl NameBindings {
is_public: bool,
sp: Span) {
// Merges the module with the existing type def or creates a new one.
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
is_public));
let type_def = self.type_def.borrow().clone();
match type_def {
None => {
*self.type_def.borrow_mut() = Some(TypeNsDef {
is_public: is_public,
modifiers: modifiers,
module_def: Some(module_),
type_def: None,
type_span: Some(sp)
@ -630,7 +641,7 @@ impl NameBindings {
}
Some(type_def) => {
*self.type_def.borrow_mut() = Some(TypeNsDef {
is_public: is_public,
modifiers: modifiers,
module_def: Some(module_),
type_span: Some(sp),
type_def: type_def.type_def
@ -647,13 +658,14 @@ impl NameBindings {
external: bool,
is_public: bool,
_sp: Span) {
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
let type_def = self.type_def.borrow().clone();
match type_def {
None => {
let module = Module::new(parent_link, def_id, kind,
external, is_public);
*self.type_def.borrow_mut() = Some(TypeNsDef {
is_public: is_public,
modifiers: modifiers,
module_def: Some(Rc::new(module)),
type_def: None,
type_span: None,
@ -668,7 +680,7 @@ impl NameBindings {
external,
is_public);
*self.type_def.borrow_mut() = Some(TypeNsDef {
is_public: is_public,
modifiers: modifiers,
module_def: Some(Rc::new(module)),
type_def: type_def.type_def,
type_span: None,
@ -681,7 +693,8 @@ impl NameBindings {
}
/// Records a type definition.
fn define_type(&self, def: Def, sp: Span, is_public: bool) {
fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
debug!("defining type for def {} with modifiers {}", def, modifiers);
// Merges the type with the existing type def or creates a new one.
let type_def = self.type_def.borrow().clone();
match type_def {
@ -690,7 +703,7 @@ impl NameBindings {
module_def: None,
type_def: Some(def),
type_span: Some(sp),
is_public: is_public,
modifiers: modifiers,
});
}
Some(type_def) => {
@ -698,18 +711,19 @@ impl NameBindings {
type_def: Some(def),
type_span: Some(sp),
module_def: type_def.module_def,
is_public: is_public,
modifiers: modifiers,
});
}
}
}
/// Records a value definition.
fn define_value(&self, def: Def, sp: Span, is_public: bool) {
fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
debug!("defining value for def {} with modifiers {}", def, modifiers);
*self.value_def.borrow_mut() = Some(ValueNsDef {
def: def,
value_span: Some(sp),
is_public: is_public,
modifiers: modifiers,
});
}
@ -743,12 +757,16 @@ impl NameBindings {
}
fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
self.defined_in_namespace_with(namespace, PUBLIC)
}
fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
match namespace {
TypeNS => match *self.type_def.borrow() {
Some(ref def) => def.is_public, None => false
Some(ref def) => def.modifiers.contains(modifiers), None => false
},
ValueNS => match *self.value_def.borrow() {
Some(ref def) => def.is_public, None => false
Some(ref def) => def.modifiers.contains(modifiers), None => false
}
}
}
@ -1214,6 +1232,7 @@ impl<'a> Resolver<'a> {
let name = item.ident.name;
let sp = item.span;
let is_public = item.vis == ast::Public;
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
match item.node {
ItemMod(..) => {
@ -1241,13 +1260,13 @@ impl<'a> Resolver<'a> {
let mutbl = m == ast::MutMutable;
name_bindings.define_value
(DefStatic(local_def(item.id), mutbl), sp, is_public);
(DefStatic(local_def(item.id), mutbl), sp, modifiers);
parent
}
ItemConst(_, _) => {
self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
.define_value(DefConst(local_def(item.id)),
sp, is_public);
sp, modifiers);
parent
}
ItemFn(_, _, _, _, _) => {
@ -1255,7 +1274,7 @@ impl<'a> Resolver<'a> {
self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
let def = DefFn(local_def(item.id), false);
name_bindings.define_value(def, sp, is_public);
name_bindings.define_value(def, sp, modifiers);
parent
}
@ -1268,7 +1287,7 @@ impl<'a> Resolver<'a> {
sp);
name_bindings.define_type
(DefTy(local_def(item.id), false), sp, is_public);
(DefTy(local_def(item.id), false), sp, modifiers);
parent
}
@ -1280,14 +1299,32 @@ impl<'a> Resolver<'a> {
sp);
name_bindings.define_type
(DefTy(local_def(item.id), true), sp, is_public);
(DefTy(local_def(item.id), true), sp, modifiers);
let parent_link = self.get_parent_link(parent.clone(), name);
// We want to make sure the module type is EnumModuleKind
// even if there's already an ImplModuleKind module defined,
// since that's how we prevent duplicate enum definitions
name_bindings.set_module_kind(parent_link,
Some(local_def(item.id)),
EnumModuleKind,
false,
is_public,
sp);
for variant in (*enum_definition).variants.iter() {
self.build_reduced_graph_for_variant(
&**variant,
local_def(item.id),
ModuleReducedGraphParent(name_bindings.get_module()),
modifiers);
// Temporary staging hack
self.build_reduced_graph_for_variant(
&**variant,
local_def(item.id),
parent.clone(),
is_public);
modifiers | ENUM_STAGING_HACK);
}
parent
}
@ -1303,14 +1340,14 @@ impl<'a> Resolver<'a> {
let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
// Define a name in the type namespace.
name_bindings.define_type(DefTy(local_def(item.id), false), sp, is_public);
name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
// If this is a newtype or unit-like struct, define a name
// in the value namespace as well
match ctor_id {
Some(cid) => {
name_bindings.define_value(DefStruct(local_def(cid)),
sp, is_public);
sp, modifiers);
}
None => {}
}
@ -1347,6 +1384,12 @@ impl<'a> Resolver<'a> {
ImplModuleKind => {
ModuleReducedGraphParent(child.get_module())
}
Some(ref child) if child.get_module_if_available()
.is_some() &&
child.get_module().kind.get() ==
EnumModuleKind => {
ModuleReducedGraphParent(child.get_module())
}
// Create the module
_ => {
let name_bindings =
@ -1403,12 +1446,16 @@ impl<'a> Resolver<'a> {
}
};
let is_public =
method.pe_vis() == ast::Public;
// NB: not IMPORTABLE
let modifiers = if method.pe_vis() == ast::Public {
PUBLIC
} else {
DefModifiers::empty()
};
method_name_bindings.define_value(
def,
method.span,
is_public);
modifiers);
}
TypeImplItem(ref typedef) => {
// Add the typedef to the module.
@ -1421,12 +1468,16 @@ impl<'a> Resolver<'a> {
typedef.span);
let def = DefAssociatedTy(local_def(
typedef.id));
let is_public = typedef.vis ==
ast::Public;
// NB: not IMPORTABLE
let modifiers = if typedef.vis == ast::Public {
PUBLIC
} else {
DefModifiers::empty()
};
typedef_name_bindings.define_type(
def,
typedef.span,
is_public);
modifiers);
}
}
}
@ -1499,9 +1550,10 @@ impl<'a> Resolver<'a> {
module_parent.clone(),
ForbidDuplicateTypesAndValues,
ty_m.span);
// NB: not IMPORTABLE
method_name_bindings.define_value(def,
ty_m.span,
true);
PUBLIC);
(name, static_flag)
}
@ -1514,9 +1566,10 @@ impl<'a> Resolver<'a> {
module_parent.clone(),
ForbidDuplicateTypesAndValues,
associated_type.span);
// NB: not IMPORTABLE
name_bindings.define_type(def,
associated_type.span,
true);
PUBLIC);
(associated_type.ident.name, TypeTraitItemKind)
}
@ -1525,7 +1578,7 @@ impl<'a> Resolver<'a> {
self.trait_item_map.insert((name, def_id), kind);
}
name_bindings.define_type(DefTrait(def_id), sp, is_public);
name_bindings.define_type(DefTrait(def_id), sp, modifiers);
parent
}
ItemMac(..) => parent
@ -1538,7 +1591,7 @@ impl<'a> Resolver<'a> {
variant: &Variant,
item_id: DefId,
parent: ReducedGraphParent,
is_public: bool) {
modifiers: DefModifiers) {
let name = variant.node.name.name;
let is_exported = match variant.node.kind {
TupleVariantKind(_) => false,
@ -1554,10 +1607,10 @@ impl<'a> Resolver<'a> {
variant.span);
child.define_value(DefVariant(item_id,
local_def(variant.node.id), is_exported),
variant.span, is_public);
variant.span, modifiers);
child.define_type(DefVariant(item_id,
local_def(variant.node.id), is_exported),
variant.span, is_public);
variant.span, modifiers);
}
/// Constructs the reduced graph for one 'view item'. View items consist
@ -1703,6 +1756,7 @@ impl<'a> Resolver<'a> {
f: |&mut Resolver|) {
let name = foreign_item.ident.name;
let is_public = foreign_item.vis == ast::Public;
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
let name_bindings =
self.add_child(name, parent, ForbidDuplicateValues,
foreign_item.span);
@ -1710,7 +1764,7 @@ impl<'a> Resolver<'a> {
match foreign_item.node {
ForeignItemFn(_, ref generics) => {
let def = DefFn(local_def(foreign_item.id), false);
name_bindings.define_value(def, foreign_item.span, is_public);
name_bindings.define_value(def, foreign_item.span, modifiers);
self.with_type_parameter_rib(
HasTypeParameters(generics,
@ -1721,7 +1775,7 @@ impl<'a> Resolver<'a> {
}
ForeignItemStatic(_, m) => {
let def = DefStatic(local_def(foreign_item.id), m);
name_bindings.define_value(def, foreign_item.span, is_public);
name_bindings.define_value(def, foreign_item.span, modifiers);
f(self)
}
@ -1766,6 +1820,7 @@ impl<'a> Resolver<'a> {
external crate) building external def, priv {}",
vis);
let is_public = vis == ast::Public;
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
let is_exported = is_public && match new_parent {
ModuleReducedGraphParent(ref module) => {
match module.def_id.get() {
@ -1779,6 +1834,7 @@ impl<'a> Resolver<'a> {
}
let kind = match def {
DefTy(_, true) => EnumModuleKind,
DefStruct(..) | DefTy(..) => ImplModuleKind,
_ => NormalModuleKind
};
@ -1813,6 +1869,7 @@ impl<'a> Resolver<'a> {
match def {
DefMod(_) | DefForeignMod(_) => {}
// Still here for staging
DefVariant(enum_did, variant_id, is_struct) => {
debug!("(building reduced graph for external crate) building \
variant {}",
@ -1822,23 +1879,36 @@ impl<'a> Resolver<'a> {
// definition.
let is_exported = is_public ||
self.external_exports.contains(&enum_did);
let modifiers = IMPORTABLE | ENUM_STAGING_HACK | if is_exported {
PUBLIC
} else {
DefModifiers::empty()
};
if is_struct {
child_name_bindings.define_type(def, DUMMY_SP, is_exported);
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
// Not adding fields for variants as they are not accessed with a self receiver
self.structs.insert(variant_id, Vec::new());
} else {
child_name_bindings.define_value(def, DUMMY_SP, is_exported);
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
}
}
DefFn(ctor_id, true) => {
child_name_bindings.define_value(
csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
.map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, is_public);
.map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
}
DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
debug!("(building reduced graph for external \
crate) building value (fn/static) {}", final_ident);
child_name_bindings.define_value(def, DUMMY_SP, is_public);
// impl methods have already been defined with the correct importability modifier
let mut modifiers = match *child_name_bindings.value_def.borrow() {
Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
None => modifiers
};
if new_parent.module().kind.get() != NormalModuleKind {
modifiers = modifiers & !IMPORTABLE;
}
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
}
DefTrait(def_id) => {
debug!("(building reduced graph for external \
@ -1867,7 +1937,7 @@ impl<'a> Resolver<'a> {
}
}
child_name_bindings.define_type(def, DUMMY_SP, is_public);
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
// Define a module if necessary.
let parent_link = self.get_parent_link(new_parent, name);
@ -1878,23 +1948,57 @@ impl<'a> Resolver<'a> {
is_public,
DUMMY_SP)
}
DefTy(def_id, true) => { // enums
debug!("(building reduced graph for external crate) building enum {}", final_ident);
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
let enum_module = ModuleReducedGraphParent(child_name_bindings.get_module());
let variants = csearch::get_enum_variant_defs(&self.session.cstore, def_id);
for &(v_def, name, vis) in variants.iter() {
let (variant_id, is_struct) = match v_def {
DefVariant(_, variant_id, is_struct) => (variant_id, is_struct),
_ => unreachable!()
};
let child = self.add_child(name, enum_module.clone(),
OverwriteDuplicates,
DUMMY_SP);
// If this variant is public, then it was publicly reexported,
// otherwise we need to inherit the visibility of the enum
// definition.
let variant_exported = vis == ast::Public || is_exported;
let modifiers = IMPORTABLE | if variant_exported {
PUBLIC
} else {
DefModifiers::empty()
};
if is_struct {
child.define_type(v_def, DUMMY_SP, modifiers);
// Not adding fields for variants as they are not accessed with a self
// receiver
self.structs.insert(variant_id, Vec::new());
} else {
child.define_value(v_def, DUMMY_SP, modifiers);
}
}
}
DefTy(..) | DefAssociatedTy(..) => {
debug!("(building reduced graph for external \
crate) building type {}", final_ident);
child_name_bindings.define_type(def, DUMMY_SP, is_public);
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
}
DefStruct(def_id) => {
debug!("(building reduced graph for external \
crate) building type and value for {}",
final_ident);
child_name_bindings.define_type(def, DUMMY_SP, is_public);
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
f.name
}).collect::<Vec<_>>();
if fields.len() == 0 {
child_name_bindings.define_value(def, DUMMY_SP, is_public);
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
}
// Record the def ID and fields of this struct.
@ -2021,9 +2125,14 @@ impl<'a> Resolver<'a> {
DUMMY_SP);
let def = DefFn(method_info.def_id, false);
// NB: not IMPORTABLE
let modifiers = if visibility == ast::Public {
PUBLIC
} else {
DefModifiers::empty()
};
method_name_bindings.define_value(
def, DUMMY_SP,
visibility == ast::Public);
def, DUMMY_SP, modifiers);
}
}
@ -2394,7 +2503,7 @@ impl<'a> Resolver<'a> {
fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
NameBindings {
type_def: RefCell::new(Some(TypeNsDef {
is_public: false,
modifiers: IMPORTABLE,
module_def: Some(module),
type_def: None,
type_span: None
@ -2596,6 +2705,12 @@ impl<'a> Resolver<'a> {
target,
ValueNS);
self.check_that_import_is_importable(
&**name_bindings,
directive.span,
target,
ValueNS);
import_resolution.value_target =
Some(Target::new(target_module.clone(),
name_bindings.clone(),
@ -2619,6 +2734,12 @@ impl<'a> Resolver<'a> {
target,
TypeNS);
self.check_that_import_is_importable(
&**name_bindings,
directive.span,
target,
TypeNS);
import_resolution.type_target =
Some(Target::new(target_module.clone(),
name_bindings.clone(),
@ -2829,7 +2950,7 @@ impl<'a> Resolver<'a> {
self.module_to_string(module_));
// Merge the child item into the import resolution.
if name_bindings.defined_in_public_namespace(ValueNS) {
if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
debug!("(resolving glob import) ... for value target");
dest_import_resolution.value_target =
Some(Target::new(containing_module.clone(),
@ -2837,7 +2958,7 @@ impl<'a> Resolver<'a> {
import_directive.shadowable));
dest_import_resolution.value_id = id;
}
if name_bindings.defined_in_public_namespace(TypeNS) {
if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
debug!("(resolving glob import) ... for type target");
dest_import_resolution.type_target =
Some(Target::new(containing_module,
@ -2879,6 +3000,19 @@ impl<'a> Resolver<'a> {
}
}
/// Checks that an import is actually importable
fn check_that_import_is_importable(&mut self,
name_bindings: &NameBindings,
import_span: Span,
name: Name,
namespace: Namespace) {
if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
let msg = format!("`{}` is not directly importable",
token::get_name(name));
self.session.span_err(import_span, msg.as_slice());
}
}
/// Checks that imported names and items don't have the same name.
fn check_for_conflicts_between_imports_and_items(&mut self,
module: &Module,
@ -2918,8 +3052,8 @@ impl<'a> Resolver<'a> {
match import_resolution.value_target {
Some(ref target) if !target.shadowable => {
match *name_bindings.value_def.borrow() {
None => {}
Some(ref value) => {
// We want to allow the "flat" def of enum variants to be shadowed
Some(ref value) if !value.modifiers.contains(ENUM_STAGING_HACK) => {
let msg = format!("import `{}` conflicts with value \
in this module",
token::get_name(name).get());
@ -2933,6 +3067,7 @@ impl<'a> Resolver<'a> {
}
}
}
_ => {}
}
}
Some(_) | None => {}
@ -2941,8 +3076,8 @@ impl<'a> Resolver<'a> {
match import_resolution.type_target {
Some(ref target) if !target.shadowable => {
match *name_bindings.type_def.borrow() {
None => {}
Some(ref ty) => {
// We want to allow the "flat" def of enum variants to be shadowed
Some(ref ty) if !ty.modifiers.contains(ENUM_STAGING_HACK) => {
match ty.module_def {
None => {
let msg = format!("import `{}` conflicts with type in \
@ -2993,6 +3128,7 @@ impl<'a> Resolver<'a> {
}
}
}
_ => {}
}
}
Some(_) | None => {}
@ -3131,43 +3267,28 @@ impl<'a> Resolver<'a> {
return Failed(Some((span, msg)));
}
Some(ref module_def) => {
// If we're doing the search for an
// import, do not allow traits and impls
// to be selected.
match (name_search_type,
module_def.kind.get()) {
(ImportSearch, TraitModuleKind) |
(ImportSearch, ImplModuleKind) => {
let msg =
"Cannot import from a trait or \
type implementation".to_string();
return Failed(Some((span, msg)));
search_module = module_def.clone();
// track extern crates for unused_extern_crate lint
match module_def.def_id.get() {
Some(did) => {
self.used_crates.insert(did.krate);
}
(_, _) => {
search_module = module_def.clone();
_ => {}
}
// track extern crates for unused_extern_crates lint
match module_def.def_id.get() {
Some(did) => {
self.used_crates.insert(did.krate);
}
_ => {}
}
// Keep track of the closest
// private module used when
// resolving this import chain.
if !used_proxy &&
!search_module.is_public {
match search_module.def_id
.get() {
Some(did) => {
closest_private =
LastMod(DependsOn(did));
}
None => {}
}
// Keep track of the closest
// private module used when
// resolving this import chain.
if !used_proxy &&
!search_module.is_public {
match search_module.def_id
.get() {
Some(did) => {
closest_private =
LastMod(DependsOn(did));
}
None => {}
}
}
}
@ -3388,6 +3509,7 @@ impl<'a> Resolver<'a> {
}
TraitModuleKind |
ImplModuleKind |
EnumModuleKind |
AnonymousModuleKind => {
search_module = parent_module_node.upgrade().unwrap();
}
@ -3485,6 +3607,7 @@ impl<'a> Resolver<'a> {
NormalModuleKind => return Some(new_module),
TraitModuleKind |
ImplModuleKind |
EnumModuleKind |
AnonymousModuleKind => module_ = new_module,
}
}
@ -3500,6 +3623,7 @@ impl<'a> Resolver<'a> {
NormalModuleKind => return module_,
TraitModuleKind |
ImplModuleKind |
EnumModuleKind |
AnonymousModuleKind => {
match self.get_nearest_normal_module_parent(module_.clone()) {
None => module_,

View File

@ -0,0 +1,38 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(globs, struct_variant)]
pub use Foo::*;
pub enum Foo {
A,
B(int),
C { a: int },
}
impl Foo {
pub fn foo() {}
}
pub mod nest {
pub use self::Bar::*;
pub enum Bar {
D,
E(int),
F { a: int },
}
impl Bar {
pub fn foo() {}
}
}

View File

@ -0,0 +1,22 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(struct_variant)]
pub enum Foo {
A,
B(int),
C { a: int },
}
impl Foo {
pub fn foo() {}
pub fn bar(&self) {}
}

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use self::sub::Bar;
pub use self::sub::{Bar, Baz};
pub trait Trait {
fn foo();
@ -26,4 +26,10 @@ mod sub {
impl Bar {
pub fn new() {}
}
pub enum Baz {}
impl Baz {
pub fn new() {}
}
}

View File

@ -13,7 +13,7 @@ mod Foo {
}
enum Foo { //~ ERROR duplicate definition of type or module `Foo`
X
X //~ ERROR duplicate definition of value `X`
}
fn main() {}

View File

@ -0,0 +1,28 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:namespaced_enums.rs
#![feature(struct_variant, globs)]
extern crate namespaced_enums;
mod m {
pub use namespaced_enums::Foo::*;
}
pub fn main() {
use namespaced_enums::Foo::*;
foo(); //~ ERROR unresolved name `foo`
m::foo(); //~ ERROR unresolved name `m::foo`
bar(); //~ ERROR unresolved name `bar`
m::bar(); //~ ERROR unresolved name `m::bar`
}

View File

@ -0,0 +1,36 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(struct_variant, globs)]
mod m2 {
pub enum Foo {
A,
B(int),
C { a: int },
}
impl Foo {
pub fn foo() {}
pub fn bar(&self) {}
}
}
mod m {
pub use m2::Foo::*;
}
pub fn main() {
use m2::Foo::*;
foo(); //~ ERROR unresolved name `foo`
m::foo(); //~ ERROR unresolved name `m::foo`
bar(); //~ ERROR unresolved name `bar`
m::bar(); //~ ERROR unresolved name `m::bar`
}

View File

@ -13,12 +13,15 @@
extern crate use_from_trait_xc;
use use_from_trait_xc::Trait::foo;
//~^ ERROR unresolved import `use_from_trait_xc::Trait::foo`. Cannot import from a trait or type imp
//~^ ERROR `foo` is not directly importable
use use_from_trait_xc::Foo::new;
//~^ ERROR unresolved import `use_from_trait_xc::Foo::new`. Cannot import from a trait or type imple
//~^ ERROR `new` is not directly importable
use use_from_trait_xc::Bar::new;
//~^ ERROR unresolved import `use_from_trait_xc::Bar::new`. Cannot import from a trait or type
use use_from_trait_xc::Bar::new as bnew;
//~^ ERROR `bnew` is not directly importable
use use_from_trait_xc::Baz::new as baznew;
//~^ ERROR `baznew` is not directly importable
fn main() {}

View File

@ -9,9 +9,9 @@
// except according to those terms.
use Trait::foo;
//~^ ERROR unresolved import `Trait::foo`. Cannot import from a trait or type implementation
//~^ ERROR `foo` is not directly importable
use Foo::new;
//~^ ERROR unresolved import `Foo::new`. Cannot import from a trait or type implementation
//~^ ERROR `new` is not directly importable
pub trait Trait {
fn foo();

View File

@ -0,0 +1,32 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:namespaced_enum_emulate_flat.rs
#![feature(struct_variant)]
extern crate namespaced_enum_emulate_flat;
use namespaced_enum_emulate_flat::{Foo, A, B, C};
use namespaced_enum_emulate_flat::nest::{Bar, D, E, F};
fn _f(f: Foo) {
match f {
A | B(_) | C { .. } => {}
}
}
fn _f2(f: Bar) {
match f {
D | E(_) | F { .. } => {}
}
}
pub fn main() {}

View File

@ -0,0 +1,51 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(globs, struct_variant)]
pub use Foo::*;
use nest::{Bar, D, E, F};
pub enum Foo {
A,
B(int),
C { a: int },
}
impl Foo {
pub fn foo() {}
}
fn _f(f: Foo) {
match f {
A | B(_) | C { .. } => {}
}
}
mod nest {
pub use self::Bar::*;
pub enum Bar {
D,
E(int),
F { a: int },
}
impl Bar {
pub fn foo() {}
}
}
fn _f2(f: Bar) {
match f {
D | E(_) | F { .. } => {}
}
}
fn main() {}

View File

@ -0,0 +1,34 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:namespaced_enums.rs
#![feature(globs, struct_variant)]
extern crate namespaced_enums;
fn _f(f: namespaced_enums::Foo) {
use namespaced_enums::Foo::*;
match f {
A | B(_) | C { .. } => {}
}
}
mod m {
pub use namespaced_enums::Foo::*;
}
fn _f2(f: namespaced_enums::Foo) {
match f {
m::A | m::B(_) | m::C { .. } => {}
}
}
pub fn main() {}

View File

@ -0,0 +1,42 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(globs, struct_variant)]
mod m2 {
pub enum Foo {
A,
B(int),
C { a: int },
}
impl Foo {
pub fn foo() {}
}
}
mod m {
pub use m2::Foo::*;
}
fn _f(f: m2::Foo) {
use m2::Foo::*;
match f {
A | B(_) | C { .. } => {}
}
}
fn _f2(f: m2::Foo) {
match f {
m::A | m::B(_) | m::C { .. } => {}
}
}
pub fn main() {}

View File

@ -0,0 +1,25 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:namespaced_enums.rs
#![feature(struct_variant)]
extern crate namespaced_enums;
use namespaced_enums::Foo;
fn _foo (f: Foo) {
match f {
Foo::A | Foo::B(_) | Foo::C { .. } => {}
}
}
pub fn main() {}

View File

@ -0,0 +1,24 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(struct_variant)]
enum Foo {
A,
B(int),
C { a: int },
}
fn _foo (f: Foo) {
match f {
Foo::A | Foo::B(_) | Foo::C { .. } => {}
}
}
pub fn main() {}