First stage of enum namespacing changes
This commit is contained in:
parent
88b6e93d35
commit
d7ff7da65a
17 changed files with 584 additions and 94 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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_,
|
||||
|
|
38
src/test/auxiliary/namespaced_enum_emulate_flat.rs
Normal file
38
src/test/auxiliary/namespaced_enum_emulate_flat.rs
Normal 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() {}
|
||||
}
|
||||
}
|
||||
|
||||
|
22
src/test/auxiliary/namespaced_enums.rs
Normal file
22
src/test/auxiliary/namespaced_enums.rs
Normal 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) {}
|
||||
}
|
||||
|
|
@ -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() {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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`
|
||||
}
|
||||
|
|
@ -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`
|
||||
}
|
|
@ -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() {}
|
||||
|
|
|
@ -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();
|
||||
|
|
32
src/test/run-pass/namespaced-enum-emulate-flat-xc.rs
Normal file
32
src/test/run-pass/namespaced-enum-emulate-flat-xc.rs
Normal 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() {}
|
||||
|
51
src/test/run-pass/namespaced-enum-emulate-flat.rs
Normal file
51
src/test/run-pass/namespaced-enum-emulate-flat.rs
Normal 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() {}
|
34
src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
Normal file
34
src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
Normal 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() {}
|
42
src/test/run-pass/namespaced-enum-glob-import.rs
Normal file
42
src/test/run-pass/namespaced-enum-glob-import.rs
Normal 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() {}
|
25
src/test/run-pass/namespaced-enums-xcrate.rs
Normal file
25
src/test/run-pass/namespaced-enums-xcrate.rs
Normal 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() {}
|
||||
|
24
src/test/run-pass/namespaced-enums.rs
Normal file
24
src/test/run-pass/namespaced-enums.rs
Normal 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() {}
|
Loading…
Add table
Reference in a new issue