diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index dec8ea8a29c39..8b9cee1d2f6d6 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -13,34 +13,46 @@ use util::nodemap::NodeMap; use syntax::ast; use hir; +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum CtorKind { + // Constructor function automatically created by a tuple struct/variant. + Fn, + // Constructor constant automatically created by a unit struct/variant. + Const, + // Unusable name in value namespace created by a struct variant. + Fictive, +} + #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Def { - Fn(DefId), - SelfTy(Option /* trait */, Option /* impl */), + // Type namespace Mod(DefId), - Static(DefId, bool /* is_mutbl */), - Const(DefId), - AssociatedConst(DefId), - Local(DefId), - Variant(DefId), + Struct(DefId), // DefId refers to NodeId of the struct itself + Union(DefId), Enum(DefId), + Variant(DefId), + Trait(DefId), TyAlias(DefId), AssociatedTy(DefId), - Trait(DefId), PrimTy(hir::PrimTy), TyParam(DefId), - Upvar(DefId, // def id of closed over local - usize, // index in the freevars list of the closure - ast::NodeId), // expr node that creates the closure + SelfTy(Option /* trait */, Option /* impl */), - // If Def::Struct lives in type namespace it denotes a struct item and its DefId refers - // to NodeId of the struct itself. - // If Def::Struct lives in value namespace (e.g. tuple struct, unit struct expressions) - // it denotes a constructor and its DefId refers to NodeId of the struct's constructor. - Struct(DefId), - Union(DefId), - Label(ast::NodeId), + // Value namespace + Fn(DefId), + Const(DefId), + Static(DefId, bool /* is_mutbl */), + StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor + VariantCtor(DefId, CtorKind), Method(DefId), + AssociatedConst(DefId), + Local(DefId), + Upvar(DefId, // def id of closed over local + usize, // index in the freevars list of the closure + ast::NodeId), // expr node that creates the closure + Label(ast::NodeId), + + // Both namespaces Err, } @@ -93,18 +105,35 @@ pub type ExportMap = NodeMap>; #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] pub struct Export { - pub name: ast::Name, // The name of the target. - pub def_id: DefId, // The definition of the target. + pub name: ast::Name, // The name of the target. + pub def: Def, // The definition of the target. +} + +impl CtorKind { + pub fn from_ast(vdata: &ast::VariantData) -> CtorKind { + match *vdata { + ast::VariantData::Tuple(..) => CtorKind::Fn, + ast::VariantData::Unit(..) => CtorKind::Const, + ast::VariantData::Struct(..) => CtorKind::Fictive, + } + } + pub fn from_hir(vdata: &hir::VariantData) -> CtorKind { + match *vdata { + hir::VariantData::Tuple(..) => CtorKind::Fn, + hir::VariantData::Unit(..) => CtorKind::Const, + hir::VariantData::Struct(..) => CtorKind::Fictive, + } + } } impl Def { pub fn def_id(&self) -> DefId { match *self { Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) | - Def::Variant(id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(id) | - Def::TyParam(id) | Def::Struct(id) | Def::Union(id) | Def::Trait(id) | - Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | - Def::Local(id) | Def::Upvar(id, ..) => { + Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) | + Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) | + Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) | + Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) => { id } @@ -123,10 +152,16 @@ impl Def { Def::Mod(..) => "module", Def::Static(..) => "static", Def::Variant(..) => "variant", + Def::VariantCtor(.., CtorKind::Fn) => "tuple variant", + Def::VariantCtor(.., CtorKind::Const) => "unit variant", + Def::VariantCtor(.., CtorKind::Fictive) => "struct variant", Def::Enum(..) => "enum", - Def::TyAlias(..) => "type", + Def::TyAlias(..) => "type alias", Def::AssociatedTy(..) => "associated type", Def::Struct(..) => "struct", + Def::StructCtor(.., CtorKind::Fn) => "tuple struct", + Def::StructCtor(.., CtorKind::Const) => "unit struct", + Def::StructCtor(.., CtorKind::Fictive) => bug!("impossible struct constructor"), Def::Union(..) => "union", Def::Trait(..) => "trait", Def::Method(..) => "method", diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dace486b277db..f56a27b9ae04a 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -44,8 +44,9 @@ use hir; use hir::map::Definitions; use hir::map::definitions::DefPathData; use hir::def_id::{DefIndex, DefId}; -use hir::def::{Def, PathResolution}; +use hir::def::{Def, CtorKind, PathResolution}; use session::Session; +use lint; use std::collections::BTreeMap; use std::iter; @@ -855,10 +856,23 @@ impl<'a> LoweringContext<'a> { }) } PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)), - PatKind::TupleStruct(ref pth, ref pats, ddpos) => { - hir::PatKind::TupleStruct(self.lower_path(pth), - pats.iter().map(|x| self.lower_pat(x)).collect(), - ddpos) + PatKind::TupleStruct(ref path, ref pats, ddpos) => { + match self.resolver.get_resolution(p.id).map(|d| d.base_def) { + Some(def @ Def::StructCtor(_, CtorKind::Const)) | + Some(def @ Def::VariantCtor(_, CtorKind::Const)) => { + // Temporarily lower `UnitVariant(..)` into `UnitVariant` + // for backward compatibility. + let msg = format!("expected tuple struct/variant, found {} `{}`", + def.kind_name(), path); + self.sess.add_lint( + lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT, + p.id, p.span, msg + ); + hir::PatKind::Path(None, self.lower_path(path)) + } + _ => hir::PatKind::TupleStruct(self.lower_path(path), + pats.iter().map(|x| self.lower_pat(x)).collect(), ddpos) + } } PatKind::Path(ref opt_qself, ref path) => { let opt_qself = opt_qself.as_ref().map(|qself| { diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 505d126db7f4f..0deea94146361 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -58,7 +58,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { PatKind::Path(..) | PatKind::Struct(..) => { match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Variant(..)) => true, + Some(Def::Variant(..)) | Some(Def::VariantCtor(..)) => true, _ => false } } @@ -173,10 +173,9 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec { PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Struct(..) => { - match dm.get(&p.id) { - Some(&PathResolution { base_def: Def::Variant(id), .. }) => { - variants.push(id); - } + match dm.get(&p.id).map(|d| d.full_def()) { + Some(Def::Variant(id)) | + Some(Def::VariantCtor(id, ..)) => variants.push(id), _ => () } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index be91b86dbcc95..dfd6256c35773 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -201,8 +201,6 @@ pub trait CrateStore<'tcx> { -> Option; fn def_key(&self, def: DefId) -> hir_map::DefKey; fn relative_def_path(&self, def: DefId) -> Option; - fn variant_kind(&self, def_id: DefId) -> Option; - fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option; fn struct_field_names(&self, def: DefId) -> Vec; fn item_children(&self, did: DefId) -> Vec; @@ -378,9 +376,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn relative_def_path(&self, def: DefId) -> Option { bug!("relative_def_path") } - fn variant_kind(&self, def_id: DefId) -> Option { bug!("variant_kind") } - fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option - { bug!("struct_ctor_def_id") } fn struct_field_names(&self, def: DefId) -> Vec { bug!("struct_field_names") } fn item_children(&self, did: DefId) -> Vec { bug!("item_children") } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 30a0c6a9dc939..dc634b08784a4 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -106,9 +106,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { self.check_def_id(def.def_id()); } _ if self.ignore_non_const_paths => (), - Def::PrimTy(_) => (), - Def::SelfTy(..) => (), - Def::Variant(variant_id) => { + Def::PrimTy(..) | Def::SelfTy(..) => (), + Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { if let Some(enum_id) = self.tcx.parent_def_id(variant_id) { self.check_def_id(enum_id); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index d7392338d5ed9..799c02b740310 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1003,7 +1003,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // the leaves of the pattern tree structure. return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| { match tcx.expect_def_or_none(pat.id) { - Some(Def::Variant(variant_did)) => { + Some(Def::Variant(variant_did)) | + Some(Def::VariantCtor(variant_did, ..)) => { let enum_did = tcx.parent_def_id(variant_did).unwrap(); let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() { cmt_pat @@ -1015,12 +1016,14 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat); delegate.matched_pat(pat, downcast_cmt, match_mode); } - Some(Def::Struct(..)) | Some(Def::Union(..)) | + Some(Def::Struct(..)) | Some(Def::StructCtor(..)) | Some(Def::Union(..)) | Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => { debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat); delegate.matched_pat(pat, cmt_pat, match_mode); } - _ => {} + None | Some(Def::Local(..)) | + Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {} + def => bug!("unexpected definition: {:?}", def) } })); } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c50e668a41794..9214138d21077 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -74,7 +74,7 @@ use hir::def_id::DefId; use hir::map as ast_map; use infer::InferCtxt; use middle::const_qualif::ConstQualif; -use hir::def::Def; +use hir::def::{Def, CtorKind}; use ty::adjustment; use ty::{self, Ty, TyCtxt}; @@ -524,20 +524,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { id, expr_ty, def); match def { - Def::Struct(..) | Def::Union(..) | Def::Variant(..) | Def::Const(..) | + Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) | Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) => { Ok(self.cat_rvalue_node(id, span, expr_ty)) } - Def::Mod(_) | - Def::Trait(_) | Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(_) | - Def::TyParam(..) | - Def::Label(_) | Def::SelfTy(..) | - Def::AssociatedTy(..) => { - span_bug!(span, "Unexpected definition in \ - memory categorization: {:?}", def); - } - Def::Static(_, mutbl) => { Ok(Rc::new(cmt_ { id:id, @@ -598,7 +589,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { })) } - Def::Err => bug!("Def::Err in memory categorization") + def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def) } } @@ -1077,7 +1068,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // alone) because PatKind::Struct can also refer to variants. let cmt = match self.tcx().expect_def_or_none(pat.id) { Some(Def::Err) => return Err(()), - Some(Def::Variant(variant_did)) => { + Some(Def::Variant(variant_did)) | + Some(Def::VariantCtor(variant_did, ..)) => { // univariant enums do not need downcasts let enum_did = self.tcx().parent_def_id(variant_did).unwrap(); if !self.tcx().lookup_adt_def(enum_did).is_univariant() { @@ -1092,11 +1084,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { match pat.node { PatKind::TupleStruct(_, ref subpats, ddpos) => { let expected_len = match self.tcx().expect_def(pat.id) { - Def::Variant(def_id) => { + Def::VariantCtor(def_id, CtorKind::Fn) => { let enum_def = self.tcx().parent_def_id(def_id).unwrap(); self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len() } - Def::Struct(..) => { + Def::StructCtor(_, CtorKind::Fn) => { match self.pat_ty(&pat)?.sty { ty::TyAdt(adt_def, _) => { adt_def.struct_variant().fields.len() diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ccab4279232b5..5192575972b02 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -617,12 +617,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, &Option)) { // Paths in import prefixes may have no resolution. match tcx.expect_def_or_none(id) { - Some(Def::PrimTy(..)) => {} - Some(Def::SelfTy(..)) => {} - Some(def) => { - maybe_do_stability_check(tcx, def.def_id(), path.span, cb); - } - None => {} + None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => {} + Some(def) => maybe_do_stability_check(tcx, def.def_id(), path.span, cb) } } @@ -631,12 +627,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option)) { - match tcx.expect_def(item.node.id) { - Def::PrimTy(..) => {} - def => { - maybe_do_stability_check(tcx, def.def_id(), item.span, cb); - } - } + maybe_do_stability_check(tcx, tcx.expect_def(item.node.id).def_id(), item.span, cb); } pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat, diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index f11dc3740da66..fa899c4026955 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -15,6 +15,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators}; use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors}; use rustc_data_structures::control_flow_graph::ControlFlowGraph; +use hir::def::CtorKind; use hir::def_id::DefId; use ty::subst::Substs; use ty::{self, AdtDef, ClosureSubsts, Region, Ty}; @@ -1140,10 +1141,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { ppaux::parameterized(fmt, substs, variant_def.did, ppaux::Ns::Value, &[])?; - match variant_def.kind { - ty::VariantKind::Unit => Ok(()), - ty::VariantKind::Tuple => fmt_tuple(fmt, lvs), - ty::VariantKind::Struct => { + match variant_def.ctor_kind { + CtorKind::Const => Ok(()), + CtorKind::Fn => fmt_tuple(fmt, lvs), + CtorKind::Fictive => { let mut struct_fmt = fmt.debug_struct(""); for (field, lv) in variant_def.fields.iter().zip(lvs) { struct_fmt.field(&field.name.as_str(), lv); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 130b05504a513..8e330ee8e824c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -20,7 +20,7 @@ pub use self::fold::TypeFoldable; use dep_graph::{self, DepNode}; use hir::map as ast_map; use middle; -use hir::def::{Def, PathResolution, ExportMap}; +use hir::def::{Def, CtorKind, PathResolution, ExportMap}; use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; @@ -1420,7 +1420,7 @@ pub struct VariantDefData<'tcx, 'container: 'tcx> { pub name: Name, // struct's name if this is a struct pub disr_val: Disr, pub fields: Vec>, - pub kind: VariantKind, + pub ctor_kind: CtorKind, } pub struct FieldDefData<'tcx, 'container: 'tcx> { @@ -1485,19 +1485,6 @@ impl<'tcx> serialize::UseSpecializedDecodable for AdtDef<'tcx> {} #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum AdtKind { Struct, Union, Enum } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] -pub enum VariantKind { Struct, Tuple, Unit } - -impl VariantKind { - pub fn from_variant_data(vdata: &hir::VariantData) -> Self { - match *vdata { - hir::VariantData::Struct(..) => VariantKind::Struct, - hir::VariantData::Tuple(..) => VariantKind::Tuple, - hir::VariantData::Unit(..) => VariantKind::Unit, - } - } -} - impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> { fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, did: DefId, @@ -1673,8 +1660,8 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> { pub fn variant_of_def(&self, def: Def) -> &VariantDefData<'gcx, 'container> { match def { - Def::Variant(vid) => self.variant_with_id(vid), - Def::Struct(..) | Def::Union(..) | + Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid), + Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => self.struct_variant(), _ => bug!("unexpected def {:?} in variant_of_def", def) } @@ -2332,11 +2319,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // or variant or their constructors, panics otherwise. pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> { match def { - Def::Variant(did) => { + Def::Variant(did) | Def::VariantCtor(did, ..) => { let enum_did = self.parent_def_id(did).unwrap(); self.lookup_adt_def(enum_did).variant_with_id(did) } - Def::Struct(did) | Def::Union(did) => { + Def::Struct(did) | Def::StructCtor(did, ..) | Def::Union(did) => { self.lookup_adt_def(did).struct_variant() } _ => bug!("expect_variant_def used with unexpected def {:?}", def) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 5178ef65cf6a4..cf54f5908ca9e 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -247,7 +247,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) if edef.is_enum() { if let Def::Local(..) = cx.tcx.expect_def(p.id) { if edef.variants.iter().any(|variant| { - variant.name == name.node && variant.kind == ty::VariantKind::Unit + variant.name == name.node && variant.ctor_kind == CtorKind::Const }) { let ty_path = cx.tcx.item_path_str(edef.did); let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, @@ -577,8 +577,8 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor, ty::TyAdt(adt, _) => { let v = ctor.variant_for_adt(adt); - match v.kind { - ty::VariantKind::Struct => { + match v.ctor_kind { + CtorKind::Fictive => { let field_pats: hir::HirVec<_> = v.fields.iter() .zip(pats) .filter(|&(_, ref pat)| pat.node != PatKind::Wild) @@ -593,10 +593,10 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor, let has_more_fields = field_pats.len() < pats_len; PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields) } - ty::VariantKind::Tuple => { + CtorKind::Fn => { PatKind::TupleStruct(def_to_path(cx.tcx, v.did), pats.collect(), None) } - ty::VariantKind::Unit => { + CtorKind::Const => { PatKind::Path(None, def_to_path(cx.tcx, v.did)) } } @@ -801,8 +801,8 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, match pat.node { PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => match cx.tcx.expect_def(pat.id) { - Def::Variant(id) => vec![Variant(id)], - Def::Struct(..) | Def::Union(..) | + Def::Variant(id) | Def::VariantCtor(id, ..) => vec![Variant(id)], + Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => vec![Single], Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat.span, "const pattern should've been rewritten"), @@ -913,10 +913,10 @@ pub fn specialize<'a, 'b, 'tcx>( Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat_span, "const pattern should've \ been rewritten"), - Def::Variant(id) if *constructor != Variant(id) => None, - Def::Variant(..) | Def::Struct(..) => Some(Vec::new()), - def => span_bug!(pat_span, "specialize: unexpected \ - definition {:?}", def), + Def::VariantCtor(id, CtorKind::Const) if *constructor != Variant(id) => None, + Def::VariantCtor(_, CtorKind::Const) | + Def::StructCtor(_, CtorKind::Const) => Some(Vec::new()), + def => span_bug!(pat_span, "specialize: unexpected definition: {:?}", def), } } @@ -925,8 +925,9 @@ pub fn specialize<'a, 'b, 'tcx>( Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat_span, "const pattern should've \ been rewritten"), - Def::Variant(id) if *constructor != Variant(id) => None, - Def::Variant(..) | Def::Struct(..) => { + Def::VariantCtor(id, CtorKind::Fn) if *constructor != Variant(id) => None, + Def::VariantCtor(_, CtorKind::Fn) | + Def::StructCtor(_, CtorKind::Fn) => { match ddpos { Some(ddpos) => { let mut pats: Vec<_> = args[..ddpos].iter().map(|p| { @@ -939,7 +940,7 @@ pub fn specialize<'a, 'b, 'tcx>( None => Some(args.iter().map(|p| wpat(p)).collect()) } } - _ => None + def => span_bug!(pat_span, "specialize: unexpected definition: {:?}", def), } } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 3bf936dc9960c..d876b4b6fec2e 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -19,7 +19,7 @@ use rustc::hir::map as ast_map; use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::cstore::InlinedItem; use rustc::traits; -use rustc::hir::def::{Def, PathResolution}; +use rustc::hir::def::{Def, CtorKind, PathResolution}; use rustc::hir::def_id::DefId; use rustc::hir::pat_util::def_to_path; use rustc::ty::{self, Ty, TyCtxt}; @@ -287,8 +287,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, entry.insert(PathResolution::new(def)); } let path = match def { - Def::Struct(def_id) => def_to_path(tcx, def_id), - Def::Variant(variant_did) => def_to_path(tcx, variant_did), + Def::StructCtor(def_id, CtorKind::Fn) | + Def::VariantCtor(def_id, CtorKind::Fn) => def_to_path(tcx, def_id), Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat { id: expr.id, node: PatKind::Lit(P(expr.clone())), @@ -326,7 +326,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir::ExprPath(_, ref path) => { match tcx.expect_def(expr.id) { - Def::Struct(..) | Def::Variant(..) => PatKind::Path(None, path.clone()), + Def::StructCtor(_, CtorKind::Const) | + Def::VariantCtor(_, CtorKind::Const) => PatKind::Path(None, path.clone()), Def::Const(def_id) | Def::AssociatedConst(def_id) => { let substs = Some(tcx.node_id_item_substs(expr.id).substs); let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap(); @@ -807,7 +808,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, signal!(e, NonConstPath); } }, - Def::Variant(variant_def) => { + Def::VariantCtor(variant_def, ..) => { if let Some(const_expr) = lookup_variant_by_id(tcx, variant_def) { match eval_const_expr_partial(tcx, const_expr, ty_hint, None) { Ok(val) => val, @@ -820,7 +821,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, signal!(e, UnimplementedConstVal("enum variants")); } } - Def::Struct(..) => { + Def::StructCtor(..) => { ConstVal::Struct(e.id) } Def::Local(def_id) => { diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 4d1744fa70fce..393f99b3eb832 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -611,11 +611,13 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { Def::Mod(..) | Def::Static(..) | Def::Variant(..) | + Def::VariantCtor(..) | Def::Enum(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::TyParam(..) | Def::Struct(..) | + Def::StructCtor(..) | Def::Union(..) | Def::Trait(..) | Def::Method(..) | diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 16a5b5402fbe3..54664b9c04046 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -149,7 +149,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.dep_graph.read(DepNode::MetaData(def_id)); let mut result = vec![]; self.get_crate_data(def_id.krate) - .each_child_of_item(def_id.index, |child| result.push(child.def_id)); + .each_child_of_item(def_id.index, |child| result.push(child.def.def_id())); result } @@ -342,18 +342,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def.krate).def_path(def.index) } - fn variant_kind(&self, def_id: DefId) -> Option - { - self.dep_graph.read(DepNode::MetaData(def_id)); - self.get_crate_data(def_id.krate).get_variant_kind(def_id.index) - } - - fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option - { - self.dep_graph.read(DepNode::MetaData(struct_def_id)); - self.get_crate_data(struct_def_id.krate).get_struct_ctor_def_id(struct_def_id.index) - } - fn struct_field_names(&self, def: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def)); @@ -566,7 +554,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { let mut bfs_queue = &mut VecDeque::new(); let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| { - let child = child.def_id; + let child = child.def.def_id(); if self.visibility(child) != ty::Visibility::Public { return; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 3e4a2542b270b..579a97138f250 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -22,7 +22,7 @@ use rustc::hir; use rustc::hir::intravisit::IdRange; use rustc::middle::cstore::{InlinedItem, LinkagePreference}; -use rustc::hir::def::{self, Def}; +use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use rustc::middle::lang_items; use rustc::ty::{self, Ty, TyCtxt}; @@ -534,7 +534,7 @@ impl<'a, 'tcx> CrateMetadata { name: self.item_name(item), fields: fields, disr_val: ConstInt::Infer(data.disr), - kind: data.kind, + ctor_kind: data.ctor_kind, }, data.struct_ctor) } @@ -670,10 +670,12 @@ impl<'a, 'tcx> CrateMetadata { // FIXME(eddyb) Don't encode these in children. EntryKind::ForeignMod => { for child_index in child.children.decode(self) { - callback(def::Export { - def_id: self.local_def_id(child_index), - name: self.item_name(&self.entry(child_index)) - }); + if let Some(def) = self.get_def(child_index) { + callback(def::Export { + def: def, + name: self.item_name(&self.entry(child_index)) + }); + } } continue; } @@ -683,11 +685,28 @@ impl<'a, 'tcx> CrateMetadata { } let def_key = child.def_key.decode(self); - if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { - callback(def::Export { - def_id: self.local_def_id(child_index), - name: name - }); + if let (Some(def), Some(name)) = (self.get_def(child_index), + def_key.disambiguated_data.data.get_opt_name()) { + callback(def::Export { def: def, name: name }); + // For non-reexport structs and variants add their constructors to children. + // Reexport lists automatically contain constructors when necessary. + match def { + Def::Struct(..) => { + if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) { + let ctor_kind = self.get_ctor_kind(child_index); + let ctor_def = Def::StructCtor(ctor_def_id, ctor_kind); + callback(def::Export { def: ctor_def, name: name }); + } + } + Def::Variant(def_id) => { + // Braced variants, unlike structs, generate unusable names in + // value namespace, they are reserved for possible future use. + let ctor_kind = self.get_ctor_kind(child_index); + let ctor_def = Def::VariantCtor(def_id, ctor_kind); + callback(def::Export { def: ctor_def, name: name }); + } + _ => {} + } } } } @@ -787,12 +806,12 @@ impl<'a, 'tcx> CrateMetadata { self.entry(id).variances.decode(self).collect() } - pub fn get_variant_kind(&self, node_id: DefIndex) -> Option { + pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind { match self.entry(node_id).kind { EntryKind::Struct(data) | EntryKind::Union(data) | - EntryKind::Variant(data) => Some(data.decode(self).kind), - _ => None + EntryKind::Variant(data) => data.decode(self).ctor_kind, + _ => CtorKind::Fictive, } } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 4d18462848e5d..3b6c20040d09c 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -258,7 +258,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_id = variant.did; let data = VariantData { - kind: variant.kind, + ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), struct_ctor: None }; @@ -406,17 +406,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> { - let variant = self.tcx.lookup_adt_def(adt_def_id).struct_variant(); + let tcx = self.tcx; + let variant = tcx.lookup_adt_def(adt_def_id).struct_variant(); let data = VariantData { - kind: variant.kind, + ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), struct_ctor: Some(def_id.index) }; + let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap(); + let struct_vis = &tcx.map.expect_item(struct_id).vis; + Entry { kind: EntryKind::Struct(self.lazy(&data)), - visibility: ty::Visibility::Public, + visibility: struct_vis.simplify(), def_key: self.encode_def_key(def_id), attributes: LazySeq::empty(), children: LazySeq::empty(), @@ -671,7 +675,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { None }; EntryKind::Struct(self.lazy(&VariantData { - kind: variant.kind, + ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), struct_ctor: struct_ctor })) @@ -680,7 +684,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let variant = tcx.lookup_adt_def(def_id).struct_variant(); EntryKind::Union(self.lazy(&VariantData { - kind: variant.kind, + ctor_kind: variant.ctor_kind, disr: variant.disr_val.to_u64_unchecked(), struct_ctor: None })) @@ -885,19 +889,12 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { hir::ItemStruct(ref struct_def, _) => { self.encode_fields(def_id); - // If this is a tuple-like struct, encode the type of the constructor. - match self.tcx.lookup_adt_def(def_id).struct_variant().kind { - ty::VariantKind::Struct => { - // no value for structs like struct Foo { ... } - } - ty::VariantKind::Tuple | ty::VariantKind::Unit => { - // there is a value for structs like `struct - // Foo()` and `struct Foo` - let ctor_def_id = self.tcx.map.local_def_id(struct_def.id()); - self.record(ctor_def_id, - EncodeContext::encode_struct_ctor, - (def_id, ctor_def_id)); - } + // If the struct has a constructor, encode it. + if !struct_def.is_struct() { + let ctor_def_id = self.tcx.map.local_def_id(struct_def.id()); + self.record(ctor_def_id, + EncodeContext::encode_struct_ctor, + (def_id, ctor_def_id)); } } hir::ItemUnion(..) => { diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 1a46315e9cd7a..0bb126ee0ffb6 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -12,7 +12,7 @@ use astencode; use index; use rustc::hir; -use rustc::hir::def; +use rustc::hir::def::{self, CtorKind}; use rustc::hir::def_id::{DefIndex, DefId}; use rustc::middle::cstore::{LinkagePreference, NativeLibraryKind}; use rustc::middle::lang_items; @@ -261,7 +261,7 @@ pub struct FnData { #[derive(RustcEncodable, RustcDecodable)] pub struct VariantData { - pub kind: ty::VariantKind, + pub ctor_kind: CtorKind, pub disr: u64, /// If this is a struct's only variant, this diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 2840538ae5b4f..a6c5cd1eeeaa7 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -15,7 +15,7 @@ use hair::cx::Cx; use hair::cx::block; use hair::cx::to_ref::ToRef; use rustc::hir::map; -use rustc::hir::def::Def; +use rustc::hir::def::{Def, CtorKind}; use rustc::middle::const_val::ConstVal; use rustc_const_eval as const_eval; use rustc::middle::region::CodeExtent; @@ -271,10 +271,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Tuple-like ADTs are represented as ExprCall. We convert them here. expr_ty.ty_adt_def().and_then(|adt_def|{ match cx.tcx.expect_def(fun.id) { - Def::Variant(variant_id) => { + Def::VariantCtor(variant_id, CtorKind::Fn) => { Some((adt_def, adt_def.variant_index_with_id(variant_id))) }, - Def::Struct(..) => { + Def::StructCtor(_, CtorKind::Fn) => { Some((adt_def, 0)) }, _ => None @@ -670,42 +670,25 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Otherwise there may be def_map borrow conflicts let def = cx.tcx.expect_def(expr.id); let def_id = match def { - // A regular function. - Def::Fn(def_id) | Def::Method(def_id) => def_id, - Def::Struct(def_id) => match cx.tcx.node_id_to_type(expr.id).sty { - // A tuple-struct constructor. Should only be reached if not called in the same - // expression. - ty::TyFnDef(..) => def_id, - // A unit struct which is used as a value. We return a completely different ExprKind - // here to account for this special case. + // A regular function, constructor function or a constant. + Def::Fn(def_id) | Def::Method(def_id) | + Def::StructCtor(def_id, CtorKind::Fn) | + Def::VariantCtor(def_id, CtorKind::Fn) | + Def::Const(def_id) | Def::AssociatedConst(def_id) => def_id, + + Def::StructCtor(def_id, CtorKind::Const) | + Def::VariantCtor(def_id, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty { + // A unit struct/variant which is used as a value. + // We return a completely different ExprKind here to account for this special case. ty::TyAdt(adt_def, substs) => return ExprKind::Adt { adt_def: adt_def, - variant_index: 0, + variant_index: adt_def.variant_index_with_id(def_id), substs: substs, fields: vec![], - base: None - }, - ref sty => bug!("unexpected sty: {:?}", sty) - }, - Def::Variant(variant_id) => match cx.tcx.node_id_to_type(expr.id).sty { - // A variant constructor. Should only be reached if not called in the same - // expression. - ty::TyFnDef(..) => variant_id, - // A unit variant, similar special case to the struct case above. - ty::TyAdt(adt_def, substs) => { - let index = adt_def.variant_index_with_id(variant_id); - return ExprKind::Adt { - adt_def: adt_def, - substs: substs, - variant_index: index, - fields: vec![], - base: None - }; + base: None, }, ref sty => bug!("unexpected sty: {:?}", sty) }, - Def::Const(def_id) | - Def::AssociatedConst(def_id) => def_id, Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id, diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index 8751b1dc03aab..84f415463be05 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -301,7 +301,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { subpatterns: Vec>) -> PatternKind<'tcx> { match self.cx.tcx.expect_def(pat.id) { - Def::Variant(variant_id) => { + Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { let enum_id = self.cx.tcx.parent_def_id(variant_id).unwrap(); let adt_def = self.cx.tcx.lookup_adt_def(enum_id); if adt_def.variants.len() > 1 { @@ -315,7 +315,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { } } - Def::Struct(..) | Def::Union(..) | + Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => { PatternKind::Leaf { subpatterns: subpatterns } } diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index 77af02c18c60e..198a6d256bcc3 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -12,7 +12,6 @@ use rustc::ty::TyCtxt; use rustc::mir::repr::*; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc_data_structures::indexed_vec::Idx; -use rustc::ty::VariantKind; pub struct Deaggregator; @@ -129,10 +128,7 @@ fn get_aggregate_statement_index<'a, 'tcx, 'b>(start: usize, } debug!("getting variant {:?}", variant); debug!("for adt_def {:?}", adt_def); - let variant_def = &adt_def.variants[variant]; - if variant_def.kind == VariantKind::Struct { - return Some(i); - } + return Some(i); }; None } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 1b86c84a05702..ee731dd042e4f 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -33,7 +33,7 @@ use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp, NonCo use rustc_const_eval::ErrKind::UnresolvedPath; use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_math::{ConstMathErr, Op}; -use rustc::hir::def::Def; +use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; @@ -489,20 +489,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } hir::ExprPath(..) => { match v.tcx.expect_def(e.id) { - Def::Variant(..) => { - // Count the discriminator or function pointer. - v.add_qualif(ConstQualif::NON_ZERO_SIZED); - } - Def::Struct(..) => { - if let ty::TyFnDef(..) = node_ty.sty { - // Count the function pointer. - v.add_qualif(ConstQualif::NON_ZERO_SIZED); - } - } - Def::Fn(..) | Def::Method(..) => { - // Count the function pointer. + Def::VariantCtor(_, CtorKind::Const) => { + // Size is determined by the whole enum, may be non-zero. v.add_qualif(ConstQualif::NON_ZERO_SIZED); } + Def::VariantCtor(..) | Def::StructCtor(..) | + Def::Fn(..) | Def::Method(..) => {} Def::Static(..) => { match v.mode { Mode::Static | Mode::StaticMut => {} @@ -539,9 +531,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } // The callee is an arbitrary expression, it doesn't necessarily have a definition. let is_const = match v.tcx.expect_def_or_none(callee.id) { - Some(Def::Struct(..)) => true, - Some(Def::Variant(..)) => { - // Count the discriminator. + Some(Def::StructCtor(_, CtorKind::Fn)) | + Some(Def::VariantCtor(_, CtorKind::Fn)) => { + // `NON_ZERO_SIZED` is about the call result, not about the ctor itself. v.add_qualif(ConstQualif::NON_ZERO_SIZED); true } diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 0336c3063d83f..0e0f8a8456731 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -14,7 +14,7 @@ use rustc::dep_graph::DepNode; use rustc::hir::map as ast_map; use rustc::session::{CompileResult, Session}; -use rustc::hir::def::{Def, DefMap}; +use rustc::hir::def::{Def, CtorKind, DefMap}; use rustc::util::nodemap::NodeMap; use syntax::ast; @@ -272,7 +272,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { // affect the specific variant used, but we need to check // the whole enum definition to see what expression that // might be (if any). - Some(Def::Variant(variant_id)) => { + Some(Def::VariantCtor(variant_id, CtorKind::Const)) => { if let Some(variant_id) = self.ast_map.as_local_node_id(variant_id) { let variant = self.ast_map.expect_variant(variant_id); let enum_id = self.ast_map.get_parent(variant_id); @@ -283,7 +283,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { } else { span_bug!(e.span, "`check_static_recursion` found \ - non-enum in Def::Variant"); + non-enum in Def::VariantCtor"); } } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 43cdf2942d230..4ffe2fe38566e 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -28,7 +28,7 @@ extern crate syntax_pos; use rustc::dep_graph::DepNode; use rustc::hir::{self, PatKind}; -use rustc::hir::def::{self, Def}; +use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; @@ -286,7 +286,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { if self.prev_level.is_some() { if let Some(exports) = self.export_map.get(&id) { for export in exports { - if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) { + if let Some(node_id) = self.tcx.map.as_local_node_id(export.def.def_id()) { self.update(node_id, Some(AccessLevel::Exported)); } } @@ -454,36 +454,25 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } } hir::ExprPath(..) => { - if let Def::Struct(..) = self.tcx.expect_def(expr.id) { - let expr_ty = self.tcx.expr_ty(expr); - let def = match expr_ty.sty { - ty::TyFnDef(.., &ty::BareFnTy { sig: ty::Binder(ty::FnSig { - output: ty, .. - }), ..}) => ty, - _ => expr_ty - }.ty_adt_def().unwrap(); - - let private_indexes : Vec<_> = def.struct_variant().fields.iter().enumerate() - .filter(|&(_,f)| { - !f.vis.is_accessible_from(self.curitem, &self.tcx.map) - }).map(|(n,&_)|n).collect(); + if let def @ Def::StructCtor(_, CtorKind::Fn) = self.tcx.expect_def(expr.id) { + let adt_def = self.tcx.expect_variant_def(def); + let private_indexes = adt_def.fields.iter().enumerate().filter(|&(_, field)| { + !field.vis.is_accessible_from(self.curitem, &self.tcx.map) + }).map(|(i, _)| i).collect::>(); if !private_indexes.is_empty() { - let mut error = struct_span_err!(self.tcx.sess, expr.span, E0450, "cannot invoke tuple struct constructor \ - with private fields"); + with private fields"); error.span_label(expr.span, &format!("cannot construct with a private field")); - if let Some(def_id) = self.tcx.map.as_local_node_id(def.did) { - if let Some(hir::map::NodeItem(node)) = self.tcx.map.find(def_id) { - if let hir::Item_::ItemStruct(ref tuple_data, _) = node.node { - - for i in private_indexes { - error.span_label(tuple_data.fields()[i].span, - &format!("private field declared here")); - } + if let Some(node_id) = self.tcx.map.as_local_node_id(adt_def.did) { + let node = self.tcx.map.find(node_id); + if let Some(hir::map::NodeStructCtor(vdata)) = node { + for i in private_indexes { + error.span_label(vdata.fields()[i].span, + &format!("private field declared here")); } } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0a0d2e4347e07..321b814238cfd 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -24,7 +24,6 @@ use {resolve_error, resolve_struct_error, ResolutionError}; use rustc::middle::cstore::LoadedMacroKind; use rustc::hir::def::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; -use rustc::hir::map::DefPathData; use rustc::ty; use std::cell::Cell; @@ -78,6 +77,12 @@ impl<'b> Resolver<'b> { }) } + fn insert_field_names(&mut self, def_id: DefId, field_names: Vec) { + if !field_names.is_empty() { + self.field_names.insert(def_id, field_names); + } + } + /// Constructs the reduced graph for one item. fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) { let parent = self.current_module; @@ -297,32 +302,31 @@ impl<'b> Resolver<'b> { // If this is a tuple or unit struct, define a name // in the value namespace as well. if !struct_def.is_struct() { - let def = Def::Struct(self.definitions.local_def_id(struct_def.id())); - self.define(parent, name, ValueNS, (def, sp, vis)); + let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()), + CtorKind::from_ast(struct_def)); + self.define(parent, name, ValueNS, (ctor_def, sp, vis)); } - // Record the def ID and fields of this struct. - let field_names = struct_def.fields().iter().enumerate().map(|(index, field)| { + // Record field names for error reporting. + let field_names = struct_def.fields().iter().filter_map(|field| { self.resolve_visibility(&field.vis); field.ident.map(|ident| ident.name) - .unwrap_or_else(|| token::intern(&index.to_string())) }).collect(); let item_def_id = self.definitions.local_def_id(item.id); - self.structs.insert(item_def_id, field_names); + self.insert_field_names(item_def_id, field_names); } ItemKind::Union(ref vdata, _) => { let def = Def::Union(self.definitions.local_def_id(item.id)); self.define(parent, name, TypeNS, (def, sp, vis)); - // Record the def ID and fields of this union. - let field_names = vdata.fields().iter().enumerate().map(|(index, field)| { + // Record field names for error reporting. + let field_names = vdata.fields().iter().filter_map(|field| { self.resolve_visibility(&field.vis); field.ident.map(|ident| ident.name) - .unwrap_or_else(|| token::intern(&index.to_string())) }).collect(); let item_def_id = self.definitions.local_def_id(item.id); - self.structs.insert(item_def_id, field_names); + self.insert_field_names(item_def_id, field_names); } ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => {} @@ -347,17 +351,18 @@ impl<'b> Resolver<'b> { parent: Module<'b>, vis: ty::Visibility) { let name = variant.node.name.name; - if variant.node.data.is_struct() { - // Not adding fields for variants as they are not accessed with a self receiver - let variant_def_id = self.definitions.local_def_id(variant.node.data.id()); - self.structs.insert(variant_def_id, Vec::new()); - } + let def_id = self.definitions.local_def_id(variant.node.data.id()); - // Variants are always treated as importable to allow them to be glob used. - // All variants are defined in both type and value namespaces as future-proofing. - let def = Def::Variant(self.definitions.local_def_id(variant.node.data.id())); - self.define(parent, name, ValueNS, (def, variant.span, vis)); + // Define a name in the type namespace. + let def = Def::Variant(def_id); self.define(parent, name, TypeNS, (def, variant.span, vis)); + + // Define a constructor name in the value namespace. + // Braced variants, unlike structs, generate unusable names in + // value namespace, they are reserved for possible future use. + let ctor_kind = CtorKind::from_ast(&variant.node.data); + let ctor_def = Def::VariantCtor(def_id, ctor_kind); + self.define(parent, name, ValueNS, (ctor_def, variant.span, vis)); } /// Constructs the reduced graph for one foreign item. @@ -395,15 +400,9 @@ impl<'b> Resolver<'b> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, child: Export) { - let def_id = child.def_id; let name = child.name; - - let def = if let Some(def) = self.session.cstore.describe_def(def_id) { - def - } else { - return; - }; - + let def = child.def; + let def_id = def.def_id(); let vis = if parent.is_trait() { ty::Visibility::Public } else { @@ -411,83 +410,56 @@ impl<'b> Resolver<'b> { }; match def { - Def::Mod(_) | Def::Enum(..) => { - debug!("(building reduced graph for external crate) building module {} {:?}", - name, vis); + Def::Mod(..) | Def::Enum(..) => { let module = self.new_module(parent, ModuleKind::Def(def, name), false); - let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis)); + self.define(parent, name, TypeNS, (module, DUMMY_SP, vis)); } - Def::Variant(variant_id) => { - debug!("(building reduced graph for external crate) building variant {}", name); - // Variants are always treated as importable to allow them to be glob used. - // All variants are defined in both type and value namespaces as future-proofing. - let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); - let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis)); - if self.session.cstore.variant_kind(variant_id) == Some(ty::VariantKind::Struct) { - // Not adding fields for variants as they are not accessed with a self receiver - self.structs.insert(variant_id, Vec::new()); - } + Def::Variant(..) => { + self.define(parent, name, TypeNS, (def, DUMMY_SP, vis)); + } + Def::VariantCtor(..) => { + self.define(parent, name, ValueNS, (def, DUMMY_SP, vis)); } Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::AssociatedConst(..) | Def::Method(..) => { - debug!("(building reduced graph for external crate) building value (fn/static) {}", - name); - let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis)); + self.define(parent, name, ValueNS, (def, DUMMY_SP, vis)); } - Def::Trait(_) => { - debug!("(building reduced graph for external crate) building type {}", name); - - // If this is a trait, add all the trait item names to the trait - // info. + Def::Trait(..) => { + let module = self.new_module(parent, ModuleKind::Def(def, name), false); + self.define(parent, name, TypeNS, (module, DUMMY_SP, vis)); + // If this is a trait, add all the trait item names to the trait info. let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id); - for &trait_item_def in &trait_item_def_ids { - let trait_item_name = - self.session.cstore.def_key(trait_item_def) - .disambiguated_data.data.get_opt_name() - .expect("opt_item_name returned None for trait"); - - debug!("(building reduced graph for external crate) ... adding trait item \ - '{}'", - trait_item_name); - + for trait_item_def_id in trait_item_def_ids { + let trait_item_name = self.session.cstore.def_key(trait_item_def_id) + .disambiguated_data.data.get_opt_name() + .expect("opt_item_name returned None for trait"); self.trait_item_map.insert((trait_item_name, def_id), false); } - - let module = self.new_module(parent, ModuleKind::Def(def, name), false); - let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis)); } Def::TyAlias(..) | Def::AssociatedTy(..) => { - debug!("(building reduced graph for external crate) building type {}", name); - let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); + self.define(parent, name, TypeNS, (def, DUMMY_SP, vis)); } - Def::Struct(_) - if self.session.cstore.def_key(def_id).disambiguated_data.data != - DefPathData::StructCtor - => { - debug!("(building reduced graph for external crate) building type and value for {}", - name); - let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); - if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) { - let def = Def::Struct(ctor_def_id); - let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis)); - } + Def::Struct(..) => { + self.define(parent, name, TypeNS, (def, DUMMY_SP, vis)); - // Record the def ID and fields of this struct. - let fields = self.session.cstore.struct_field_names(def_id); - self.structs.insert(def_id, fields); + // Record field names for error reporting. + let field_names = self.session.cstore.struct_field_names(def_id); + self.insert_field_names(def_id, field_names); + } + Def::StructCtor(..) => { + self.define(parent, name, ValueNS, (def, DUMMY_SP, vis)); } - Def::Union(_) => { - let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); + Def::Union(..) => { + self.define(parent, name, TypeNS, (def, DUMMY_SP, vis)); - // Record the def ID and fields of this union. - let fields = self.session.cstore.struct_field_names(def_id); - self.structs.insert(def_id, fields); + // Record field names for error reporting. + let field_names = self.session.cstore.struct_field_names(def_id); + self.insert_field_names(def_id, field_names); } - Def::Struct(..) => {} Def::Local(..) | Def::PrimTy(..) | Def::TyParam(..) | @@ -495,7 +467,7 @@ impl<'b> Resolver<'b> { Def::Label(..) | Def::SelfTy(..) | Def::Err => { - bug!("didn't expect `{:?}`", def); + bug!("unexpected definition: {:?}", def); } } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 90a9e5960617e..4f41dfc8b6455 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -485,7 +485,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, E0531, "unresolved {} `{}`", expected_what, - path.segments.last().unwrap().identifier) + path) } ResolutionError::PatPathUnexpected(expected_what, found_what, path) => { struct_span_err!(resolver.session, @@ -494,7 +494,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, "expected {}, found {} `{}`", expected_what, found_what, - path.segments.last().unwrap().identifier) + path) } } } @@ -924,7 +924,8 @@ impl<'a> NameBinding<'a> { fn is_variant(&self) -> bool { match self.kind { - NameBindingKind::Def(Def::Variant(..)) => true, + NameBindingKind::Def(Def::Variant(..)) | + NameBindingKind::Def(Def::VariantCtor(..)) => true, _ => false, } } @@ -1005,7 +1006,9 @@ pub struct Resolver<'a> { trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>, - structs: FnvHashMap>, + // Names of fields of an item `DefId` accessible with dot syntax. + // Used for hints during error reporting. + field_names: FnvHashMap>, // All imports known to succeed or fail. determined_imports: Vec<&'a ImportDirective<'a>>, @@ -1217,7 +1220,7 @@ impl<'a> Resolver<'a> { prelude: None, trait_item_map: FnvHashMap(), - structs: FnvHashMap(), + field_names: FnvHashMap(), determined_imports: Vec::new(), indeterminate_imports: Vec::new(), @@ -2373,15 +2376,16 @@ impl<'a> Resolver<'a> { let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || bmode != BindingMode::ByValue(Mutability::Immutable); match def { - Def::Struct(..) | Def::Variant(..) | - Def::Const(..) | Def::AssociatedConst(..) if !always_binding => { - // A constant, unit variant, etc pattern. + Def::StructCtor(_, CtorKind::Const) | + Def::VariantCtor(_, CtorKind::Const) | + Def::Const(..) if !always_binding => { + // A unit struct/variant or constant pattern. let name = ident.node.name; self.record_use(name, ValueNS, binding.unwrap(), ident.span); Some(PathResolution::new(def)) } - Def::Struct(..) | Def::Variant(..) | - Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => { + Def::StructCtor(..) | Def::VariantCtor(..) | + Def::Const(..) | Def::Static(..) => { // A fresh binding that shadows something unacceptable. resolve_error( self, @@ -2398,7 +2402,7 @@ impl<'a> Resolver<'a> { } def => { span_bug!(ident.span, "unexpected definition for an \ - identifier in pattern {:?}", def); + identifier in pattern: {:?}", def); } } }).unwrap_or_else(|| { @@ -2408,23 +2412,29 @@ impl<'a> Resolver<'a> { self.record_def(pat.id, resolution); } - PatKind::TupleStruct(ref path, ..) => { + PatKind::TupleStruct(ref path, ref pats, ddpos) => { self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| { match def { - Def::Struct(..) | Def::Variant(..) => true, + Def::StructCtor(_, CtorKind::Fn) | + Def::VariantCtor(_, CtorKind::Fn) => true, + // `UnitVariant(..)` is accepted for backward compatibility. + Def::StructCtor(_, CtorKind::Const) | + Def::VariantCtor(_, CtorKind::Const) + if pats.is_empty() && ddpos.is_some() => true, _ => false, } - }, "variant or struct"); + }, "tuple struct/variant"); } PatKind::Path(ref qself, ref path) => { self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| { match def { - Def::Struct(..) | Def::Variant(..) | + Def::StructCtor(_, CtorKind::Const) | + Def::VariantCtor(_, CtorKind::Const) | Def::Const(..) | Def::AssociatedConst(..) => true, _ => false, } - }, "variant, struct or constant"); + }, "unit struct/variant or constant"); } PatKind::Struct(ref path, ..) => { @@ -2776,10 +2786,9 @@ impl<'a> Resolver<'a> { // Look for a field with the same name in the current self_type. if let Some(resolution) = self.def_map.get(&node_id) { match resolution.base_def { - Def::Enum(did) | Def::TyAlias(did) | Def::Union(did) | - Def::Struct(did) | Def::Variant(did) if resolution.depth == 0 => { - if let Some(fields) = self.structs.get(&did) { - if fields.iter().any(|&field_name| name == field_name) { + Def::Struct(did) | Def::Union(did) if resolution.depth == 0 => { + if let Some(field_names) = self.field_names.get(&did) { + if field_names.iter().any(|&field_name| name == field_name) { return Field; } } @@ -2846,13 +2855,11 @@ impl<'a> Resolver<'a> { if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id, maybe_qself.as_ref(), path, ValueNS) { // Check if struct variant - let is_struct_variant = if let Def::Variant(variant_id) = path_res.base_def { - self.structs.contains_key(&variant_id) - } else { - false + let is_struct_variant = match path_res.base_def { + Def::VariantCtor(_, CtorKind::Fictive) => true, + _ => false, }; if is_struct_variant { - let _ = self.structs.contains_key(&path_res.base_def.def_id()); let path_name = path_names_to_string(path, 0); let mut err = resolve_struct_error(self, @@ -2885,9 +2892,6 @@ impl<'a> Resolver<'a> { } } else { // Be helpful if the name refers to a struct - // (The pattern matching def_tys where the id is in self.structs - // matches on regular structs while excluding tuple- and enum-like - // structs, which wouldn't result in this error.) let path_name = path_names_to_string(path, 0); let type_res = self.with_no_errors(|this| { this.resolve_path(expr.id, path, 0, TypeNS) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 1fc9c45de9306..4689c4ded5c0a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -797,7 +797,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { (binding.is_import() || binding.is_extern_crate()) { let def = binding.def(); if def != Def::Err { - reexports.push(Export { name: name, def_id: def.def_id() }); + reexports.push(Export { name: name, def: def }); } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 0869ad168bced..6d9cd88afb17b 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -271,12 +271,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } } - // looks up anything, not just a type - fn lookup_type_ref(&self, ref_id: NodeId) -> Option { + fn lookup_def_id(&self, ref_id: NodeId) -> Option { self.tcx.expect_def_or_none(ref_id).and_then(|def| { match def { - Def::PrimTy(..) => None, - Def::SelfTy(..) => None, + Def::PrimTy(..) | Def::SelfTy(..) => None, def => Some(def.def_id()), } }) @@ -303,10 +301,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { }.lower(self.tcx)); } Def::Struct(..) | + Def::Variant(..) | Def::Union(..) | Def::Enum(..) | Def::TyAlias(..) | - Def::AssociatedTy(..) | Def::Trait(_) => { self.dumper.type_ref(TypeRefData { span: sub_span.expect("No span found for type ref"), @@ -316,11 +314,9 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { }.lower(self.tcx)); } Def::Static(..) | - Def::Const(_) | - Def::AssociatedConst(..) | - Def::Local(..) | - Def::Variant(..) | - Def::Upvar(..) => { + Def::Const(..) | + Def::StructCtor(..) | + Def::VariantCtor(..) => { self.dumper.variable_ref(VariableRefData { span: sub_span.expect("No span found for var ref"), ref_id: def_id, @@ -335,10 +331,14 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { scope: scope }.lower(self.tcx)); } + Def::Local(..) | + Def::Upvar(..) | Def::SelfTy(..) | Def::Label(_) | Def::TyParam(..) | Def::Method(..) | + Def::AssociatedTy(..) | + Def::AssociatedConst(..) | Def::PrimTy(_) | Def::Err => { span_bug!(span, @@ -422,7 +422,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { None => { if let Some(NodeItem(item)) = self.tcx.map.get_if_local(id) { if let hir::ItemImpl(_, _, _, _, ref ty, _) = item.node { - trait_id = self.lookup_type_ref(ty.id); + trait_id = self.lookup_def_id(ty.id); } } } @@ -805,7 +805,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { }; let trait_ref = &trait_ref.trait_ref; - if let Some(id) = self.lookup_type_ref(trait_ref.ref_id) { + if let Some(id) = self.lookup_def_id(trait_ref.ref_id) { let sub_span = self.span.sub_span_for_type_name(trait_ref.path.span); if !self.span.filter_generated(sub_span, trait_ref.path.span) { self.dumper.type_ref(TypeRefData { @@ -924,13 +924,19 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } } } - Def::Local(..) | - Def::Static(..) | + Def::Fn(..) | Def::Const(..) | + Def::Static(..) | + Def::StructCtor(..) | + Def::VariantCtor(..) | Def::AssociatedConst(..) | + Def::Local(..) | + Def::Upvar(..) | Def::Struct(..) | + Def::Union(..) | Def::Variant(..) | - Def::Fn(..) => self.write_sub_paths_truncated(path, false), + Def::TyAlias(..) | + Def::AssociatedTy(..) => self.write_sub_paths_truncated(path, false), _ => {} } } @@ -1163,7 +1169,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> match use_item.node { ast::ViewPathSimple(ident, ref path) => { let sub_span = self.span.span_for_last_ident(path.span); - let mod_id = match self.lookup_type_ref(item.id) { + let mod_id = match self.lookup_def_id(item.id) { Some(def_id) => { let scope = self.cur_scope; self.process_def_kind(item.id, path.span, sub_span, def_id, scope); @@ -1221,7 +1227,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> for plid in list { let scope = self.cur_scope; let id = plid.node.id; - if let Some(def_id) = self.lookup_type_ref(id) { + if let Some(def_id) = self.lookup_def_id(id) { let span = plid.span; self.process_def_kind(id, span, Some(span), def_id, scope); } @@ -1316,7 +1322,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> self.process_macro_use(t.span, t.id); match t.node { ast::TyKind::Path(_, ref path) => { - if let Some(id) = self.lookup_type_ref(t.id) { + if let Some(id) = self.lookup_def_id(t.id) { let sub_span = self.span.sub_span_for_type_name(t.span); if !self.span.filter_generated(sub_span, t.span) { self.dumper.type_ref(TypeRefData { @@ -1486,14 +1492,12 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> }.lower(self.tcx)); } } - Def::Variant(..) | Def::Enum(..) | - Def::TyAlias(..) | Def::Struct(..) => { + Def::StructCtor(..) | Def::VariantCtor(..) | + Def::Const(..) | Def::AssociatedConst(..) | + Def::Struct(..) | Def::Variant(..) | + Def::TyAlias(..) | Def::AssociatedTy(..) => { paths_to_process.push((id, p.clone(), Some(ref_kind))) } - // FIXME(nrc) what are these doing here? - Def::Static(..) | - Def::Const(..) | - Def::AssociatedConst(..) => {} def => error!("unexpected definition kind when processing collected paths: {:?}", def), } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index aa68a873120ec..15c74f2ed6ab5 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -507,7 +507,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Def::Static(..) | Def::Const(..) | Def::AssociatedConst(..) | - Def::Variant(..) => { + Def::StructCtor(..) | + Def::VariantCtor(..) => { Some(Data::VariableRefData(VariableRefData { name: self.span_utils.snippet(sub_span.unwrap()), span: sub_span.unwrap(), @@ -516,9 +517,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } Def::Struct(def_id) | + Def::Variant(def_id, ..) | Def::Union(def_id) | Def::Enum(def_id) | Def::TyAlias(def_id) | + Def::AssociatedTy(def_id) | Def::Trait(def_id) | Def::TyParam(def_id) => { Some(Data::TypeRefData(TypeRefData { @@ -572,7 +575,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname: String::new() // FIXME: generate the real qualname })) } - _ => None, + Def::PrimTy(..) | + Def::SelfTy(..) | + Def::Label(..) | + Def::Err => None, } } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index a441800795b96..765c128c30b63 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -24,6 +24,7 @@ use session::Session; use llvm::{self, ValueRef}; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock}; +use rustc::hir::def::CtorKind; use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::hir; @@ -1076,10 +1077,6 @@ struct StructMemberDescriptionFactory<'tcx> { impl<'tcx> StructMemberDescriptionFactory<'tcx> { fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> Vec { - if self.variant.kind == ty::VariantKind::Unit { - return Vec::new(); - } - let field_size = if self.is_simd { let fty = monomorphize::field_ty(cx.tcx(), self.substs, @@ -1093,7 +1090,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> { }; self.variant.fields.iter().enumerate().map(|(i, f)| { - let name = if self.variant.kind == ty::VariantKind::Tuple { + let name = if self.variant.ctor_kind == CtorKind::Fn { format!("__{}", i) } else { f.name.to_string() @@ -1387,12 +1384,12 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { // For the metadata of the wrapper struct, we need to create a // MemberDescription of the struct's single field. let sole_struct_member_description = MemberDescription { - name: match non_null_variant.kind { - ty::VariantKind::Tuple => "__0".to_string(), - ty::VariantKind::Struct => { + name: match non_null_variant.ctor_kind { + CtorKind::Fn => "__0".to_string(), + CtorKind::Fictive => { non_null_variant.fields[0].name.to_string() } - ty::VariantKind::Unit => bug!() + CtorKind::Const => bug!() }, llvm_type: non_null_llvm_type, type_metadata: non_null_type_metadata, @@ -1579,16 +1576,16 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, containing_scope); // Get the argument names from the enum variant info - let mut arg_names: Vec<_> = match variant.kind { - ty::VariantKind::Unit => vec![], - ty::VariantKind::Tuple => { + let mut arg_names: Vec<_> = match variant.ctor_kind { + CtorKind::Const => vec![], + CtorKind::Fn => { variant.fields .iter() .enumerate() .map(|(i, _)| format!("__{}", i)) .collect() } - ty::VariantKind::Struct => { + CtorKind::Fictive => { variant.fields .iter() .map(|f| f.name.to_string()) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 99d1da77018ad..87729da773f45 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use hir::def::Def; +use rustc::hir::{self, PatKind}; +use rustc::hir::def::{Def, CtorKind}; +use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::infer::{self, InferOk, TypeOrigin}; -use hir::pat_util::EnumerateAndAdjustIterator; -use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference, VariantKind}; +use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference}; use check::{FnCtxt, Expectation}; -use lint; use util::nodemap::FnvHashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -23,9 +23,6 @@ use syntax::codemap::Spanned; use syntax::ptr::P; use syntax_pos::Span; -use rustc::hir::{self, PatKind}; -use rustc::hir::print as pprust; - impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) { let tcx = self.tcx; @@ -516,10 +513,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected: Ty<'tcx>) -> Ty<'tcx> { let tcx = self.tcx; - let report_unexpected_def = || { + let report_unexpected_def = |def: Def| { span_err!(tcx.sess, pat.span, E0533, - "`{}` does not name a unit variant, unit struct or a constant", - pprust::path_to_string(path)); + "expected unit struct/variant or constant, found {} `{}`", + def.kind_name(), path); }; // Resolve the path and check the definition for errors. @@ -531,18 +528,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return tcx.types.err; } Def::Method(..) => { - report_unexpected_def(); + report_unexpected_def(def); return tcx.types.err; } - Def::Variant(..) | Def::Struct(..) => { - let variant = tcx.expect_variant_def(def); - if variant.kind != VariantKind::Unit { - report_unexpected_def(); - return tcx.types.err; - } - } + Def::VariantCtor(_, CtorKind::Const) | + Def::StructCtor(_, CtorKind::Const) | Def::Const(..) | Def::AssociatedConst(..) => {} // OK - _ => bug!("unexpected pattern definition {:?}", def) + _ => bug!("unexpected pattern definition: {:?}", def) } // Type check the path. @@ -564,17 +556,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_pat(&pat, tcx.types.err); } }; - let report_unexpected_def = |is_lint| { - let msg = format!("`{}` does not name a tuple variant or a tuple struct", - pprust::path_to_string(path)); - if is_lint { - tcx.sess.add_lint(lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT, - pat.id, pat.span, msg); - } else { - struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg) - .span_label(pat.span, &format!("not a tuple variant or struct")).emit(); - on_error(); - } + let report_unexpected_def = |def: Def| { + let msg = format!("expected tuple struct/variant, found {} `{}`", + def.kind_name(), path); + struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg) + .span_label(pat.span, &format!("not a tuple variant or struct")).emit(); + on_error(); }; // Resolve the path and check the definition for errors. @@ -585,33 +572,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { on_error(); return tcx.types.err; } - Def::Const(..) | Def::AssociatedConst(..) | Def::Method(..) => { - report_unexpected_def(false); + Def::AssociatedConst(..) | Def::Method(..) => { + report_unexpected_def(def); return tcx.types.err; } - Def::Variant(..) | Def::Struct(..) => { + Def::VariantCtor(_, CtorKind::Fn) | + Def::StructCtor(_, CtorKind::Fn) => { tcx.expect_variant_def(def) } - _ => bug!("unexpected pattern definition {:?}", def) + _ => bug!("unexpected pattern definition: {:?}", def) }; - if variant.kind == VariantKind::Unit && subpats.is_empty() && ddpos.is_some() { - // Matching unit structs with tuple variant patterns (`UnitVariant(..)`) - // is allowed for backward compatibility. - report_unexpected_def(true); - } else if variant.kind != VariantKind::Tuple { - report_unexpected_def(false); - return tcx.types.err; - } // Type check the path. let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id); - let pat_ty = if pat_ty.is_fn() { - // Replace constructor type with constructed type for tuple struct patterns. - tcx.no_late_bound_regions(&pat_ty.fn_ret()).unwrap() - } else { - // Leave the type as is for unit structs (backward compatibility). - pat_ty - }; + // Replace constructor type with constructed type for tuple struct patterns. + let pat_ty = tcx.no_late_bound_regions(&pat_ty.fn_ret()).expect("expected fn type"); self.demand_eqtype(pat.span, expected, pat_ty); // Type check subpatterns. @@ -626,16 +601,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_pat(&subpat, field_ty); } } else { - let subpats_ending = if subpats.len() == 1 { - "" - } else { - "s" - }; - let fields_ending = if variant.fields.len() == 1 { - "" - } else { - "s" - }; + let subpats_ending = if subpats.len() == 1 { "" } else { "s" }; + let fields_ending = if variant.fields.len() == 1 { "" } else { "s" }; struct_span_err!(tcx.sess, pat.span, E0023, "this pattern has {} field{}, but the corresponding {} has {} field{}", subpats.len(), subpats_ending, def.kind_name(), diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 34bcd2ba046e9..ac8a35f08b0d9 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -451,27 +451,26 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { fn handle_external_def(ccx: &CrateCtxt, traits: &mut AllTraitsVec, external_mods: &mut FnvHashSet, - def_id: DefId) { - match ccx.tcx.sess.cstore.describe_def(def_id) { - Some(Def::Trait(_)) => { + def: Def) { + let def_id = def.def_id(); + match def { + Def::Trait(..) => { traits.push(TraitInfo::new(def_id)); } - Some(Def::Mod(_)) => { + Def::Mod(..) => { if !external_mods.insert(def_id) { return; } for child in ccx.tcx.sess.cstore.item_children(def_id) { - handle_external_def(ccx, traits, external_mods, child.def_id) + handle_external_def(ccx, traits, external_mods, child.def) } } _ => {} } } for cnum in ccx.tcx.sess.cstore.crates() { - handle_external_def(ccx, &mut traits, &mut external_mods, DefId { - krate: cnum, - index: CRATE_DEF_INDEX - }); + let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(def_id)); } *ccx.all_traits.borrow_mut() = Some(traits); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 00114099c44bf..79c1c5fb5e2e1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,7 +83,7 @@ use self::TupleArgumentsFlag::*; use astconv::{AstConv, ast_region_to_region, PathParamMode}; use dep_graph::DepNode; use fmt_macros::{Parser, Piece, Position}; -use hir::def::{Def, PathResolution}; +use hir::def::{Def, CtorKind, PathResolution}; use hir::def_id::{DefId, LOCAL_CRATE}; use hir::pat_util; use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable}; @@ -3020,7 +3020,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { while let Some((base_t, autoderefs)) = autoderef.next() { let field = match base_t.sty { ty::TyAdt(base_def, substs) if base_def.is_struct() => { - tuple_like = base_def.struct_variant().kind == ty::VariantKind::Tuple; + tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn; if !tuple_like { continue } debug!("tuple struct named {:?}", base_t); @@ -3245,7 +3245,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Struct(type_did) | Def::Union(type_did) => { Some((type_did, self.tcx.expect_variant_def(def))) } - Def::TyAlias(did) => { + Def::TyAlias(did) | Def::AssociatedTy(did) => { match self.tcx.opt_lookup_item_type(did).map(|scheme| &scheme.ty.sty) { Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => { Some((did, adt.struct_variant())) @@ -3257,7 +3257,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; if let Some((def_id, variant)) = variant { - if variant.kind == ty::VariantKind::Tuple && + if variant.ctor_kind == CtorKind::Fn && !self.tcx.sess.features.borrow().relaxed_adts { emit_feature_err(&self.tcx.sess.parse_sess, "relaxed_adts", span, GateIssue::Language, @@ -4064,34 +4064,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // // There are basically four cases to consider: // - // 1. Reference to a *type*, such as a struct or enum: + // 1. Reference to a constructor of enum variant or struct: // - // mod a { struct Foo { ... } } - // - // Because we don't allow types to be declared within one - // another, a path that leads to a type will always look like - // `a::b::Foo` where `a` and `b` are modules. This implies - // that only the final segment can have type parameters, and - // they are located in the TypeSpace. - // - // *Note:* Generally speaking, references to types don't - // actually pass through this function, but rather the - // `ast_ty_to_ty` function in `astconv`. However, in the case - // of struct patterns (and maybe literals) we do invoke - // `instantiate_value_path` to get the general type of an instance of - // a struct. (In these cases, there are actually no type - // parameters permitted at present, but perhaps we will allow - // them in the future.) - // - // 1b. Reference to an enum variant or tuple-like struct: - // - // struct foo(...) - // enum E { foo(...) } + // struct Foo(...) + // enum E { Foo(...) } // // In these cases, the parameters are declared in the type // space. // - // 2. Reference to a *fn item*: + // 2. Reference to a fn item or a free constant: // // fn foo() { } // @@ -4100,7 +4081,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // type parameters. However, in this case, those parameters are // declared on a value, and hence are in the `FnSpace`. // - // 3. Reference to a *method*: + // 3. Reference to a method or an associated constant: // // impl SomeStruct { // fn foo(...) @@ -4112,15 +4093,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `SomeStruct::`, contains parameters in TypeSpace, and the // final segment, `foo::` contains parameters in fn space. // - // 4. Reference to an *associated const*: - // - // impl AnotherStruct { - // const FOO: B = BAR; - // } + // 4. Reference to a local variable // - // The path in this case will look like - // `a::b::AnotherStruct::::FOO`, so the penultimate segment - // only will have parameters in TypeSpace. + // Local variables can't have any type parameters. // // The first step then is to categorize the segments appropriately. @@ -4130,14 +4105,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut type_segment = None; let mut fn_segment = None; match def { - // Case 1 and 1b. Reference to a *type* or *enum variant*. - Def::Struct(def_id) | - Def::Union(def_id) | - Def::Variant(def_id) | - Def::Enum(def_id) | - Def::TyAlias(def_id) | - Def::AssociatedTy(def_id) | - Def::Trait(def_id) => { + // Case 1. Reference to a struct/variant constructor. + Def::StructCtor(def_id, ..) | + Def::VariantCtor(def_id, ..) => { // Everything but the final segment should have no // parameters at all. let mut generics = self.tcx.lookup_generics(def_id); @@ -4180,17 +4150,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn_segment = Some((segments.last().unwrap(), generics)); } - // Other cases. Various nonsense that really shouldn't show up - // here. If they do, an error will have been reported - // elsewhere. (I hope) - Def::Mod(..) | - Def::PrimTy(..) | - Def::SelfTy(..) | - Def::TyParam(..) | - Def::Local(..) | - Def::Label(..) | - Def::Upvar(..) | - Def::Err => {} + // Case 4. Local variable, no generics. + Def::Local(..) | Def::Upvar(..) => {} + + _ => bug!("unexpected definition: {:?}", def), } // In `>::method`, `A` and `B` are mandatory, but diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index cdd7bef2c7fb9..128db6ef5848a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -68,7 +68,6 @@ use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err}; use rustc::ty::subst::Substs; use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer}; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt, TypeScheme}; -use rustc::ty::{VariantKind}; use rustc::ty::util::IntTypeExt; use rscope::*; use rustc::dep_graph::DepNode; @@ -87,7 +86,7 @@ use syntax::parse::token::keywords; use syntax_pos::Span; use rustc::hir::{self, intravisit, map as hir_map, print as pprust}; -use rustc::hir::def::Def; +use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; /////////////////////////////////////////////////////////////////////////// @@ -987,9 +986,9 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let tcx = ccx.tcx; let def_id = tcx.map.local_def_id(ctor_id); generics_of_def_id(ccx, def_id); - let ctor_ty = match variant.kind { - VariantKind::Unit | VariantKind::Struct => scheme.ty, - VariantKind::Tuple => { + let ctor_ty = match variant.ctor_kind { + CtorKind::Fictive | CtorKind::Const => scheme.ty, + CtorKind::Fn => { let inputs: Vec<_> = variant.fields .iter() @@ -1066,7 +1065,7 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, name: name, disr_val: disr_val, fields: fields, - kind: VariantKind::from_variant_data(def), + ctor_kind: CtorKind::from_hir(def), } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 208a5d810922a..feca2d328fe3b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -15,11 +15,10 @@ use std::iter::once; use syntax::ast; use rustc::hir; -use rustc::hir::def::Def; +use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; -use rustc::hir::map::DefPathData; use rustc::hir::print as pprust; -use rustc::ty::{self, TyCtxt, VariantKind}; +use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::FnvHashSet; use rustc_const_eval::lookup_const_by_id; @@ -81,9 +80,7 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, record_extern_fqn(cx, did, clean::TypeKind::Function); clean::FunctionItem(build_external_function(cx, tcx, did)) } - Def::Struct(did) - // If this is a struct constructor, we skip it - if tcx.def_key(did).disambiguated_data.data != DefPathData::StructCtor => { + Def::Struct(did) => { record_extern_fqn(cx, did, clean::TypeKind::Struct); ret.extend(build_impls(cx, tcx, did)); clean::StructItem(build_struct(cx, tcx, did)) @@ -105,7 +102,10 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, } // Assume that the enum type is reexported next to the variant, and // variants don't show up in documentation specially. - Def::Variant(..) => return Some(Vec::new()), + // Similarly, consider that struct type is reexported next to its constructor. + Def::Variant(..) | + Def::VariantCtor(..) | + Def::StructCtor(..) => return Some(Vec::new()), Def::Mod(did) => { record_extern_fqn(cx, did, clean::TypeKind::Module); clean::ModuleItem(build_module(cx, tcx, did)) @@ -114,7 +114,7 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, record_extern_fqn(cx, did, clean::TypeKind::Static); clean::StaticItem(build_static(cx, tcx, did, mtbl)) } - Def::Const(did) | Def::AssociatedConst(did) => { + Def::Const(did) => { record_extern_fqn(cx, did, clean::TypeKind::Const); clean::ConstantItem(build_const(cx, tcx, did)) } @@ -219,10 +219,10 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, let variant = tcx.lookup_adt_def(did).struct_variant(); clean::Struct { - struct_type: match variant.kind { - VariantKind::Struct => doctree::Plain, - VariantKind::Tuple => doctree::Tuple, - VariantKind::Unit => doctree::Unit, + struct_type: match variant.ctor_kind { + CtorKind::Fictive => doctree::Plain, + CtorKind::Fn => doctree::Tuple, + CtorKind::Const => doctree::Unit, }, generics: (t.generics, &predicates).clean(cx), fields: variant.fields.clean(cx), @@ -498,12 +498,11 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, // visit each node at most once. let mut visited = FnvHashSet(); for item in tcx.sess.cstore.item_children(did) { - if tcx.sess.cstore.visibility(item.def_id) == ty::Visibility::Public { - if !visited.insert(item.def_id) { continue } - if let Some(def) = tcx.sess.cstore.describe_def(item.def_id) { - if let Some(i) = try_inline_def(cx, tcx, def) { - items.extend(i) - } + let def_id = item.def.def_id(); + if tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public { + if !visited.insert(def_id) { continue } + if let Some(i) = try_inline_def(cx, tcx, item.def) { + items.extend(i) } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cf20572510b5c..eb6115e937315 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -32,7 +32,7 @@ use syntax_pos::{self, DUMMY_SP, Pos}; use rustc_trans::back::link; use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime::DefRegion::*; -use rustc::hir::def::Def; +use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::{self, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::print as pprust; use rustc::ty::subst::Substs; @@ -237,7 +237,7 @@ impl Clean for CrateNum { let root = DefId { krate: self.0, index: CRATE_DEF_INDEX }; cx.tcx_opt().map(|tcx| { for item in tcx.sess.cstore.item_children(root) { - let attrs = inline::load_attrs(cx, tcx, item.def_id); + let attrs = inline::load_attrs(cx, tcx, item.def.def_id()); PrimitiveType::find(&attrs).map(|prim| primitives.push(prim)); } }); @@ -2032,14 +2032,14 @@ impl Clean for doctree::Variant { impl<'tcx> Clean for ty::VariantDefData<'tcx, 'static> { fn clean(&self, cx: &DocContext) -> Item { - let kind = match self.kind { - ty::VariantKind::Unit => VariantKind::CLike, - ty::VariantKind::Tuple => { + let kind = match self.ctor_kind { + CtorKind::Const => VariantKind::CLike, + CtorKind::Fn => { VariantKind::Tuple( self.fields.iter().map(|f| f.unsubst_ty().clean(cx)).collect() ) } - ty::VariantKind::Struct => { + CtorKind::Fictive => { VariantKind::Struct(VariantStruct { struct_type: doctree::Plain, fields_stripped: false, diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 285b47fe60abf..6d2830c56192b 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -66,11 +66,12 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> { pub fn visit_mod(&mut self, def_id: DefId) { for item in self.cstore.item_children(def_id) { - self.visit_item(item.def_id); + self.visit_item(item.def); } } - fn visit_item(&mut self, def_id: DefId) { + fn visit_item(&mut self, def: Def) { + let def_id = def.def_id(); let vis = self.cstore.visibility(def_id); let inherited_item_level = if vis == Visibility::Public { self.prev_level @@ -80,7 +81,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> { let item_level = self.update(def_id, inherited_item_level); - if let Some(Def::Mod(_)) = self.cstore.describe_def(def_id) { + if let Def::Mod(..) = def { let orig_level = self.prev_level; self.prev_level = item_level; diff --git a/src/test/compile-fail/E0164.rs b/src/test/compile-fail/E0164.rs index 1665a80bead77..8d21cde84da1c 100644 --- a/src/test/compile-fail/E0164.rs +++ b/src/test/compile-fail/E0164.rs @@ -8,7 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum Foo { B { i: u32 } } +#![feature(associated_consts)] + +enum Foo {} + +impl Foo { + const B: u8 = 0; +} fn bar(foo: Foo) -> u32 { match foo { diff --git a/src/test/compile-fail/auxiliary/namespace-mix-new.rs b/src/test/compile-fail/auxiliary/namespace-mix-new.rs new file mode 100644 index 0000000000000..88e8b0d56fe3d --- /dev/null +++ b/src/test/compile-fail/auxiliary/namespace-mix-new.rs @@ -0,0 +1,78 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(item_like_imports, relaxed_adts)] + +pub mod c { + pub struct S {} + pub struct TS(); + pub struct US; + pub enum E { + V {}, + TV(), + UV, + } + + pub struct Item; +} + +pub mod xm1 { + pub use ::c::*; + pub type S = ::c::Item; +} +pub mod xm2 { + pub use ::c::*; + pub const S: ::c::Item = ::c::Item; +} + +pub mod xm3 { + pub use ::c::*; + pub type TS = ::c::Item; +} +pub mod xm4 { + pub use ::c::*; + pub const TS: ::c::Item = ::c::Item; +} + +pub mod xm5 { + pub use ::c::*; + pub type US = ::c::Item; +} +pub mod xm6 { + pub use ::c::*; + pub const US: ::c::Item = ::c::Item; +} + +pub mod xm7 { + pub use ::c::E::*; + pub type V = ::c::Item; +} +pub mod xm8 { + pub use ::c::E::*; + pub const V: ::c::Item = ::c::Item; +} + +pub mod xm9 { + pub use ::c::E::*; + pub type TV = ::c::Item; +} +pub mod xmA { + pub use ::c::E::*; + pub const TV: ::c::Item = ::c::Item; +} + +pub mod xmB { + pub use ::c::E::*; + pub type UV = ::c::Item; +} +pub mod xmC { + pub use ::c::E::*; + pub const UV: ::c::Item = ::c::Item; +} diff --git a/src/test/compile-fail/auxiliary/namespace-mix-old.rs b/src/test/compile-fail/auxiliary/namespace-mix-old.rs new file mode 100644 index 0000000000000..7bbba7163b557 --- /dev/null +++ b/src/test/compile-fail/auxiliary/namespace-mix-old.rs @@ -0,0 +1,85 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// FIXME: Remove when `item_like_imports` is stabilized. + +#![feature(relaxed_adts)] + +pub mod c { + pub struct S {} + pub struct TS(); + pub struct US; + pub enum E { + V {}, + TV(), + UV, + } + + pub struct Item; +} + +pub mod proxy { + pub use c::*; + pub use c::E::*; +} + +pub mod xm1 { + pub use ::proxy::*; + pub type S = ::c::Item; +} +pub mod xm2 { + pub use ::proxy::*; + pub const S: ::c::Item = ::c::Item; +} + +pub mod xm3 { + pub use ::proxy::*; + pub type TS = ::c::Item; +} +pub mod xm4 { + pub use ::proxy::*; + pub const TS: ::c::Item = ::c::Item; +} + +pub mod xm5 { + pub use ::proxy::*; + pub type US = ::c::Item; +} +pub mod xm6 { + pub use ::proxy::*; + pub const US: ::c::Item = ::c::Item; +} + +pub mod xm7 { + pub use ::proxy::*; + pub type V = ::c::Item; +} +pub mod xm8 { + pub use ::proxy::*; + pub const V: ::c::Item = ::c::Item; +} + +pub mod xm9 { + pub use ::proxy::*; + pub type TV = ::c::Item; +} +pub mod xmA { + pub use ::proxy::*; + pub const TV: ::c::Item = ::c::Item; +} + +pub mod xmB { + pub use ::proxy::*; + pub type UV = ::c::Item; +} +pub mod xmC { + pub use ::proxy::*; + pub const UV: ::c::Item = ::c::Item; +} diff --git a/src/test/compile-fail/blind-item-block-middle.rs b/src/test/compile-fail/blind-item-block-middle.rs index f57727b773d63..0db7eaf0ca7c3 100644 --- a/src/test/compile-fail/blind-item-block-middle.rs +++ b/src/test/compile-fail/blind-item-block-middle.rs @@ -12,6 +12,6 @@ mod foo { pub struct bar; } fn main() { let bar = 5; - //~^ ERROR let bindings cannot shadow structs + //~^ ERROR let bindings cannot shadow unit structs use foo::bar; } diff --git a/src/test/compile-fail/empty-struct-braces-pat-1.rs b/src/test/compile-fail/empty-struct-braces-pat-1.rs index 74546152ca90f..e527170e9f957 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-1.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-1.rs @@ -32,13 +32,13 @@ fn main() { } match e3 { E::Empty3 => () - //~^ ERROR `E::Empty3` does not name a unit variant, unit struct or a constant + //~^ ERROR expected unit struct/variant or constant, found struct variant `E::Empty3` } match xe1 { XEmpty1 => () // Not an error, `XEmpty1` is interpreted as a new binding } match xe3 { XE::XEmpty3 => () - //~^ ERROR `XE::XEmpty3` does not name a unit variant, unit struct or a constant + //~^ ERROR expected unit struct/variant or constant, found struct variant `XE::XEmpty3` } } diff --git a/src/test/compile-fail/empty-struct-braces-pat-2.rs b/src/test/compile-fail/empty-struct-braces-pat-2.rs index 52481517ce751..58e3ca6b3ac5c 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-2.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-2.rs @@ -24,15 +24,15 @@ fn main() { let xe1 = XEmpty1 {}; match e1 { - Empty1() => () //~ ERROR unresolved variant or struct `Empty1` + Empty1() => () //~ ERROR unresolved tuple struct/variant `Empty1` } match xe1 { - XEmpty1() => () //~ ERROR unresolved variant or struct `XEmpty1` + XEmpty1() => () //~ ERROR unresolved tuple struct/variant `XEmpty1` } match e1 { - Empty1(..) => () //~ ERROR unresolved variant or struct `Empty1` + Empty1(..) => () //~ ERROR unresolved tuple struct/variant `Empty1` } match xe1 { - XEmpty1(..) => () //~ ERROR unresolved variant or struct `XEmpty1` + XEmpty1(..) => () //~ ERROR unresolved tuple struct/variant `XEmpty1` } } diff --git a/src/test/compile-fail/empty-struct-braces-pat-3.rs b/src/test/compile-fail/empty-struct-braces-pat-3.rs index cb859fe7501c6..1960eca9f8028 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-3.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-3.rs @@ -26,15 +26,19 @@ fn main() { let xe3 = XE::XEmpty3 {}; match e3 { - E::Empty3() => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct + E::Empty3() => () + //~^ ERROR expected tuple struct/variant, found struct variant `E::Empty3` } match xe3 { - XE::XEmpty3() => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple struct + XE::XEmpty3() => () + //~^ ERROR expected tuple struct/variant, found struct variant `XE::XEmpty3` } match e3 { - E::Empty3(..) => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct + E::Empty3(..) => () + //~^ ERROR expected tuple struct/variant, found struct variant `E::Empty3` } match xe3 { - XE::XEmpty3(..) => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple + XE::XEmpty3(..) => () + //~^ ERROR expected tuple struct/variant, found struct variant `XE::XEmpty3 } } diff --git a/src/test/compile-fail/empty-struct-tuple-pat.rs b/src/test/compile-fail/empty-struct-tuple-pat.rs index be90e3b26c7ef..f15c126a12608 100644 --- a/src/test/compile-fail/empty-struct-tuple-pat.rs +++ b/src/test/compile-fail/empty-struct-tuple-pat.rs @@ -31,17 +31,19 @@ fn main() { let xe5 = XE::XEmpty5(); match e2 { - Empty2 => () //~ ERROR `Empty2` does not name a unit variant, unit struct or a constant + Empty2 => () //~ ERROR match bindings cannot shadow tuple structs } match xe6 { - XEmpty6 => () //~ ERROR `XEmpty6` does not name a unit variant, unit struct or a constant + XEmpty6 => () //~ ERROR match bindings cannot shadow tuple structs } match e4 { - E::Empty4 => () //~ ERROR `E::Empty4` does not name a unit variant, unit struct or a + E::Empty4 => () + //~^ ERROR expected unit struct/variant or constant, found tuple variant `E::Empty4` } match xe5 { - XE::XEmpty5 => (), //~ ERROR `XE::XEmpty5` does not name a unit variant, unit struct or a + XE::XEmpty5 => (), + //~^ ERROR expected unit struct/variant or constant, found tuple variant `XE::XEmpty5` _ => {}, } } diff --git a/src/test/compile-fail/empty-struct-unit-pat-1.rs b/src/test/compile-fail/empty-struct-unit-pat-1.rs index aec4ad4cad401..273cb48b2d2a5 100644 --- a/src/test/compile-fail/empty-struct-unit-pat-1.rs +++ b/src/test/compile-fail/empty-struct-unit-pat-1.rs @@ -31,21 +31,22 @@ fn main() { let xe4 = XE::XEmpty4; match e2 { - Empty2(..) => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct + Empty2(..) => () //~ ERROR expected tuple struct/variant, found unit struct `Empty2` //~^ WARNING hard error } match xe2 { - XEmpty2(..) => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct + XEmpty2(..) => () //~ ERROR expected tuple struct/variant, found unit struct `XEmpty2` //~^ WARNING hard error } match e4 { - E::Empty4(..) => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct + E::Empty4(..) => () //~ ERROR expected tuple struct/variant, found unit variant `E::Empty4` //~^ WARNING hard error } match xe4 { - XE::XEmpty4(..) => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple - //~^ WARNING hard error + XE::XEmpty4(..) => (), + //~^ ERROR expected tuple struct/variant, found unit variant `XE::XEmpty4` + //~| WARNING hard error _ => {}, } } diff --git a/src/test/compile-fail/empty-struct-unit-pat-2.rs b/src/test/compile-fail/empty-struct-unit-pat-2.rs index 6375a7f23381e..993f10e08067b 100644 --- a/src/test/compile-fail/empty-struct-unit-pat-2.rs +++ b/src/test/compile-fail/empty-struct-unit-pat-2.rs @@ -23,7 +23,6 @@ enum E { Empty4 } -// remove attribute after warning cycle and promoting warnings to errors fn main() { let e2 = Empty2; let e4 = E::Empty4; @@ -31,17 +30,21 @@ fn main() { let xe4 = XE::XEmpty4; match e2 { - Empty2() => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct + Empty2() => () + //~^ ERROR expected tuple struct/variant, found unit struct `Empty2` } match xe2 { - XEmpty2() => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct + XEmpty2() => () + //~^ ERROR expected tuple struct/variant, found unit struct `XEmpty2` } match e4 { - E::Empty4() => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct + E::Empty4() => () + //~^ ERROR expected tuple struct/variant, found unit variant `E::Empty4` } match xe4 { - XE::XEmpty4() => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple + XE::XEmpty4() => (), + //~^ ERROR expected tuple struct/variant, found unit variant `XE::XEmpty4` _ => {}, } } diff --git a/src/test/compile-fail/enum-in-scope.rs b/src/test/compile-fail/enum-in-scope.rs index e89b08a8a0651..bc1bd03f2d652 100644 --- a/src/test/compile-fail/enum-in-scope.rs +++ b/src/test/compile-fail/enum-in-scope.rs @@ -11,5 +11,5 @@ struct hello(isize); fn main() { - let hello = 0; //~ERROR let bindings cannot shadow structs + let hello = 0; //~ERROR let bindings cannot shadow tuple structs } diff --git a/src/test/compile-fail/enums-pats-not-idents.rs b/src/test/compile-fail/enums-pats-not-idents.rs index c847366a707a7..03bdbe4e54b68 100644 --- a/src/test/compile-fail/enums-pats-not-idents.rs +++ b/src/test/compile-fail/enums-pats-not-idents.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let a(1) = 13; //~ ERROR unresolved variant or struct `a` + let a(1) = 13; //~ ERROR unresolved tuple struct/variant `a` } diff --git a/src/test/compile-fail/issue-10200.rs b/src/test/compile-fail/issue-10200.rs index 9eec8487a5087..8c58ef6261e10 100644 --- a/src/test/compile-fail/issue-10200.rs +++ b/src/test/compile-fail/issue-10200.rs @@ -13,7 +13,7 @@ fn foo(_: usize) -> Foo { Foo(false) } fn main() { match Foo(true) { - foo(x) //~ ERROR expected variant or struct, found function `foo` + foo(x) //~ ERROR expected tuple struct/variant, found function `foo` => () } } diff --git a/src/test/compile-fail/issue-12863.rs b/src/test/compile-fail/issue-12863.rs index 7912410f69ea1..d3432410c5427 100644 --- a/src/test/compile-fail/issue-12863.rs +++ b/src/test/compile-fail/issue-12863.rs @@ -12,6 +12,6 @@ mod foo { pub fn bar() {} } fn main() { match () { - foo::bar => {} //~ ERROR expected variant, struct or constant, found function `bar` + foo::bar => {} //~ ERROR expected unit struct/variant or constant, found function `foo::bar` } } diff --git a/src/test/compile-fail/issue-17933.rs b/src/test/compile-fail/issue-17933.rs index 2313a3fe9c6d5..049a0665c5458 100644 --- a/src/test/compile-fail/issue-17933.rs +++ b/src/test/compile-fail/issue-17933.rs @@ -13,7 +13,7 @@ pub static X: usize = 1; fn main() { match 1 { self::X => { }, - //~^ ERROR expected variant, struct or constant, found static `X` + //~^ ERROR expected unit struct/variant or constant, found static `self::X` _ => { }, } } diff --git a/src/test/compile-fail/issue-19086.rs b/src/test/compile-fail/issue-19086.rs index 56452449d4ee1..ba571ce17fd12 100644 --- a/src/test/compile-fail/issue-19086.rs +++ b/src/test/compile-fail/issue-19086.rs @@ -18,6 +18,6 @@ fn main() { let f = FooB { x: 3, y: 4 }; match f { FooB(a, b) => println!("{} {}", a, b), -//~^ ERROR `FooB` does not name a tuple variant or a tuple struct + //~^ ERROR expected tuple struct/variant, found struct variant `FooB` } } diff --git a/src/test/compile-fail/issue-27033.rs b/src/test/compile-fail/issue-27033.rs index 2a015adb498e1..b8552aaee9005 100644 --- a/src/test/compile-fail/issue-27033.rs +++ b/src/test/compile-fail/issue-27033.rs @@ -10,7 +10,7 @@ fn main() { match Some(1) { - None @ _ => {} //~ ERROR match bindings cannot shadow variants + None @ _ => {} //~ ERROR match bindings cannot shadow unit variants }; const C: u8 = 1; match 1 { diff --git a/src/test/compile-fail/issue-27815.rs b/src/test/compile-fail/issue-27815.rs index 7a329bac61b22..33930d1db1476 100644 --- a/src/test/compile-fail/issue-27815.rs +++ b/src/test/compile-fail/issue-27815.rs @@ -14,7 +14,9 @@ fn main() { let u = A { x: 1 }; //~ ERROR `A` does not name a struct or a struct variant let v = u32 { x: 1 }; //~ ERROR `u32` does not name a struct or a struct variant match () { - A { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found module `A` - u32 { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found builtin type `u32 + A { x: 1 } => {} + //~^ ERROR expected variant, struct or type alias, found module `A` + u32 { x: 1 } => {} + //~^ ERROR expected variant, struct or type alias, found builtin type `u32` } } diff --git a/src/test/compile-fail/issue-28992-empty.rs b/src/test/compile-fail/issue-28992-empty.rs index e492d48fdaf0f..d47fdda0203e8 100644 --- a/src/test/compile-fail/issue-28992-empty.rs +++ b/src/test/compile-fail/issue-28992-empty.rs @@ -21,6 +21,7 @@ impl S { } fn main() { - if let C1(..) = 0 {} //~ ERROR expected variant or struct, found constant `C1` - if let S::C2(..) = 0 {} //~ ERROR `S::C2` does not name a tuple variant or a tuple struct + if let C1(..) = 0 {} //~ ERROR expected tuple struct/variant, found constant `C1` + if let S::C2(..) = 0 {} + //~^ ERROR expected tuple struct/variant, found associated constant `S::C2` } diff --git a/src/test/compile-fail/issue-32004.rs b/src/test/compile-fail/issue-32004.rs index 576451f7292a8..7e1f4c28d21e9 100644 --- a/src/test/compile-fail/issue-32004.rs +++ b/src/test/compile-fail/issue-32004.rs @@ -18,12 +18,12 @@ struct S; fn main() { match Foo::Baz { Foo::Bar => {} - //~^ ERROR `Foo::Bar` does not name a unit variant, unit struct or a constant + //~^ ERROR expected unit struct/variant or constant, found tuple variant `Foo::Bar` _ => {} } match S { S(()) => {} - //~^ ERROR `S` does not name a tuple variant or a tuple struct + //~^ ERROR expected tuple struct/variant, found unit struct `S` } } diff --git a/src/test/compile-fail/issue-32086.rs b/src/test/compile-fail/issue-32086.rs index 926f58198dfae..dd236b76a6739 100644 --- a/src/test/compile-fail/issue-32086.rs +++ b/src/test/compile-fail/issue-32086.rs @@ -12,6 +12,6 @@ struct S(u8); const C: S = S(10); fn main() { - let C(a) = S(11); //~ ERROR expected variant or struct, found constant `C` - let C(..) = S(11); //~ ERROR expected variant or struct, found constant `C` + let C(a) = S(11); //~ ERROR expected tuple struct/variant, found constant `C` + let C(..) = S(11); //~ ERROR expected tuple struct/variant, found constant `C` } diff --git a/src/test/compile-fail/issue-5927.rs b/src/test/compile-fail/issue-5927.rs index 3a8ff12429ab3..7668a2117a265 100644 --- a/src/test/compile-fail/issue-5927.rs +++ b/src/test/compile-fail/issue-5927.rs @@ -11,7 +11,7 @@ fn main() { let z = match 3 { - x(1) => x(1) //~ ERROR unresolved variant or struct `x` + x(1) => x(1) //~ ERROR unresolved tuple struct/variant `x` //~^ ERROR unresolved name `x` }; assert!(z == 3); diff --git a/src/test/compile-fail/match-pattern-field-mismatch-2.rs b/src/test/compile-fail/match-pattern-field-mismatch-2.rs index a4ba93ea17333..aed9130d60e4b 100644 --- a/src/test/compile-fail/match-pattern-field-mismatch-2.rs +++ b/src/test/compile-fail/match-pattern-field-mismatch-2.rs @@ -20,7 +20,7 @@ fn main() { color::rgb(_, _, _) => { } color::cmyk(_, _, _, _) => { } color::no_color(_) => { } - //~^ ERROR `color::no_color` does not name a tuple variant or a tuple struct + //~^ ERROR expected tuple struct/variant, found unit variant `color::no_color` } } } diff --git a/src/test/compile-fail/match-pattern-field-mismatch.rs b/src/test/compile-fail/match-pattern-field-mismatch.rs index 8426ecdaf995e..ddd5d63317011 100644 --- a/src/test/compile-fail/match-pattern-field-mismatch.rs +++ b/src/test/compile-fail/match-pattern-field-mismatch.rs @@ -18,7 +18,7 @@ fn main() { fn foo(c: color) { match c { color::rgb(_, _) => { } - //~^ ERROR this pattern has 2 fields, but the corresponding variant has 3 fields + //~^ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields color::cmyk(_, _, _, _) => { } color::no_color => { } } diff --git a/src/test/compile-fail/method-path-in-pattern.rs b/src/test/compile-fail/method-path-in-pattern.rs index ef011c89c622b..aaa89b2282967 100644 --- a/src/test/compile-fail/method-path-in-pattern.rs +++ b/src/test/compile-fail/method-path-in-pattern.rs @@ -22,13 +22,13 @@ impl MyTrait for Foo {} fn main() { match 0u32 { - Foo::bar => {} //~ ERROR `Foo::bar` does not name a unit variant, unit struct or a constant + Foo::bar => {} //~ ERROR expected unit struct/variant or constant, found method `Foo::bar` } match 0u32 { - ::bar => {} //~ ERROR `bar` does not name a unit variant, unit struct or a constant + ::bar => {} //~ ERROR expected unit struct/variant or constant, found method `bar` } match 0u32 { ::trait_bar => {} - //~^ ERROR `trait_bar` does not name a unit variant, unit struct or a constant + //~^ ERROR expected unit struct/variant or constant, found method `trait_bar` } } diff --git a/src/test/compile-fail/method-resolvable-path-in-pattern.rs b/src/test/compile-fail/method-resolvable-path-in-pattern.rs index 3ae792f9c0f37..4d8959466b948 100644 --- a/src/test/compile-fail/method-resolvable-path-in-pattern.rs +++ b/src/test/compile-fail/method-resolvable-path-in-pattern.rs @@ -19,6 +19,6 @@ impl MyTrait for Foo {} fn main() { match 0u32 { ::trait_bar => {} - //~^ ERROR expected variant, struct or constant, found method `trait_bar` + //~^ ERROR expected unit struct/variant or constant, found method `MyTrait::trait_bar` } } diff --git a/src/test/compile-fail/name-clash-nullary.rs b/src/test/compile-fail/name-clash-nullary.rs index 2e2d53c4d40b6..4c76c4b8b0265 100644 --- a/src/test/compile-fail/name-clash-nullary.rs +++ b/src/test/compile-fail/name-clash-nullary.rs @@ -11,7 +11,7 @@ use std::option::*; fn main() { - let None: isize = 42; //~ ERROR let bindings cannot shadow variants + let None: isize = 42; //~ ERROR let bindings cannot shadow unit variants log(debug, None); //~^ ERROR unresolved name `debug` //~| ERROR unresolved name `log` diff --git a/src/test/compile-fail/namespace-mix-new.rs b/src/test/compile-fail/namespace-mix-new.rs new file mode 100644 index 0000000000000..0abe8bd439093 --- /dev/null +++ b/src/test/compile-fail/namespace-mix-new.rs @@ -0,0 +1,167 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:namespace-mix-new.rs + +#![feature(item_like_imports, relaxed_adts)] + +extern crate namespace_mix_new; +use namespace_mix_new::*; + +mod c { + pub struct S {} + pub struct TS(); + pub struct US; + pub enum E { + V {}, + TV(), + UV, + } + + pub struct Item; +} + +// Use something emitting the type argument name, e.g. unsatisfied bound. +trait Impossible {} +fn check(_: T) {} + +mod m1 { + pub use ::c::*; + pub type S = ::c::Item; +} +mod m2 { + pub use ::c::*; + pub const S: ::c::Item = ::c::Item; +} + +fn f12() { + check(m1::S{}); //~ ERROR c::Item + check(m1::S); //~ ERROR unresolved name + check(m2::S{}); //~ ERROR c::S + check(m2::S); //~ ERROR c::Item +} +fn xf12() { + check(xm1::S{}); //~ ERROR c::Item + check(xm1::S); //~ ERROR unresolved name + check(xm2::S{}); //~ ERROR c::S + check(xm2::S); //~ ERROR c::Item +} + +mod m3 { + pub use ::c::*; + pub type TS = ::c::Item; +} +mod m4 { + pub use ::c::*; + pub const TS: ::c::Item = ::c::Item; +} + +fn f34() { + check(m3::TS{}); //~ ERROR c::Item + check(m3::TS); //~ ERROR c::TS + check(m4::TS{}); //~ ERROR c::TS + check(m4::TS); //~ ERROR c::Item +} +fn xf34() { + check(xm3::TS{}); //~ ERROR c::Item + check(xm3::TS); //~ ERROR c::TS + check(xm4::TS{}); //~ ERROR c::TS + check(xm4::TS); //~ ERROR c::Item +} + +mod m5 { + pub use ::c::*; + pub type US = ::c::Item; +} +mod m6 { + pub use ::c::*; + pub const US: ::c::Item = ::c::Item; +} + +fn f56() { + check(m5::US{}); //~ ERROR c::Item + check(m5::US); //~ ERROR c::US + check(m6::US{}); //~ ERROR c::US + check(m6::US); //~ ERROR c::Item +} +fn xf56() { + check(xm5::US{}); //~ ERROR c::Item + check(xm5::US); //~ ERROR c::US + check(xm6::US{}); //~ ERROR c::US + check(xm6::US); //~ ERROR c::Item +} + +mod m7 { + pub use ::c::E::*; + pub type V = ::c::Item; +} +mod m8 { + pub use ::c::E::*; + pub const V: ::c::Item = ::c::Item; +} + +fn f78() { + check(m7::V{}); //~ ERROR c::Item + check(m7::V); //~ ERROR name of a struct or struct variant + check(m8::V{}); //~ ERROR c::E + check(m8::V); //~ ERROR c::Item +} +fn xf78() { + check(xm7::V{}); //~ ERROR c::Item + check(xm7::V); //~ ERROR name of a struct or struct variant + check(xm8::V{}); //~ ERROR c::E + check(xm8::V); //~ ERROR c::Item +} + +mod m9 { + pub use ::c::E::*; + pub type TV = ::c::Item; +} +mod mA { + pub use ::c::E::*; + pub const TV: ::c::Item = ::c::Item; +} + +fn f9A() { + check(m9::TV{}); //~ ERROR c::Item + check(m9::TV); //~ ERROR c::E + check(mA::TV{}); //~ ERROR c::E + check(mA::TV); //~ ERROR c::Item +} +fn xf9A() { + check(xm9::TV{}); //~ ERROR c::Item + check(xm9::TV); //~ ERROR c::E + check(xmA::TV{}); //~ ERROR c::E + check(xmA::TV); //~ ERROR c::Item +} + +mod mB { + pub use ::c::E::*; + pub type UV = ::c::Item; +} +mod mC { + pub use ::c::E::*; + pub const UV: ::c::Item = ::c::Item; +} + +fn fBC() { + check(mB::UV{}); //~ ERROR c::Item + check(mB::UV); //~ ERROR c::E + check(mC::UV{}); //~ ERROR c::E + check(mC::UV); //~ ERROR c::Item +} +fn xfBC() { + check(xmB::UV{}); //~ ERROR c::Item + check(xmB::UV); //~ ERROR c::E + check(xmC::UV{}); //~ ERROR c::E + check(xmC::UV); //~ ERROR c::Item +} + +fn main() {} diff --git a/src/test/compile-fail/namespace-mix-old.rs b/src/test/compile-fail/namespace-mix-old.rs new file mode 100644 index 0000000000000..ad6766441961b --- /dev/null +++ b/src/test/compile-fail/namespace-mix-old.rs @@ -0,0 +1,174 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// FIXME: Remove when `item_like_imports` is stabilized. + +// aux-build:namespace-mix-old.rs + +#![feature(relaxed_adts)] + +extern crate namespace_mix_old; +use namespace_mix_old::{xm1, xm2, xm3, xm4, xm5, xm6, xm7, xm8, xm9, xmA, xmB, xmC}; + +mod c { + pub struct S {} + pub struct TS(); + pub struct US; + pub enum E { + V {}, + TV(), + UV, + } + + pub struct Item; +} + +mod proxy { + pub use c::*; + pub use c::E::*; +} + +// Use something emitting the type argument name, e.g. unsatisfied bound. +trait Impossible {} +fn check(_: T) {} + +mod m1 { + pub use ::proxy::*; + pub type S = ::c::Item; +} +mod m2 { + pub use ::proxy::*; + pub const S: ::c::Item = ::c::Item; +} + +fn f12() { + check(m1::S{}); //~ ERROR c::Item + check(m1::S); //~ ERROR unresolved name + check(m2::S{}); //~ ERROR c::S + check(m2::S); //~ ERROR c::Item +} +fn xf12() { + check(xm1::S{}); //~ ERROR c::Item + check(xm1::S); //~ ERROR unresolved name + check(xm2::S{}); //~ ERROR c::S + check(xm2::S); //~ ERROR c::Item +} + +mod m3 { + pub use ::proxy::*; + pub type TS = ::c::Item; +} +mod m4 { + pub use ::proxy::*; + pub const TS: ::c::Item = ::c::Item; +} + +fn f34() { + check(m3::TS{}); //~ ERROR c::Item + check(m3::TS); //~ ERROR c::TS + check(m4::TS{}); //~ ERROR c::TS + check(m4::TS); //~ ERROR c::Item +} +fn xf34() { + check(xm3::TS{}); //~ ERROR c::Item + check(xm3::TS); //~ ERROR c::TS + check(xm4::TS{}); //~ ERROR c::TS + check(xm4::TS); //~ ERROR c::Item +} + +mod m5 { + pub use ::proxy::*; + pub type US = ::c::Item; +} +mod m6 { + pub use ::proxy::*; + pub const US: ::c::Item = ::c::Item; +} + +fn f56() { + check(m5::US{}); //~ ERROR c::Item + check(m5::US); //~ ERROR c::US + check(m6::US{}); //~ ERROR c::US + check(m6::US); //~ ERROR c::Item +} +fn xf56() { + check(xm5::US{}); //~ ERROR c::Item + check(xm5::US); //~ ERROR c::US + check(xm6::US{}); //~ ERROR c::US + check(xm6::US); //~ ERROR c::Item +} + +mod m7 { + pub use ::proxy::*; + pub type V = ::c::Item; +} +mod m8 { + pub use ::proxy::*; + pub const V: ::c::Item = ::c::Item; +} + +fn f78() { + check(m7::V{}); //~ ERROR c::Item + check(m7::V); //~ ERROR name of a struct or struct variant + check(m8::V{}); //~ ERROR c::E + check(m8::V); //~ ERROR c::Item +} +fn xf78() { + check(xm7::V{}); //~ ERROR c::Item + check(xm7::V); //~ ERROR name of a struct or struct variant + check(xm8::V{}); //~ ERROR c::E + check(xm8::V); //~ ERROR c::Item +} + +mod m9 { + pub use ::proxy::*; + pub type TV = ::c::Item; +} +mod mA { + pub use ::proxy::*; + pub const TV: ::c::Item = ::c::Item; +} + +fn f9A() { + check(m9::TV{}); //~ ERROR c::Item + check(m9::TV); //~ ERROR c::E + check(mA::TV{}); //~ ERROR c::E + check(mA::TV); //~ ERROR c::Item +} +fn xf9A() { + check(xm9::TV{}); //~ ERROR c::Item + check(xm9::TV); //~ ERROR c::E + check(xmA::TV{}); //~ ERROR c::E + check(xmA::TV); //~ ERROR c::Item +} + +mod mB { + pub use ::proxy::*; + pub type UV = ::c::Item; +} +mod mC { + pub use ::proxy::*; + pub const UV: ::c::Item = ::c::Item; +} + +fn fBC() { + check(mB::UV{}); //~ ERROR c::Item + check(mB::UV); //~ ERROR c::E + check(mC::UV{}); //~ ERROR c::E + check(mC::UV); //~ ERROR c::Item +} +fn xfBC() { + check(xmB::UV{}); //~ ERROR c::Item + check(xmB::UV); //~ ERROR c::E + check(xmC::UV{}); //~ ERROR c::E + check(xmC::UV); //~ ERROR c::Item +} + +fn main() {} diff --git a/src/test/compile-fail/pat-shadow-in-nested-binding.rs b/src/test/compile-fail/pat-shadow-in-nested-binding.rs index f1683e51c648d..3dbe08f1908d7 100644 --- a/src/test/compile-fail/pat-shadow-in-nested-binding.rs +++ b/src/test/compile-fail/pat-shadow-in-nested-binding.rs @@ -11,5 +11,5 @@ struct foo(usize); fn main() { - let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow structs + let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow tuple structs } diff --git a/src/test/compile-fail/pat-tuple-overfield.rs b/src/test/compile-fail/pat-tuple-overfield.rs index 034ef4a72e21c..069c1dc0aea1b 100644 --- a/src/test/compile-fail/pat-tuple-overfield.rs +++ b/src/test/compile-fail/pat-tuple-overfield.rs @@ -20,9 +20,9 @@ fn main() { } match S(1, 2, 3) { S(1, 2, 3, 4) => {} - //~^ ERROR this pattern has 4 fields, but the corresponding struct has 3 fields + //~^ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields S(1, 2, .., 3, 4) => {} - //~^ ERROR this pattern has 4 fields, but the corresponding struct has 3 fields + //~^ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields _ => {} } } diff --git a/src/test/compile-fail/pattern-error-continue.rs b/src/test/compile-fail/pattern-error-continue.rs index 507012e8c5c06..e63b84594aa94 100644 --- a/src/test/compile-fail/pattern-error-continue.rs +++ b/src/test/compile-fail/pattern-error-continue.rs @@ -25,7 +25,7 @@ fn f(_c: char) {} fn main() { match A::B(1, 2) { A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but - A::D(_) => (), //~ ERROR `A::D` does not name a tuple variant or a tuple struct + A::D(_) => (), //~ ERROR expected tuple struct/variant, found unit variant `A::D` _ => () } match 'c' { diff --git a/src/test/compile-fail/qualified-path-params.rs b/src/test/compile-fail/qualified-path-params.rs index 9034e24a6fee0..82b0536a64ad4 100644 --- a/src/test/compile-fail/qualified-path-params.rs +++ b/src/test/compile-fail/qualified-path-params.rs @@ -28,7 +28,7 @@ impl S { fn main() { match 10 { ::A::f:: => {} - //~^ ERROR `Tr::A::f` does not name a unit variant, unit struct or a constant + //~^ ERROR expected unit struct/variant or constant, found method `Tr::A::f` 0 ... ::A::f:: => {} //~ ERROR only char and numeric types are allowed in range } } diff --git a/src/test/compile-fail/xcrate-private-by-default.rs b/src/test/compile-fail/xcrate-private-by-default.rs index 3bd4c780625a4..7dd4d970945e0 100644 --- a/src/test/compile-fail/xcrate-private-by-default.rs +++ b/src/test/compile-fail/xcrate-private-by-default.rs @@ -39,7 +39,7 @@ fn main() { foo::(); //~^ ERROR: enum `m` is private foo::(); - //~^ ERROR: type `n` is private + //~^ ERROR: type alias `n` is private // public items in a private mod should be inaccessible static_priv_by_default::foo::a;