Skip to content

Commit bd291ce

Browse files
committed
Turn some impossible definitions into ICEs
1 parent 75d6522 commit bd291ce

File tree

18 files changed

+161
-238
lines changed

18 files changed

+161
-238
lines changed

src/librustc/hir/def.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,34 @@ pub enum CtorKind {
2525

2626
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2727
pub enum Def {
28-
Fn(DefId),
29-
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
28+
// Type namespace
3029
Mod(DefId),
31-
Static(DefId, bool /* is_mutbl */),
32-
Const(DefId),
33-
AssociatedConst(DefId),
34-
Local(DefId),
35-
Variant(DefId),
36-
VariantCtor(DefId, CtorKind),
30+
Struct(DefId), // DefId refers to NodeId of the struct itself
31+
Union(DefId),
3732
Enum(DefId),
33+
Variant(DefId),
34+
Trait(DefId),
3835
TyAlias(DefId),
3936
AssociatedTy(DefId),
40-
Trait(DefId),
4137
PrimTy(hir::PrimTy),
4238
TyParam(DefId),
39+
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
40+
41+
// Value namespace
42+
Fn(DefId),
43+
Const(DefId),
44+
Static(DefId, bool /* is_mutbl */),
45+
StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor
46+
VariantCtor(DefId, CtorKind),
47+
Method(DefId),
48+
AssociatedConst(DefId),
49+
Local(DefId),
4350
Upvar(DefId, // def id of closed over local
4451
usize, // index in the freevars list of the closure
4552
ast::NodeId), // expr node that creates the closure
46-
Struct(DefId), // DefId refers to NodeId of the struct itself
47-
StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor
48-
Union(DefId),
4953
Label(ast::NodeId),
50-
Method(DefId),
54+
55+
// Both namespaces
5156
Err,
5257
}
5358

src/librustc/hir/lowering.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ use hir;
4444
use hir::map::Definitions;
4545
use hir::map::definitions::DefPathData;
4646
use hir::def_id::{DefIndex, DefId};
47-
use hir::def::{Def, PathResolution};
47+
use hir::def::{Def, CtorKind, PathResolution};
4848
use session::Session;
49+
use lint;
4950

5051
use std::collections::BTreeMap;
5152
use std::iter;
@@ -855,10 +856,23 @@ impl<'a> LoweringContext<'a> {
855856
})
856857
}
857858
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
858-
PatKind::TupleStruct(ref pth, ref pats, ddpos) => {
859-
hir::PatKind::TupleStruct(self.lower_path(pth),
860-
pats.iter().map(|x| self.lower_pat(x)).collect(),
861-
ddpos)
859+
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
860+
match self.resolver.get_resolution(p.id).map(|d| d.base_def) {
861+
Some(def @ Def::StructCtor(_, CtorKind::Const)) |
862+
Some(def @ Def::VariantCtor(_, CtorKind::Const)) => {
863+
// Temporarily lower `UnitVariant(..)` into `UnitVariant`
864+
// for backward compatibility.
865+
let msg = format!("expected tuple struct/variant, found {} `{}`",
866+
def.kind_name(), path);
867+
self.sess.add_lint(
868+
lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
869+
p.id, p.span, msg
870+
);
871+
hir::PatKind::Path(None, self.lower_path(path))
872+
}
873+
_ => hir::PatKind::TupleStruct(self.lower_path(path),
874+
pats.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
875+
}
862876
}
863877
PatKind::Path(ref opt_qself, ref path) => {
864878
let opt_qself = opt_qself.as_ref().map(|qself| {

src/librustc/hir/pat_util.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
5858
PatKind::Path(..) |
5959
PatKind::Struct(..) => {
6060
match dm.get(&pat.id).map(|d| d.full_def()) {
61-
Some(Def::Variant(..)) => true,
61+
Some(Def::Variant(..)) | Some(Def::VariantCtor(..)) => true,
6262
_ => false
6363
}
6464
}
@@ -173,11 +173,9 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
173173
PatKind::TupleStruct(..) |
174174
PatKind::Path(..) |
175175
PatKind::Struct(..) => {
176-
match dm.get(&p.id) {
177-
Some(&PathResolution { base_def: Def::Variant(id), .. }) |
178-
Some(&PathResolution { base_def: Def::VariantCtor(id, ..), .. }) => {
179-
variants.push(id);
180-
}
176+
match dm.get(&p.id).map(|d| d.full_def()) {
177+
Some(Def::Variant(id)) |
178+
Some(Def::VariantCtor(id, ..)) => variants.push(id),
181179
_ => ()
182180
}
183181
}

src/librustc/middle/dead.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
106106
self.check_def_id(def.def_id());
107107
}
108108
_ if self.ignore_non_const_paths => (),
109-
Def::PrimTy(_) => (),
110-
Def::SelfTy(..) => (),
109+
Def::PrimTy(..) | Def::SelfTy(..) => (),
111110
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
112111
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
113112
self.check_def_id(enum_id);

src/librustc/middle/expr_use_visitor.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
10211021
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
10221022
delegate.matched_pat(pat, cmt_pat, match_mode);
10231023
}
1024-
_ => {}
1024+
None | Some(Def::Local(..)) |
1025+
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {}
1026+
def => bug!("unexpected definition: {:?}", def)
10251027
}
10261028
}));
10271029
}

