diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 5a69de90d2a..8b9cee1d2f6 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -25,29 +25,34 @@ pub enum CtorKind { #[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), - VariantCtor(DefId, CtorKind), + 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), + SelfTy(Option /* trait */, Option /* impl */), + + // 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 - Struct(DefId), // DefId refers to NodeId of the struct itself - StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor - Union(DefId), Label(ast::NodeId), - Method(DefId), + + // Both namespaces Err, } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dace486b277..f56a27b9ae0 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 0e78acb15c8..0deea941463 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,11 +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), .. }) | - Some(&PathResolution { base_def: Def::VariantCtor(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/dead.rs b/src/librustc/middle/dead.rs index af22ef0bd3d..dc634b08784 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -106,8 +106,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { self.check_def_id(def.def_id()); } _ if self.ignore_non_const_paths => (), - Def::PrimTy(_) => (), - Def::SelfTy(..) => (), + 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 a03a0372e48..799c02b7403 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1021,7 +1021,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { 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 4d1151c2826..9214138d210 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,22 +524,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { id, expr_ty, def); match def { - Def::StructCtor(..) | Def::Union(..) | Def::VariantCtor(..) | 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::Variant(..) | - Def::Struct(..) | - Def::AssociatedTy(..) => { - span_bug!(span, "Unexpected definition in \ - memory categorization: {:?}", def); - } - Def::Static(_, mutbl) => { Ok(Rc::new(cmt_ { id:id, @@ -600,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) } } @@ -1095,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::VariantCtor(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::StructCtor(..) => { + 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 ccab4279232..5192575972b 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_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 287203c2f65..cf54f5908ca 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -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::VariantCtor(id, ..) if *constructor != Variant(id) => None, - Def::VariantCtor(..) | Def::StructCtor(..) => 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::VariantCtor(id, ..) if *constructor != Variant(id) => None, - Def::VariantCtor(..) | Def::StructCtor(..) => { + 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 890319d5024..d876b4b6fec 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::StructCtor(def_id, ..) => def_to_path(tcx, def_id), - Def::VariantCtor(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::StructCtor(..) | Def::VariantCtor(..) => 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(); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 926b0dc1fc1..a6c5cd1eeea 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -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::VariantCtor(variant_id, ..) => { + Def::VariantCtor(variant_id, CtorKind::Fn) => { Some((adt_def, adt_def.variant_index_with_id(variant_id))) }, - Def::StructCtor(..) => { + Def::StructCtor(_, CtorKind::Fn) => { Some((adt_def, 0)) }, _ => None @@ -670,38 +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, + // 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_id, - Def::StructCtor(_, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty { - // A unit struct which is used as a value. We return a completely different ExprKind - // here to account for this special case. + 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 + base: None, }, ref sty => bug!("unexpected sty: {:?}", sty) }, - Def::VariantCtor(def_id, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty { - // A unit variant, similar special case to the struct case above. - ty::TyAdt(adt_def, substs) => { - let index = adt_def.variant_index_with_id(def_id); - return ExprKind::Adt { - adt_def: adt_def, - substs: substs, - variant_index: index, - fields: vec![], - 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_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 0f5a67e66fb..0e0f8a84567 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::VariantCtor(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); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index a6a1326b719..4ffe2fe3856 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; @@ -454,36 +454,25 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } } hir::ExprPath(..) => { - if let Def::StructCtor(..) = 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/lib.rs b/src/librustc_resolve/lib.rs index 49e7f3ba19c..4f41dfc8b64 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2786,8 +2786,7 @@ 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 => { + 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; diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 8dd1a7940b3..6d9cd88afb1 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,11 +301,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { }.lower(self.tcx)); } Def::Struct(..) | - Def::StructCtor(..) | + 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"), @@ -317,12 +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::VariantCtor(..) | - 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, @@ -337,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, @@ -424,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); } } } @@ -807,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 { @@ -926,15 +924,19 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } } } - Def::Local(..) | - Def::Static(..) | + Def::Fn(..) | Def::Const(..) | - Def::AssociatedConst(..) | - Def::Struct(..) | + Def::Static(..) | Def::StructCtor(..) | - Def::Variant(..) | Def::VariantCtor(..) | - Def::Fn(..) => self.write_sub_paths_truncated(path, false), + Def::AssociatedConst(..) | + Def::Local(..) | + Def::Upvar(..) | + Def::Struct(..) | + Def::Union(..) | + Def::Variant(..) | + Def::TyAlias(..) | + Def::AssociatedTy(..) => self.write_sub_paths_truncated(path, false), _ => {} } } @@ -1167,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); @@ -1225,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); } @@ -1320,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 { @@ -1490,14 +1492,12 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> }.lower(self.tcx)); } } - Def::Variant(..) | Def::VariantCtor(..) | Def::Enum(..) | - Def::TyAlias(..) | Def::Struct(..) | Def::StructCtor(..) => { + 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 0e3ee5e9fff..15c74f2ed6a 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -507,7 +507,7 @@ 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()), @@ -517,10 +517,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } Def::Struct(def_id) | - Def::StructCtor(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 { @@ -574,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_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 27491c6dfce..87729da773f 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -14,7 +14,6 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::infer::{self, InferOk, TypeOrigin}; 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}; @@ -557,17 +556,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_pat(&pat, tcx.types.err); } }; - let report_unexpected_def = |def: Def, is_lint| { + let report_unexpected_def = |def: Def| { let msg = format!("expected tuple struct/variant, found {} `{}`", def.kind_name(), 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(); - } + 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. @@ -579,15 +573,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return tcx.types.err; } Def::AssociatedConst(..) | Def::Method(..) => { - report_unexpected_def(def, false); + report_unexpected_def(def); return tcx.types.err; } - Def::VariantCtor(_, ctor_kind) | Def::StructCtor(_, ctor_kind) => { - if ctor_kind == CtorKind::Const { - // Matching unit structs with tuple variant patterns (`UnitVariant(..)`) - // is allowed for backward compatibility. - report_unexpected_def(def, true); - } + Def::VariantCtor(_, CtorKind::Fn) | + Def::StructCtor(_, CtorKind::Fn) => { tcx.expect_variant_def(def) } _ => bug!("unexpected pattern definition: {:?}", def) @@ -595,13 +585,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // 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. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4f348a7b32b..79c1c5fb5e2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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())) @@ -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*: + // 4. Reference to a local variable // - // impl AnotherStruct { - // const FOO: B = BAR; - // } - // - // 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*. + // Case 1. Reference to a struct/variant constructor. Def::StructCtor(def_id, ..) | - Def::Union(def_id) | - Def::VariantCtor(def_id, ..) | - Def::Enum(def_id) | - Def::TyAlias(def_id) | - Def::AssociatedTy(def_id) | - Def::Trait(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,19 +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::Variant(..) | - Def::Struct(..) | - 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/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 68e5bc6c21e..feca2d328fe 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -17,7 +17,6 @@ use rustc::hir; 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}; use rustc::util::nodemap::FnvHashSet; @@ -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)) } @@ -501,10 +501,8 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, 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(def) = tcx.sess.cstore.describe_def(def_id) { - if let Some(i) = try_inline_def(cx, tcx, def) { - items.extend(i) - } + if let Some(i) = try_inline_def(cx, tcx, item.def) { + items.extend(i) } } }