Skip to content

Commit 5f3c141

Browse files
Ariel Ben-Yehudaarielb1
authored andcommitted
use VariantDef instead of struct_fields
1 parent 4816e60 commit 5f3c141

File tree

36 files changed

+892
-1441
lines changed

36 files changed

+892
-1441
lines changed

src/librustc/diagnostics.rs

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -692,64 +692,6 @@ There's no easy fix for this, generally code will need to be refactored so that
692692
you no longer need to derive from `Super<Self>`.
693693
"####,
694694

695-
E0079: r##"
696-
Enum variants which contain no data can be given a custom integer
697-
representation. This error indicates that the value provided is not an integer
698-
literal and is therefore invalid.
699-
700-
For example, in the following code,
701-
702-
```
703-
enum Foo {
704-
Q = "32"
705-
}
706-
```
707-
708-
we try to set the representation to a string.
709-
710-
There's no general fix for this; if you can work with an integer then just set
711-
it to one:
712-
713-
```
714-
enum Foo {
715-
Q = 32
716-
}
717-
```
718-
719-
however if you actually wanted a mapping between variants and non-integer
720-
objects, it may be preferable to use a method with a match instead:
721-
722-
```
723-
enum Foo { Q }
724-
impl Foo {
725-
fn get_str(&self) -> &'static str {
726-
match *self {
727-
Foo::Q => "32",
728-
}
729-
}
730-
}
731-
```
732-
"##,
733-
734-
E0080: r##"
735-
This error indicates that the compiler was unable to sensibly evaluate an
736-
integer expression provided as an enum discriminant. Attempting to divide by 0
737-
or causing integer overflow are two ways to induce this error. For example:
738-
739-
```
740-
enum Enum {
741-
X = (1 << 500),
742-
Y = (1 / 0)
743-
}
744-
```
745-
746-
Ensure that the expressions given can be evaluated as the desired integer type.
747-
See the FFI section of the Reference for more information about using a custom
748-
integer type:
749-
750-
https://doc.rust-lang.org/reference.html#ffi-attributes
751-
"##,
752-
753695
E0109: r##"
754696
You tried to give a type parameter to a type which doesn't need it. Erroneous
755697
code example:
@@ -1937,6 +1879,5 @@ register_diagnostics! {
19371879
E0314, // closure outlives stack frame
19381880
E0315, // cannot invoke closure outside of its lifetime
19391881
E0316, // nested quantification of lifetimes
1940-
E0370, // discriminant overflow
19411882
E0400 // overloaded derefs are not allowed in constants
19421883
}

src/librustc/middle/cast.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,14 @@ pub enum CastKind {
5858
}
5959

6060
impl<'tcx> CastTy<'tcx> {
61-
pub fn from_ty(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>)
62-
-> Option<CastTy<'tcx>> {
61+
pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
6362
match t.sty {
6463
ty::TyBool => Some(CastTy::Int(IntTy::Bool)),
6564
ty::TyChar => Some(CastTy::Int(IntTy::Char)),
6665
ty::TyInt(_) => Some(CastTy::Int(IntTy::I)),
6766
ty::TyUint(u) => Some(CastTy::Int(IntTy::U(u))),
6867
ty::TyFloat(_) => Some(CastTy::Float),
69-
ty::TyEnum(..) if t.is_c_like_enum(tcx) =>
68+
ty::TyEnum(d,_) if d.is_payloadfree() =>
7069
Some(CastTy::Int(IntTy::CEnum)),
7170
ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)),
7271
ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)),