src/librustc/middle/mem_categorization.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use hir::def_id::DefId;
7474
use hir::map as ast_map;
7575
use infer::InferCtxt;
7676
use middle::const_qualif::ConstQualif;
77-
use hir::def::Def;
77+
use hir::def::{Def, CtorKind};
7878
use ty::adjustment;
7979
use ty::{self, Ty, TyCtxt};
8080

@@ -524,22 +524,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
524524
id, expr_ty, def);
525525

526526
match def {
527-
Def::StructCtor(..) | Def::Union(..) | Def::VariantCtor(..) | Def::Const(..) |
527+
Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
528528
Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) => {
529529
Ok(self.cat_rvalue_node(id, span, expr_ty))
530530
}
531531

532-
Def::Mod(_) |
533-
Def::Trait(_) | Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(_) |
534-
Def::TyParam(..) |
535-
Def::Label(_) | Def::SelfTy(..) |
536-
Def::Variant(..) |
537-
Def::Struct(..) |
538-
Def::AssociatedTy(..) => {
539-
span_bug!(span, "Unexpected definition in \
540-
memory categorization: {:?}", def);
541-
}
542-
543532
Def::Static(_, mutbl) => {
544533
Ok(Rc::new(cmt_ {
545534
id:id,
@@ -600,7 +589,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
600589
}))
601590
}
602591

603-
Def::Err => bug!("Def::Err in memory categorization")
592+
def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
604593
}
605594
}
606595

