mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-31 09:04:18 +00:00
First stage of enum namespacing changes
This commit is contained in:
parent
88b6e93d35
commit
d7ff7da65a
@ -15,6 +15,7 @@
|
|||||||
use metadata::common::*;
|
use metadata::common::*;
|
||||||
use metadata::cstore;
|
use metadata::cstore;
|
||||||
use metadata::decoder;
|
use metadata::decoder;
|
||||||
|
use middle::def;
|
||||||
use middle::lang_items;
|
use middle::lang_items;
|
||||||
use middle::resolve;
|
use middle::resolve;
|
||||||
use middle::ty;
|
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)
|
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)
|
pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
|
||||||
-> Vec<Rc<ty::VariantInfo>> {
|
-> Vec<Rc<ty::VariantInfo>> {
|
||||||
let cstore = &tcx.sess.cstore;
|
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,
|
pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
|
||||||
tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> {
|
tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> {
|
||||||
let data = cdata.data();
|
let data = cdata.data();
|
||||||
|
@ -492,6 +492,7 @@ enum ModuleKind {
|
|||||||
NormalModuleKind,
|
NormalModuleKind,
|
||||||
TraitModuleKind,
|
TraitModuleKind,
|
||||||
ImplModuleKind,
|
ImplModuleKind,
|
||||||
|
EnumModuleKind,
|
||||||
AnonymousModuleKind,
|
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.
|
// Records a possibly-private type definition.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
struct TypeNsDef {
|
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>>,
|
module_def: Option<Rc<Module>>,
|
||||||
type_def: Option<Def>,
|
type_def: Option<Def>,
|
||||||
type_span: Option<Span>
|
type_span: Option<Span>
|
||||||
@ -580,7 +590,7 @@ struct TypeNsDef {
|
|||||||
// Records a possibly-private value definition.
|
// Records a possibly-private value definition.
|
||||||
#[deriving(Clone, Show)]
|
#[deriving(Clone, Show)]
|
||||||
struct ValueNsDef {
|
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,
|
def: Def,
|
||||||
value_span: Option<Span>,
|
value_span: Option<Span>,
|
||||||
}
|
}
|
||||||
@ -616,13 +626,14 @@ impl NameBindings {
|
|||||||
is_public: bool,
|
is_public: bool,
|
||||||
sp: Span) {
|
sp: Span) {
|
||||||
// Merges the module with the existing type def or creates a new one.
|
// 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,
|
let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
|
||||||
is_public));
|
is_public));
|
||||||
let type_def = self.type_def.borrow().clone();
|
let type_def = self.type_def.borrow().clone();
|
||||||
match type_def {
|
match type_def {
|
||||||
None => {
|
None => {
|
||||||
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
||||||
is_public: is_public,
|
modifiers: modifiers,
|
||||||
module_def: Some(module_),
|
module_def: Some(module_),
|
||||||
type_def: None,
|
type_def: None,
|
||||||
type_span: Some(sp)
|
type_span: Some(sp)
|
||||||
@ -630,7 +641,7 @@ impl NameBindings {
|
|||||||
}
|
}
|
||||||
Some(type_def) => {
|
Some(type_def) => {
|
||||||
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
||||||
is_public: is_public,
|
modifiers: modifiers,
|
||||||
module_def: Some(module_),
|
module_def: Some(module_),
|
||||||
type_span: Some(sp),
|
type_span: Some(sp),
|
||||||
type_def: type_def.type_def
|
type_def: type_def.type_def
|
||||||
@ -647,13 +658,14 @@ impl NameBindings {
|
|||||||
external: bool,
|
external: bool,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
_sp: Span) {
|
_sp: Span) {
|
||||||
|
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||||
let type_def = self.type_def.borrow().clone();
|
let type_def = self.type_def.borrow().clone();
|
||||||
match type_def {
|
match type_def {
|
||||||
None => {
|
None => {
|
||||||
let module = Module::new(parent_link, def_id, kind,
|
let module = Module::new(parent_link, def_id, kind,
|
||||||
external, is_public);
|
external, is_public);
|
||||||
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
||||||
is_public: is_public,
|
modifiers: modifiers,
|
||||||
module_def: Some(Rc::new(module)),
|
module_def: Some(Rc::new(module)),
|
||||||
type_def: None,
|
type_def: None,
|
||||||
type_span: None,
|
type_span: None,
|
||||||
@ -668,7 +680,7 @@ impl NameBindings {
|
|||||||
external,
|
external,
|
||||||
is_public);
|
is_public);
|
||||||
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
*self.type_def.borrow_mut() = Some(TypeNsDef {
|
||||||
is_public: is_public,
|
modifiers: modifiers,
|
||||||
module_def: Some(Rc::new(module)),
|
module_def: Some(Rc::new(module)),
|
||||||
type_def: type_def.type_def,
|
type_def: type_def.type_def,
|
||||||
type_span: None,
|
type_span: None,
|
||||||
@ -681,7 +693,8 @@ impl NameBindings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Records a type definition.
|
/// 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.
|
// Merges the type with the existing type def or creates a new one.
|
||||||
let type_def = self.type_def.borrow().clone();
|
let type_def = self.type_def.borrow().clone();
|
||||||
match type_def {
|
match type_def {
|
||||||
@ -690,7 +703,7 @@ impl NameBindings {
|
|||||||
module_def: None,
|
module_def: None,
|
||||||
type_def: Some(def),
|
type_def: Some(def),
|
||||||
type_span: Some(sp),
|
type_span: Some(sp),
|
||||||
is_public: is_public,
|
modifiers: modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(type_def) => {
|
Some(type_def) => {
|
||||||
@ -698,18 +711,19 @@ impl NameBindings {
|
|||||||
type_def: Some(def),
|
type_def: Some(def),
|
||||||
type_span: Some(sp),
|
type_span: Some(sp),
|
||||||
module_def: type_def.module_def,
|
module_def: type_def.module_def,
|
||||||
is_public: is_public,
|
modifiers: modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Records a value definition.
|
/// 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 {
|
*self.value_def.borrow_mut() = Some(ValueNsDef {
|
||||||
def: def,
|
def: def,
|
||||||
value_span: Some(sp),
|
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 {
|
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 {
|
match namespace {
|
||||||
TypeNS => match *self.type_def.borrow() {
|
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() {
|
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 name = item.ident.name;
|
||||||
let sp = item.span;
|
let sp = item.span;
|
||||||
let is_public = item.vis == ast::Public;
|
let is_public = item.vis == ast::Public;
|
||||||
|
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
ItemMod(..) => {
|
ItemMod(..) => {
|
||||||
@ -1241,13 +1260,13 @@ impl<'a> Resolver<'a> {
|
|||||||
let mutbl = m == ast::MutMutable;
|
let mutbl = m == ast::MutMutable;
|
||||||
|
|
||||||
name_bindings.define_value
|
name_bindings.define_value
|
||||||
(DefStatic(local_def(item.id), mutbl), sp, is_public);
|
(DefStatic(local_def(item.id), mutbl), sp, modifiers);
|
||||||
parent
|
parent
|
||||||
}
|
}
|
||||||
ItemConst(_, _) => {
|
ItemConst(_, _) => {
|
||||||
self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
|
self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
|
||||||
.define_value(DefConst(local_def(item.id)),
|
.define_value(DefConst(local_def(item.id)),
|
||||||
sp, is_public);
|
sp, modifiers);
|
||||||
parent
|
parent
|
||||||
}
|
}
|
||||||
ItemFn(_, _, _, _, _) => {
|
ItemFn(_, _, _, _, _) => {
|
||||||
@ -1255,7 +1274,7 @@ impl<'a> Resolver<'a> {
|
|||||||
self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
|
self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
|
||||||
|
|
||||||
let def = DefFn(local_def(item.id), false);
|
let def = DefFn(local_def(item.id), false);
|
||||||
name_bindings.define_value(def, sp, is_public);
|
name_bindings.define_value(def, sp, modifiers);
|
||||||
parent
|
parent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1268,7 +1287,7 @@ impl<'a> Resolver<'a> {
|
|||||||
sp);
|
sp);
|
||||||
|
|
||||||
name_bindings.define_type
|
name_bindings.define_type
|
||||||
(DefTy(local_def(item.id), false), sp, is_public);
|
(DefTy(local_def(item.id), false), sp, modifiers);
|
||||||
parent
|
parent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,14 +1299,32 @@ impl<'a> Resolver<'a> {
|
|||||||
sp);
|
sp);
|
||||||
|
|
||||||
name_bindings.define_type
|
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() {
|
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(
|
self.build_reduced_graph_for_variant(
|
||||||
&**variant,
|
&**variant,
|
||||||
local_def(item.id),
|
local_def(item.id),
|
||||||
parent.clone(),
|
parent.clone(),
|
||||||
is_public);
|
modifiers | ENUM_STAGING_HACK);
|
||||||
}
|
}
|
||||||
parent
|
parent
|
||||||
}
|
}
|
||||||
@ -1303,14 +1340,14 @@ impl<'a> Resolver<'a> {
|
|||||||
let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
|
let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
|
||||||
|
|
||||||
// Define a name in the type namespace.
|
// 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
|
// If this is a newtype or unit-like struct, define a name
|
||||||
// in the value namespace as well
|
// in the value namespace as well
|
||||||
match ctor_id {
|
match ctor_id {
|
||||||
Some(cid) => {
|
Some(cid) => {
|
||||||
name_bindings.define_value(DefStruct(local_def(cid)),
|
name_bindings.define_value(DefStruct(local_def(cid)),
|
||||||
sp, is_public);
|
sp, modifiers);
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
@ -1347,6 +1384,12 @@ impl<'a> Resolver<'a> {
|
|||||||
ImplModuleKind => {
|
ImplModuleKind => {
|
||||||
ModuleReducedGraphParent(child.get_module())
|
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
|
// Create the module
|
||||||
_ => {
|
_ => {
|
||||||
let name_bindings =
|
let name_bindings =
|
||||||
@ -1403,12 +1446,16 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_public =
|
// NB: not IMPORTABLE
|
||||||
method.pe_vis() == ast::Public;
|
let modifiers = if method.pe_vis() == ast::Public {
|
||||||
|
PUBLIC
|
||||||
|
} else {
|
||||||
|
DefModifiers::empty()
|
||||||
|
};
|
||||||
method_name_bindings.define_value(
|
method_name_bindings.define_value(
|
||||||
def,
|
def,
|
||||||
method.span,
|
method.span,
|
||||||
is_public);
|
modifiers);
|
||||||
}
|
}
|
||||||
TypeImplItem(ref typedef) => {
|
TypeImplItem(ref typedef) => {
|
||||||
// Add the typedef to the module.
|
// Add the typedef to the module.
|
||||||
@ -1421,12 +1468,16 @@ impl<'a> Resolver<'a> {
|
|||||||
typedef.span);
|
typedef.span);
|
||||||
let def = DefAssociatedTy(local_def(
|
let def = DefAssociatedTy(local_def(
|
||||||
typedef.id));
|
typedef.id));
|
||||||
let is_public = typedef.vis ==
|
// NB: not IMPORTABLE
|
||||||
ast::Public;
|
let modifiers = if typedef.vis == ast::Public {
|
||||||
|
PUBLIC
|
||||||
|
} else {
|
||||||
|
DefModifiers::empty()
|
||||||
|
};
|
||||||
typedef_name_bindings.define_type(
|
typedef_name_bindings.define_type(
|
||||||
def,
|
def,
|
||||||
typedef.span,
|
typedef.span,
|
||||||
is_public);
|
modifiers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1499,9 +1550,10 @@ impl<'a> Resolver<'a> {
|
|||||||
module_parent.clone(),
|
module_parent.clone(),
|
||||||
ForbidDuplicateTypesAndValues,
|
ForbidDuplicateTypesAndValues,
|
||||||
ty_m.span);
|
ty_m.span);
|
||||||
|
// NB: not IMPORTABLE
|
||||||
method_name_bindings.define_value(def,
|
method_name_bindings.define_value(def,
|
||||||
ty_m.span,
|
ty_m.span,
|
||||||
true);
|
PUBLIC);
|
||||||
|
|
||||||
(name, static_flag)
|
(name, static_flag)
|
||||||
}
|
}
|
||||||
@ -1514,9 +1566,10 @@ impl<'a> Resolver<'a> {
|
|||||||
module_parent.clone(),
|
module_parent.clone(),
|
||||||
ForbidDuplicateTypesAndValues,
|
ForbidDuplicateTypesAndValues,
|
||||||
associated_type.span);
|
associated_type.span);
|
||||||
|
// NB: not IMPORTABLE
|
||||||
name_bindings.define_type(def,
|
name_bindings.define_type(def,
|
||||||
associated_type.span,
|
associated_type.span,
|
||||||
true);
|
PUBLIC);
|
||||||
|
|
||||||
(associated_type.ident.name, TypeTraitItemKind)
|
(associated_type.ident.name, TypeTraitItemKind)
|
||||||
}
|
}
|
||||||
@ -1525,7 +1578,7 @@ impl<'a> Resolver<'a> {
|
|||||||
self.trait_item_map.insert((name, def_id), kind);
|
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
|
parent
|
||||||
}
|
}
|
||||||
ItemMac(..) => parent
|
ItemMac(..) => parent
|
||||||
@ -1538,7 +1591,7 @@ impl<'a> Resolver<'a> {
|
|||||||
variant: &Variant,
|
variant: &Variant,
|
||||||
item_id: DefId,
|
item_id: DefId,
|
||||||
parent: ReducedGraphParent,
|
parent: ReducedGraphParent,
|
||||||
is_public: bool) {
|
modifiers: DefModifiers) {
|
||||||
let name = variant.node.name.name;
|
let name = variant.node.name.name;
|
||||||
let is_exported = match variant.node.kind {
|
let is_exported = match variant.node.kind {
|
||||||
TupleVariantKind(_) => false,
|
TupleVariantKind(_) => false,
|
||||||
@ -1554,10 +1607,10 @@ impl<'a> Resolver<'a> {
|
|||||||
variant.span);
|
variant.span);
|
||||||
child.define_value(DefVariant(item_id,
|
child.define_value(DefVariant(item_id,
|
||||||
local_def(variant.node.id), is_exported),
|
local_def(variant.node.id), is_exported),
|
||||||
variant.span, is_public);
|
variant.span, modifiers);
|
||||||
child.define_type(DefVariant(item_id,
|
child.define_type(DefVariant(item_id,
|
||||||
local_def(variant.node.id), is_exported),
|
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
|
/// Constructs the reduced graph for one 'view item'. View items consist
|
||||||
@ -1703,6 +1756,7 @@ impl<'a> Resolver<'a> {
|
|||||||
f: |&mut Resolver|) {
|
f: |&mut Resolver|) {
|
||||||
let name = foreign_item.ident.name;
|
let name = foreign_item.ident.name;
|
||||||
let is_public = foreign_item.vis == ast::Public;
|
let is_public = foreign_item.vis == ast::Public;
|
||||||
|
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||||
let name_bindings =
|
let name_bindings =
|
||||||
self.add_child(name, parent, ForbidDuplicateValues,
|
self.add_child(name, parent, ForbidDuplicateValues,
|
||||||
foreign_item.span);
|
foreign_item.span);
|
||||||
@ -1710,7 +1764,7 @@ impl<'a> Resolver<'a> {
|
|||||||
match foreign_item.node {
|
match foreign_item.node {
|
||||||
ForeignItemFn(_, ref generics) => {
|
ForeignItemFn(_, ref generics) => {
|
||||||
let def = DefFn(local_def(foreign_item.id), false);
|
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(
|
self.with_type_parameter_rib(
|
||||||
HasTypeParameters(generics,
|
HasTypeParameters(generics,
|
||||||
@ -1721,7 +1775,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
ForeignItemStatic(_, m) => {
|
ForeignItemStatic(_, m) => {
|
||||||
let def = DefStatic(local_def(foreign_item.id), 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)
|
f(self)
|
||||||
}
|
}
|
||||||
@ -1766,6 +1820,7 @@ impl<'a> Resolver<'a> {
|
|||||||
external crate) building external def, priv {}",
|
external crate) building external def, priv {}",
|
||||||
vis);
|
vis);
|
||||||
let is_public = vis == ast::Public;
|
let is_public = vis == ast::Public;
|
||||||
|
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||||
let is_exported = is_public && match new_parent {
|
let is_exported = is_public && match new_parent {
|
||||||
ModuleReducedGraphParent(ref module) => {
|
ModuleReducedGraphParent(ref module) => {
|
||||||
match module.def_id.get() {
|
match module.def_id.get() {
|
||||||
@ -1779,6 +1834,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let kind = match def {
|
let kind = match def {
|
||||||
|
DefTy(_, true) => EnumModuleKind,
|
||||||
DefStruct(..) | DefTy(..) => ImplModuleKind,
|
DefStruct(..) | DefTy(..) => ImplModuleKind,
|
||||||
_ => NormalModuleKind
|
_ => NormalModuleKind
|
||||||
};
|
};
|
||||||
@ -1813,6 +1869,7 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
match def {
|
match def {
|
||||||
DefMod(_) | DefForeignMod(_) => {}
|
DefMod(_) | DefForeignMod(_) => {}
|
||||||
|
// Still here for staging
|
||||||
DefVariant(enum_did, variant_id, is_struct) => {
|
DefVariant(enum_did, variant_id, is_struct) => {
|
||||||
debug!("(building reduced graph for external crate) building \
|
debug!("(building reduced graph for external crate) building \
|
||||||
variant {}",
|
variant {}",
|
||||||
@ -1822,23 +1879,36 @@ impl<'a> Resolver<'a> {
|
|||||||
// definition.
|
// definition.
|
||||||
let is_exported = is_public ||
|
let is_exported = is_public ||
|
||||||
self.external_exports.contains(&enum_did);
|
self.external_exports.contains(&enum_did);
|
||||||
|
let modifiers = IMPORTABLE | ENUM_STAGING_HACK | if is_exported {
|
||||||
|
PUBLIC
|
||||||
|
} else {
|
||||||
|
DefModifiers::empty()
|
||||||
|
};
|
||||||
if is_struct {
|
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
|
// Not adding fields for variants as they are not accessed with a self receiver
|
||||||
self.structs.insert(variant_id, Vec::new());
|
self.structs.insert(variant_id, Vec::new());
|
||||||
} else {
|
} else {
|
||||||
child_name_bindings.define_value(def, DUMMY_SP, is_exported);
|
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefFn(ctor_id, true) => {
|
DefFn(ctor_id, true) => {
|
||||||
child_name_bindings.define_value(
|
child_name_bindings.define_value(
|
||||||
csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
|
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(..) => {
|
DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
|
||||||
debug!("(building reduced graph for external \
|
debug!("(building reduced graph for external \
|
||||||
crate) building value (fn/static) {}", final_ident);
|
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) => {
|
DefTrait(def_id) => {
|
||||||
debug!("(building reduced graph for external \
|
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.
|
// Define a module if necessary.
|
||||||
let parent_link = self.get_parent_link(new_parent, name);
|
let parent_link = self.get_parent_link(new_parent, name);
|
||||||
@ -1878,23 +1948,57 @@ impl<'a> Resolver<'a> {
|
|||||||
is_public,
|
is_public,
|
||||||
DUMMY_SP)
|
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(..) => {
|
DefTy(..) | DefAssociatedTy(..) => {
|
||||||
debug!("(building reduced graph for external \
|
debug!("(building reduced graph for external \
|
||||||
crate) building type {}", final_ident);
|
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) => {
|
DefStruct(def_id) => {
|
||||||
debug!("(building reduced graph for external \
|
debug!("(building reduced graph for external \
|
||||||
crate) building type and value for {}",
|
crate) building type and value for {}",
|
||||||
final_ident);
|
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| {
|
let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
|
||||||
f.name
|
f.name
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
if fields.len() == 0 {
|
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.
|
// Record the def ID and fields of this struct.
|
||||||
@ -2021,9 +2125,14 @@ impl<'a> Resolver<'a> {
|
|||||||
DUMMY_SP);
|
DUMMY_SP);
|
||||||
let def = DefFn(method_info.def_id, false);
|
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(
|
method_name_bindings.define_value(
|
||||||
def, DUMMY_SP,
|
def, DUMMY_SP, modifiers);
|
||||||
visibility == ast::Public);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2394,7 +2503,7 @@ impl<'a> Resolver<'a> {
|
|||||||
fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
|
fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
|
||||||
NameBindings {
|
NameBindings {
|
||||||
type_def: RefCell::new(Some(TypeNsDef {
|
type_def: RefCell::new(Some(TypeNsDef {
|
||||||
is_public: false,
|
modifiers: IMPORTABLE,
|
||||||
module_def: Some(module),
|
module_def: Some(module),
|
||||||
type_def: None,
|
type_def: None,
|
||||||
type_span: None
|
type_span: None
|
||||||
@ -2596,6 +2705,12 @@ impl<'a> Resolver<'a> {
|
|||||||
target,
|
target,
|
||||||
ValueNS);
|
ValueNS);
|
||||||
|
|
||||||
|
self.check_that_import_is_importable(
|
||||||
|
&**name_bindings,
|
||||||
|
directive.span,
|
||||||
|
target,
|
||||||
|
ValueNS);
|
||||||
|
|
||||||
import_resolution.value_target =
|
import_resolution.value_target =
|
||||||
Some(Target::new(target_module.clone(),
|
Some(Target::new(target_module.clone(),
|
||||||
name_bindings.clone(),
|
name_bindings.clone(),
|
||||||
@ -2619,6 +2734,12 @@ impl<'a> Resolver<'a> {
|
|||||||
target,
|
target,
|
||||||
TypeNS);
|
TypeNS);
|
||||||
|
|
||||||
|
self.check_that_import_is_importable(
|
||||||
|
&**name_bindings,
|
||||||
|
directive.span,
|
||||||
|
target,
|
||||||
|
TypeNS);
|
||||||
|
|
||||||
import_resolution.type_target =
|
import_resolution.type_target =
|
||||||
Some(Target::new(target_module.clone(),
|
Some(Target::new(target_module.clone(),
|
||||||
name_bindings.clone(),
|
name_bindings.clone(),
|
||||||
@ -2829,7 +2950,7 @@ impl<'a> Resolver<'a> {
|
|||||||
self.module_to_string(module_));
|
self.module_to_string(module_));
|
||||||
|
|
||||||
// Merge the child item into the import resolution.
|
// 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");
|
debug!("(resolving glob import) ... for value target");
|
||||||
dest_import_resolution.value_target =
|
dest_import_resolution.value_target =
|
||||||
Some(Target::new(containing_module.clone(),
|
Some(Target::new(containing_module.clone(),
|
||||||
@ -2837,7 +2958,7 @@ impl<'a> Resolver<'a> {
|
|||||||
import_directive.shadowable));
|
import_directive.shadowable));
|
||||||
dest_import_resolution.value_id = id;
|
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");
|
debug!("(resolving glob import) ... for type target");
|
||||||
dest_import_resolution.type_target =
|
dest_import_resolution.type_target =
|
||||||
Some(Target::new(containing_module,
|
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.
|
/// Checks that imported names and items don't have the same name.
|
||||||
fn check_for_conflicts_between_imports_and_items(&mut self,
|
fn check_for_conflicts_between_imports_and_items(&mut self,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
@ -2918,8 +3052,8 @@ impl<'a> Resolver<'a> {
|
|||||||
match import_resolution.value_target {
|
match import_resolution.value_target {
|
||||||
Some(ref target) if !target.shadowable => {
|
Some(ref target) if !target.shadowable => {
|
||||||
match *name_bindings.value_def.borrow() {
|
match *name_bindings.value_def.borrow() {
|
||||||
None => {}
|
// We want to allow the "flat" def of enum variants to be shadowed
|
||||||
Some(ref value) => {
|
Some(ref value) if !value.modifiers.contains(ENUM_STAGING_HACK) => {
|
||||||
let msg = format!("import `{}` conflicts with value \
|
let msg = format!("import `{}` conflicts with value \
|
||||||
in this module",
|
in this module",
|
||||||
token::get_name(name).get());
|
token::get_name(name).get());
|
||||||
@ -2933,6 +3067,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) | None => {}
|
Some(_) | None => {}
|
||||||
@ -2941,8 +3076,8 @@ impl<'a> Resolver<'a> {
|
|||||||
match import_resolution.type_target {
|
match import_resolution.type_target {
|
||||||
Some(ref target) if !target.shadowable => {
|
Some(ref target) if !target.shadowable => {
|
||||||
match *name_bindings.type_def.borrow() {
|
match *name_bindings.type_def.borrow() {
|
||||||
None => {}
|
// We want to allow the "flat" def of enum variants to be shadowed
|
||||||
Some(ref ty) => {
|
Some(ref ty) if !ty.modifiers.contains(ENUM_STAGING_HACK) => {
|
||||||
match ty.module_def {
|
match ty.module_def {
|
||||||
None => {
|
None => {
|
||||||
let msg = format!("import `{}` conflicts with type in \
|
let msg = format!("import `{}` conflicts with type in \
|
||||||
@ -2993,6 +3128,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) | None => {}
|
Some(_) | None => {}
|
||||||
@ -3131,43 +3267,28 @@ impl<'a> Resolver<'a> {
|
|||||||
return Failed(Some((span, msg)));
|
return Failed(Some((span, msg)));
|
||||||
}
|
}
|
||||||
Some(ref module_def) => {
|
Some(ref module_def) => {
|
||||||
// If we're doing the search for an
|
search_module = module_def.clone();
|
||||||
// import, do not allow traits and impls
|
|
||||||
// to be selected.
|
// track extern crates for unused_extern_crate lint
|
||||||
match (name_search_type,
|
match module_def.def_id.get() {
|
||||||
module_def.kind.get()) {
|
Some(did) => {
|
||||||
(ImportSearch, TraitModuleKind) |
|
self.used_crates.insert(did.krate);
|
||||||
(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_crates lint
|
// Keep track of the closest
|
||||||
match module_def.def_id.get() {
|
// private module used when
|
||||||
Some(did) => {
|
// resolving this import chain.
|
||||||
self.used_crates.insert(did.krate);
|
if !used_proxy &&
|
||||||
}
|
!search_module.is_public {
|
||||||
_ => {}
|
match search_module.def_id
|
||||||
}
|
.get() {
|
||||||
|
Some(did) => {
|
||||||
// Keep track of the closest
|
closest_private =
|
||||||
// private module used when
|
LastMod(DependsOn(did));
|
||||||
// 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 => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3388,6 +3509,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
TraitModuleKind |
|
TraitModuleKind |
|
||||||
ImplModuleKind |
|
ImplModuleKind |
|
||||||
|
EnumModuleKind |
|
||||||
AnonymousModuleKind => {
|
AnonymousModuleKind => {
|
||||||
search_module = parent_module_node.upgrade().unwrap();
|
search_module = parent_module_node.upgrade().unwrap();
|
||||||
}
|
}
|
||||||
@ -3485,6 +3607,7 @@ impl<'a> Resolver<'a> {
|
|||||||
NormalModuleKind => return Some(new_module),
|
NormalModuleKind => return Some(new_module),
|
||||||
TraitModuleKind |
|
TraitModuleKind |
|
||||||
ImplModuleKind |
|
ImplModuleKind |
|
||||||
|
EnumModuleKind |
|
||||||
AnonymousModuleKind => module_ = new_module,
|
AnonymousModuleKind => module_ = new_module,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3500,6 +3623,7 @@ impl<'a> Resolver<'a> {
|
|||||||
NormalModuleKind => return module_,
|
NormalModuleKind => return module_,
|
||||||
TraitModuleKind |
|
TraitModuleKind |
|
||||||
ImplModuleKind |
|
ImplModuleKind |
|
||||||
|
EnumModuleKind |
|
||||||
AnonymousModuleKind => {
|
AnonymousModuleKind => {
|
||||||
match self.get_nearest_normal_module_parent(module_.clone()) {
|
match self.get_nearest_normal_module_parent(module_.clone()) {
|
||||||
None => module_,
|
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
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
pub use self::sub::Bar;
|
pub use self::sub::{Bar, Baz};
|
||||||
|
|
||||||
pub trait Trait {
|
pub trait Trait {
|
||||||
fn foo();
|
fn foo();
|
||||||
@ -26,4 +26,10 @@ mod sub {
|
|||||||
impl Bar {
|
impl Bar {
|
||||||
pub fn new() {}
|
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`
|
enum Foo { //~ ERROR duplicate definition of type or module `Foo`
|
||||||
X
|
X //~ ERROR duplicate definition of value `X`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
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;
|
extern crate use_from_trait_xc;
|
||||||
|
|
||||||
use use_from_trait_xc::Trait::foo;
|
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;
|
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;
|
use use_from_trait_xc::Bar::new as bnew;
|
||||||
//~^ ERROR unresolved import `use_from_trait_xc::Bar::new`. Cannot import from a trait or type
|
//~^ ERROR `bnew` is not directly importable
|
||||||
|
|
||||||
|
use use_from_trait_xc::Baz::new as baznew;
|
||||||
|
//~^ ERROR `baznew` is not directly importable
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use Trait::foo;
|
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;
|
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 {
|
pub trait Trait {
|
||||||
fn foo();
|
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…
Reference in New Issue
Block a user