Turn some impossible definitions into ICEs
This commit is contained in:
parent
75d6522b9a
commit
bd291ce21a
@ -25,29 +25,34 @@ pub enum CtorKind {
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Def {
|
||||
Fn(DefId),
|
||||
SelfTy(Option<DefId> /* trait */, Option<DefId> /* 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<DefId> /* trait */, Option<DefId> /* 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,
|
||||
}
|
||||
|
||||
|
@ -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| {
|
||||
|
@ -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<DefId> {
|
||||
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),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -617,12 +617,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
&Option<DeprecationEntry>)) {
|
||||
// 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<DeprecationEntry>)) {
|
||||
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,
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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::<Vec<_>>();
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<DefId> {
|
||||
fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
|
||||
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),
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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<T> { ... } }
|
||||
//
|
||||
// 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<T>` 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<T>(...)
|
||||
// enum E<T> { foo(...) }
|
||||
// struct Foo<T>(...)
|
||||
// enum E<T> { 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<T>() { }
|
||||
//
|
||||
@ -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<A> SomeStruct<A> {
|
||||
// fn foo<B>(...)
|
||||
@ -4112,15 +4093,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// `SomeStruct::<A>`, contains parameters in TypeSpace, and the
|
||||
// final segment, `foo::<B>` contains parameters in fn space.
|
||||
//
|
||||
// 4. Reference to an *associated const*:
|
||||
// 4. Reference to a local variable
|
||||
//
|
||||
// impl<A> AnotherStruct<A> {
|
||||
// const FOO: B = BAR;
|
||||
// }
|
||||
//
|
||||
// The path in this case will look like
|
||||
// `a::b::AnotherStruct::<A>::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 `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user