@@ -1095,11 +1084,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10951084
match pat.node {
10961085
PatKind::TupleStruct(_, ref subpats, ddpos) => {
10971086
let expected_len = match self.tcx().expect_def(pat.id) {
1098-
Def::VariantCtor(def_id, ..) => {
1087+
Def::VariantCtor(def_id, CtorKind::Fn) => {
10991088
let enum_def = self.tcx().parent_def_id(def_id).unwrap();
11001089
self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len()
11011090
}
1102-
Def::StructCtor(..) => {
1091+
Def::StructCtor(_, CtorKind::Fn) => {
11031092
match self.pat_ty(&pat)?.sty {
11041093
ty::TyAdt(adt_def, _) => {
11051094
adt_def.struct_variant().fields.len()

src/librustc/middle/stability.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
617617
&Option<DeprecationEntry>)) {
618618
// Paths in import prefixes may have no resolution.
619619
match tcx.expect_def_or_none(id) {
620-
Some(Def::PrimTy(..)) => {}
621-
Some(Def::SelfTy(..)) => {}
622-
Some(def) => {
623-
maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
624-
}
625-
None => {}
620+
None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => {}
621+
Some(def) => maybe_do_stability_check(tcx, def.def_id(), path.span, cb)
626622
}
627623
}
628624

@@ -631,12 +627,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
631627
cb: &mut FnMut(DefId, Span,
632628
&Option<&Stability>,
633629
&Option<DeprecationEntry>)) {
634-
match tcx.expect_def(item.node.id) {
635-
Def::PrimTy(..) => {}
636-
def => {
637-
maybe_do_stability_check(tcx, def.def_id(), item.span, cb);
638-
}
639-
}
630+
maybe_do_stability_check(tcx, tcx.expect_def(item.node.id).def_id(), item.span, cb);
640631
}
641632

642633
pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,

src/librustc_const_eval/check_match.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -913,10 +913,10 @@ pub fn specialize<'a, 'b, 'tcx>(
913913
Def::Const(..) | Def::AssociatedConst(..) =>
914914
span_bug!(pat_span, "const pattern should've \
915915
been rewritten"),
916-
Def::VariantCtor(id, ..) if *constructor != Variant(id) => None,
917-
Def::VariantCtor(..) | Def::StructCtor(..) => Some(Vec::new()),
918-
def => span_bug!(pat_span, "specialize: unexpected \
919-
definition {:?}", def),
916+
Def::VariantCtor(id, CtorKind::Const) if *constructor != Variant(id) => None,
917+
Def::VariantCtor(_, CtorKind::Const) |
918+
Def::StructCtor(_, CtorKind::Const) => Some(Vec::new()),
919+
def => span_bug!(pat_span, "specialize: unexpected definition: {:?}", def),
920920
}
921921
}
922922

@@ -925,8 +925,9 @@ pub fn specialize<'a, 'b, 'tcx>(
925925
Def::Const(..) | Def::AssociatedConst(..) =>
926926
span_bug!(pat_span, "const pattern should've \
927927
been rewritten"),
928-
Def::VariantCtor(id, ..) if *constructor != Variant(id) => None,
929-
Def::VariantCtor(..) | Def::StructCtor(..) => {
928+
Def::VariantCtor(id, CtorKind::Fn) if *constructor != Variant(id) => None,
929+
Def::VariantCtor(_, CtorKind::Fn) |
930+
Def::StructCtor(_, CtorKind::Fn) => {
930931
match ddpos {
931932
Some(ddpos) => {
932933
let mut pats: Vec<_> = args[..ddpos].iter().map(|p| {
@@ -939,7 +940,7 @@ pub fn specialize<'a, 'b, 'tcx>(
939940
None => Some(args.iter().map(|p| wpat(p)).collect())
940941
}
941942
}
942-
_ => None
943+
def => span_bug!(pat_span, "specialize: unexpected definition: {:?}", def),
943944
}
944945
}
945946

src/librustc_const_eval/eval.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc::hir::map as ast_map;
1919
use rustc::hir::map::blocks::FnLikeNode;
2020
use rustc::middle::cstore::InlinedItem;
2121
use rustc::traits;
22-
use rustc::hir::def::{Def, PathResolution};
22+
use rustc::hir::def::{Def, CtorKind, PathResolution};
2323
use rustc::hir::def_id::DefId;
2424
use rustc::hir::pat_util::def_to_path;
2525
use rustc::ty::{self, Ty, TyCtxt};
@@ -287,8 +287,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
287287
entry.insert(PathResolution::new(def));
288288
}
289289
let path = match def {
290-
Def::StructCtor(def_id, ..) => def_to_path(tcx, def_id),
291-
Def::VariantCtor(variant_did, ..) => def_to_path(tcx, variant_did),
290+
Def::StructCtor(def_id, CtorKind::Fn) |
291+
Def::VariantCtor(def_id, CtorKind::Fn) => def_to_path(tcx, def_id),
292292
Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat {
293293
id: expr.id,
294294
node: PatKind::Lit(P(expr.clone())),
@@ -326,7 +326,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
326326

327327
hir::ExprPath(_, ref path) => {
328328
match tcx.expect_def(expr.id) {
329-
Def::StructCtor(..) | Def::VariantCtor(..) => PatKind::Path(None, path.clone()),
329+
Def::StructCtor(_, CtorKind::Const) |
330+
Def::VariantCtor(_, CtorKind::Const) => PatKind::Path(None, path.clone()),
330331
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
331332
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
332333
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();

src/librustc_mir/hair/cx/expr.rs

+13-26
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
271271
// Tuple-like ADTs are represented as ExprCall. We convert them here.
272272
expr_ty.ty_adt_def().and_then(|adt_def|{
273273
match cx.tcx.expect_def(fun.id) {
274-
Def::VariantCtor(variant_id, ..) => {
274+
Def::VariantCtor(variant_id, CtorKind::Fn) => {
275275
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
276276
},
277-
Def::StructCtor(..) => {
277+
Def::StructCtor(_, CtorKind::Fn) => {
278278
Some((adt_def, 0))
279279
},
280280
_ => None
@@ -670,38 +670,25 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
670670
// Otherwise there may be def_map borrow conflicts
671671
let def = cx.tcx.expect_def(expr.id);
672672
let def_id = match def {
673-
// A regular function.
674-
Def::Fn(def_id) | Def::Method(def_id) => def_id,
673+
// A regular function, constructor function or a constant.
674+
Def::Fn(def_id) | Def::Method(def_id) |
675675
Def::StructCtor(def_id, CtorKind::Fn) |
676-
Def::VariantCtor(def_id, CtorKind::Fn) => def_id,
677-
Def::StructCtor(_, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty {
678-
// A unit struct which is used as a value. We return a completely different ExprKind
679-
// here to account for this special case.
676+
Def::VariantCtor(def_id, CtorKind::Fn) |
677+
Def::Const(def_id) | Def::AssociatedConst(def_id) => def_id,
678+
679+
Def::StructCtor(def_id, CtorKind::Const) |
680+
Def::VariantCtor(def_id, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty {
681+
// A unit struct/variant which is used as a value.
682+
// We return a completely different ExprKind here to account for this special case.
680683
ty::TyAdt(adt_def, substs) => return ExprKind::Adt {
681684
adt_def: adt_def,
682-
variant_index: 0,
685+
variant_index: adt_def.variant_index_with_id(def_id),
683686
substs: substs,
684687
fields: vec![],
685-
base: None
686-
},
687-
ref sty => bug!("unexpected sty: {:?}", sty)
688-
},
689-
Def::VariantCtor(def_id, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty {
690-
// A unit variant, similar special case to the struct case above.
691-
ty::TyAdt(adt_def, substs) => {
692-
let index = adt_def.variant_index_with_id(def_id);
693-
return ExprKind::Adt {
694-
adt_def: adt_def,
695-
substs: substs,
696-
variant_index: index,
697-
fields: vec![],
698-
base: None
699-
};
688+
base: None,
700689
},
701690
ref sty => bug!("unexpected sty: {:?}", sty)
702691
},
703-
Def::Const(def_id) |
704-
Def::AssociatedConst(def_id) => def_id,
705692

706693
Def::Static(node_id, _) => return ExprKind::StaticRef {
707694
id: node_id,

src/librustc_passes/static_recursion.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use rustc::dep_graph::DepNode;
1515
use rustc::hir::map as ast_map;
1616
use rustc::session::{CompileResult, Session};
17-
use rustc::hir::def::{Def, DefMap};
17+
use rustc::hir::def::{Def, CtorKind, DefMap};
1818
use rustc::util::nodemap::NodeMap;
1919

2020
use syntax::ast;
@@ -272,7 +272,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
272272
// affect the specific variant used, but we need to check
273273
// the whole enum definition to see what expression that
274274
// might be (if any).
275-
Some(Def::VariantCtor(variant_id, ..)) => {
275+
Some(Def::VariantCtor(variant_id, CtorKind::Const)) => {
276276
if let Some(variant_id) = self.ast_map.as_local_node_id(variant_id) {
277277
let variant = self.ast_map.expect_variant(variant_id);
278278
let enum_id = self.ast_map.get_parent(variant_id);

0 commit comments

Comments
 (0)