src/librustc/middle/check_match.rs

Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
237237
if let ty::TyEnum(edef, _) = pat_ty.sty {
238238
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
239239
if let Some(DefLocal(_)) = def {
240-
if cx.tcx.enum_variants(edef.did).iter().any(|variant|
240+
if edef.variants.iter().any(|variant|
241241
variant.name == ident.node.name
242-
&& variant.args.is_empty()
242+
&& variant.kind() == VariantKind::Unit
243243
) {
244244
span_warn!(cx.tcx.sess, p.span, E0170,
245245
"pattern binding `{}` is named the same as one \
@@ -508,16 +508,10 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
508508
let pat = match left_ty.sty {
509509
ty::TyTuple(_) => ast::PatTup(pats.collect()),
510510

511-
ty::TyEnum(cid, _) | ty::TyStruct(cid, _) => {
512-
let (vid, is_structure) = match ctor {
513-
&Variant(vid) =>
514-
(vid, cx.tcx.enum_variant_with_id(cid.did, vid).arg_names.is_some()),
515-
_ =>
516-
(cid.did, !cid.struct_variant().is_tuple_struct())
517-
};
518-
if is_structure {
519-
let fields = cx.tcx.lookup_struct_fields(vid);
520-
let field_pats: Vec<_> = fields.into_iter()
511+
ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => {
512+
let v = adt.variant_of_ctor(ctor);
513+
if let VariantKind::Dict = v.kind() {
514+
let field_pats: Vec<_> = v.fields.iter()
521515
.zip(pats)
522516
.filter(|&(_, ref pat)| pat.node != ast::PatWild(ast::PatWildSingle))
523517
.map(|(field, pat)| Spanned {
@@ -529,9 +523,9 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
529523
}
530524
}).collect();
531525
let has_more_fields = field_pats.len() < pats_len;
532-
ast::PatStruct(def_to_path(cx.tcx, vid), field_pats, has_more_fields)
526+
ast::PatStruct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
533527
} else {
534-
ast::PatEnum(def_to_path(cx.tcx, vid), Some(pats.collect()))
528+
ast::PatEnum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
535529
}
536530
}
537531

@@ -580,6 +574,15 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
580574
})
581575
}
582576

577+
impl<'tcx> ADTDef<'tcx> {
578+
fn variant_of_ctor(&'tcx self, ctor: &Constructor) -> &'tcx VariantDef<'tcx> {
579+
match ctor {
580+
&Variant(vid) => self.variant_with_id(vid),
581+
_ => self.struct_variant()
582+
}
583+
}
584+
}
585+
583586
fn missing_constructor(cx: &MatchCheckCtxt, &Matrix(ref rows): &Matrix,
584587
left_ty: Ty, max_slice_length: usize) -> Option<Constructor> {
585588
let used_constructors: Vec<Constructor> = rows.iter()
@@ -594,7 +597,7 @@ fn missing_constructor(cx: &MatchCheckCtxt, &Matrix(ref rows): &Matrix,
594597
/// values of type `left_ty`. For vectors, this would normally be an infinite set
595598
/// but is instead bounded by the maximum fixed length of slice patterns in
596599
/// the column of patterns being analyzed.
597-
fn all_constructors(cx: &MatchCheckCtxt, left_ty: Ty,
600+
fn all_constructors(_cx: &MatchCheckCtxt, left_ty: Ty,
598601
max_slice_length: usize) -> Vec<Constructor> {
599602
match left_ty.sty {
600603
ty::TyBool =>
@@ -603,17 +606,11 @@ fn all_constructors(cx: &MatchCheckCtxt, left_ty: Ty,
603606
ty::TyRef(_, ty::TypeAndMut { ty, .. }) => match ty.sty {
604607
ty::TySlice(_) =>
605608
range_inclusive(0, max_slice_length).map(|length| Slice(length)).collect(),
606-
_ => vec!(Single)
609+
_ => vec![Single]
607610
},
608611

609-
ty::TyEnum(edef, _) =>
610-
cx.tcx.enum_variants(edef.did)
611-
.iter()
612-
.map(|va| Variant(va.id))
613-
.collect(),
614-
615-
_ =>
616-
vec!(Single)
612+
ty::TyEnum(def, _) => def.variants.iter().map(|v| Variant(v.did)).collect(),
613+
_ => vec![Single]
617614
}
618615
}
619616

@@ -804,7 +801,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
804801
///
805802
/// For instance, a tuple pattern (_, 42, Some([])) has the arity of 3.
806803
/// A struct pattern's arity is the number of fields it contains, etc.
807-
pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize {
804+
pub fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize {
808805
match ty.sty {
809806
ty::TyTuple(ref fs) => fs.len(),
810807
ty::TyBox(_) => 1,
@@ -817,13 +814,9 @@ pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usi
817814
ty::TyStr => 0,
818815
_ => 1
819816
},
820-
ty::TyEnum(edef, _) => {
821-
match *ctor {
822-
Variant(id) => cx.tcx.enum_variant_with_id(edef.did, id).args.len(),
823-
_ => unreachable!()
824-
}
817+
ty::TyEnum(adt, _) | ty::TyStruct(adt, _) => {
818+
adt.variant_of_ctor(ctor).fields.len()
825819
}
826-
ty::TyStruct(cdef, _) => cx.tcx.lookup_struct_fields(cdef.did).len(),
827820
ty::TyArray(_, n) => n,
828821
_ => 0
829822
}
@@ -902,39 +895,20 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
902895
}
903896

904897
ast::PatStruct(_, ref pattern_fields, _) => {
905-
// Is this a struct or an enum variant?
906898
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
907-
let class_id = match def {
908-
DefConst(..) | DefAssociatedConst(..) =>
909-
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
910-
been rewritten"),
911-
DefVariant(_, variant_id, _) => if *constructor == Variant(variant_id) {
912-
Some(variant_id)
913-
} else {
914-
None
915-
},
916-
_ => {
917-
// Assume this is a struct.
918-
match cx.tcx.node_id_to_type(pat_id).ty_to_def_id() {
919-
None => {
920-
cx.tcx.sess.span_bug(pat_span,
921-
"struct pattern wasn't of a \
922-
type with a def ID?!")
923-
}
924-
Some(def_id) => Some(def_id),
925-
}
926-
}
927-
};
928-
class_id.map(|variant_id| {
929-
let struct_fields = cx.tcx.lookup_struct_fields(variant_id);
930-
let args = struct_fields.iter().map(|sf| {
899+
let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap();
900+
let variant = adt.variant_of_ctor(constructor);
901+
let def_variant = adt.variant_of_def(def);
902+
if variant.did == def_variant.did {
903+
Some(variant.fields.iter().map(|sf| {
931904
match pattern_fields.iter().find(|f| f.node.ident.name == sf.name) {
932905
Some(ref f) => &*f.node.pat,
933906
_ => DUMMY_WILD_PAT
934907
}
935-
}).collect();
936-
args
937-
})
908+
}).collect())
909+
} else {
910+
None
911+
}
938912
}
939913

940914
ast::PatTup(ref args) =>

src/librustc/middle/dead.rs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -100,51 +100,32 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
100100
}
101101

102102
fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) {
103-
match self.tcx.expr_ty_adjusted(lhs).sty {
104-
ty::TyStruct(def, _) => {
105-
let fields = self.tcx.lookup_struct_fields(def.did);
106-
let field_id = fields.iter()
107-
.find(|field| field.name == name).unwrap().id;
108-
self.live_symbols.insert(field_id.node);
109-
},
110-
_ => ()
103+
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
104+
self.live_symbols.insert(def.struct_variant().field_named(name).did.node);
105+
} else {
106+
self.tcx.sess.span_bug(lhs.span, "named field access on non-struct")
111107
}
112108
}
113109

114110
fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) {
115-
match self.tcx.expr_ty_adjusted(lhs).sty {
116-
ty::TyStruct(def, _) => {
117-
let fields = self.tcx.lookup_struct_fields(def.did);
118-
let field_id = fields[idx].id;
119-
self.live_symbols.insert(field_id.node);
120-
},
121-
_ => ()
111+
if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
112+
self.live_symbols.insert(def.struct_variant().fields[idx].did.node);
122113
}
123114
}
124115

125116
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
126117
pats: &[codemap::Spanned<ast::FieldPat>]) {
127-
let id = match self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def() {
128-
def::DefVariant(_, id, _) => id,
129-
_ => {
130-
match self.tcx.node_id_to_type(lhs.id).ty_to_def_id() {
131-
None => {
132-
self.tcx.sess.span_bug(lhs.span,
133-
"struct pattern wasn't of a \
134-
type with a def ID?!")
135-
}
136-
Some(def_id) => def_id,
137-
}
138-
}
118+
let def = self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def();
119+
let pat_ty = self.tcx.node_id_to_type(lhs.id);
120+
let variant = match pat_ty.sty {
121+
ty::TyStruct(adt, _) | ty::TyEnum(adt, _) => adt.variant_of_def(def),
122+
_ => self.tcx.sess.span_bug(lhs.span, "non-ADT in struct pattern")
139123
};
140-
let fields = self.tcx.lookup_struct_fields(id);
141124
for pat in pats {
142125
if let ast::PatWild(ast::PatWildSingle) = pat.node.pat.node {
143126
continue;
144127
}
145-
let field_id = fields.iter()
146-
.find(|field| field.name == pat.node.ident.name).unwrap().id;
147-
self.live_symbols.insert(field_id.node);
128+
self.live_symbols.insert(variant.field_named(pat.node.ident.name).did.node);
148129
}
149130
}
150131

src/librustc/middle/expr_use_visitor.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -694,40 +694,36 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
694694

695695
// Select just those fields of the `with`
696696
// expression that will actually be used
697-
let with_fields = match with_cmt.ty.sty {
698-
ty::TyStruct(def, substs) => {
699-
self.tcx().struct_fields(def.did, substs)
700-
}
701-
_ => {
702-
// the base expression should always evaluate to a
703-
// struct; however, when EUV is run during typeck, it
704-
// may not. This will generate an error earlier in typeck,
705-
// so we can just ignore it.
706-
if !self.tcx().sess.has_errors() {
707-
self.tcx().sess.span_bug(
708-
with_expr.span,
709-
"with expression doesn't evaluate to a struct");
697+
if let ty::TyStruct(def, substs) = with_cmt.ty.sty {
698+
// Consume those fields of the with expression that are needed.
699+
for with_field in &def.struct_variant().fields {
700+
if !contains_field_named(with_field, fields) {
701+
let cmt_field = self.mc.cat_field(
702+
&*with_expr,
703+
with_cmt.clone(),
704+
with_field.name,
705+
with_field.ty(self.tcx(), substs)
706+
);
707+
self.delegate_consume(with_expr.id, with_expr.span, cmt_field);
710708
}
711-
vec!()
712709
}
713-
};
714-
715-
// Consume those fields of the with expression that are needed.
716-
for with_field in &with_fields {
717-
if !contains_field_named(with_field, fields) {
718-
let cmt_field = self.mc.cat_field(&*with_expr,
719-
with_cmt.clone(),
720-
with_field.name,
721-
with_field.mt.ty);
722-
self.delegate_consume(with_expr.id, with_expr.span, cmt_field);
710+
} else {
711+
// the base expression should always evaluate to a
712+
// struct; however, when EUV is run during typeck, it
713+
// may not. This will generate an error earlier in typeck,
714+
// so we can just ignore it.
715+
if !self.tcx().sess.has_errors() {
716+
self.tcx().sess.span_bug(
717+
with_expr.span,
718+
"with expression doesn't evaluate to a struct");
723719
}
724-
}
720+
};
725721

726722
// walk the with expression so that complex expressions
727723
// are properly handled.
728724
self.walk_expr(with_expr);
729725

730-
fn contains_field_named(field: &ty::Field,
726+
fn contains_field_named(field: &ty::FieldDef,
731727
fields: &Vec<ast::Field>)
732728
-> bool
733729
{
@@ -1105,7 +1101,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
11051101

11061102
Some(def::DefVariant(enum_did, variant_did, _is_struct)) => {
11071103
let downcast_cmt =
1108-
if tcx.enum_is_univariant(enum_did) {
1104+
if tcx.lookup_adt_def(enum_did).is_univariant() {
11091105
cmt_pat
11101106
} else {
11111107
let cmt_pat_ty = cmt_pat.ty;

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
12161216
let cmt = match opt_def {
12171217
Some(def::DefVariant(enum_did, variant_did, _))
12181218
// univariant enums do not need downcasts
1219-
if !self.tcx().enum_is_univariant(enum_did) => {
1219+
if !self.tcx().lookup_adt_def(enum_did).is_univariant() => {
12201220
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
12211221
}
12221222
_ => cmt

0 commit comments

Comments
 (0)