Skip to content

Commit c68e963

Browse files
committed
Add Rvalue::Discriminant to retrieve discriminant
1 parent 031c116 commit c68e963

File tree

7 files changed

+60
-12
lines changed

7 files changed

+60
-12
lines changed

src/librustc/mir/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,12 @@ pub enum Rvalue<'tcx> {
997997

998998
UnaryOp(UnOp, Operand<'tcx>),
999999

1000+
/// Read the discriminant of an ADT.
1001+
///
1002+
/// Undefined (i.e. no effort is made to make it defined, but there’s no reason why it cannot
1003+
/// be defined to return, say, a 0) if ADT is not an enum.
1004+
Discriminant(Lvalue<'tcx>),
1005+
10001006
/// Creates an *uninitialized* Box
10011007
Box(Ty<'tcx>),
10021008

@@ -1111,6 +1117,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11111117
write!(fmt, "Checked{:?}({:?}, {:?})", op, a, b)
11121118
}
11131119
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
1120+
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
11141121
Box(ref t) => write!(fmt, "Box({:?})", t),
11151122
InlineAsm { ref asm, ref outputs, ref inputs } => {
11161123
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)

src/librustc/mir/tcx.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,15 @@ impl<'tcx> Lvalue<'tcx> {
135135
impl<'tcx> Rvalue<'tcx> {
136136
pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>>
137137
{
138-
match self {
139-
&Rvalue::Use(ref operand) => Some(operand.ty(mir, tcx)),
140-
&Rvalue::Repeat(ref operand, ref count) => {
138+
match *self {
139+
Rvalue::Use(ref operand) => Some(operand.ty(mir, tcx)),
140+
Rvalue::Repeat(ref operand, ref count) => {
141141
let op_ty = operand.ty(mir, tcx);
142142
let count = count.value.as_u64(tcx.sess.target.uint_type);
143143
assert_eq!(count as usize as u64, count);
144144
Some(tcx.mk_array(op_ty, count as usize))
145145
}
146-
&Rvalue::Ref(reg, bk, ref lv) => {
146+
Rvalue::Ref(reg, bk, ref lv) => {
147147
let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
148148
Some(tcx.mk_ref(reg,
149149
ty::TypeAndMut {
@@ -152,27 +152,35 @@ impl<'tcx> Rvalue<'tcx> {
152152
}
153153
))
154154
}
155-
&Rvalue::Len(..) => Some(tcx.types.usize),
156-
&Rvalue::Cast(.., ty) => Some(ty),
157-
&Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
155+
Rvalue::Len(..) => Some(tcx.types.usize),
156+
Rvalue::Cast(.., ty) => Some(ty),
157+
Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
158158
let lhs_ty = lhs.ty(mir, tcx);
159159
let rhs_ty = rhs.ty(mir, tcx);
160160
Some(op.ty(tcx, lhs_ty, rhs_ty))
161161
}
162-
&Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
162+
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
163163
let lhs_ty = lhs.ty(mir, tcx);
164164
let rhs_ty = rhs.ty(mir, tcx);
165165
let ty = op.ty(tcx, lhs_ty, rhs_ty);
166166
let ty = tcx.intern_tup(&[ty, tcx.types.bool], false);
167167
Some(ty)
168168
}
169-
&Rvalue::UnaryOp(_, ref operand) => {
169+
Rvalue::UnaryOp(_, ref operand) => {
170170
Some(operand.ty(mir, tcx))
171171
}
172-
&Rvalue::Box(t) => {
172+
Rvalue::Discriminant(ref lval) => {
173+
if let ty::TyAdt(_, _) = lval.ty(mir, tcx).to_ty(tcx).sty {
174+
// TODO
175+
None
176+
} else {
177+
None
178+
}
179+
}
180+
Rvalue::Box(t) => {
173181
Some(tcx.mk_box(t))
174182
}
175-
&Rvalue::Aggregate(ref ak, ref ops) => {
183+
Rvalue::Aggregate(ref ak, ref ops) => {
176184
match *ak {
177185
AggregateKind::Array => {
178186
if let Some(operand) = ops.get(0) {
@@ -196,7 +204,7 @@ impl<'tcx> Rvalue<'tcx> {
196204
}
197205
}
198206
}
199-
&Rvalue::InlineAsm { .. } => None
207+
Rvalue::InlineAsm { .. } => None
200208
}
201209
}
202210
}

src/librustc/mir/visit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,10 @@ macro_rules! make_mir_visitor {
506506
self.visit_operand(op, location);
507507
}
508508

509+
Rvalue::Discriminant(ref $($mutability)* lvalue) => {
510+
self.visit_lvalue(lvalue, LvalueContext::Inspect, location);
511+
}
512+
509513
Rvalue::Box(ref $($mutability)* ty) => {
510514
self.visit_ty(ty);
511515
}

src/librustc_borrowck/borrowck/mir/gather_moves.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
435435
}
436436
}
437437
Rvalue::Ref(..) |
438+
Rvalue::Discriminant(..) |
438439
Rvalue::Len(..) |
439440
Rvalue::InlineAsm { .. } => {}
440441
Rvalue::Box(..) => {

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
739739
}
740740
}
741741

742+
Rvalue::Discriminant(..) => {
743+
// FIXME discriminant
744+
self.add(Qualif::NOT_CONST);
745+
if self.mode != Mode::Fn {
746+
bug!("implement discriminant const qualify");
747+
}
748+
}
749+
742750
Rvalue::Box(_) => {
743751
self.add(Qualif::NOT_CONST);
744752
if self.mode != Mode::Fn {

src/librustc_passes/mir_stats.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
186186
Rvalue::BinaryOp(..) => "Rvalue::BinaryOp",
187187
Rvalue::CheckedBinaryOp(..) => "Rvalue::CheckedBinaryOp",
188188
Rvalue::UnaryOp(..) => "Rvalue::UnaryOp",
189+
Rvalue::Discriminant(..) => "Rvalue::Discriminant",
189190
Rvalue::Box(..) => "Rvalue::Box",
190191
Rvalue::Aggregate(ref kind, ref _operands) => {
191192
// AggregateKind is not distinguished by visit API, so

src/librustc_trans/mir/rvalue.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,24 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
429429
})
430430
}
431431

432+
mir::Rvalue::Discriminant(ref lvalue) => {
433+
let discr_lvalue = self.trans_lvalue(&bcx, lvalue);
434+
let enum_ty = discr_lvalue.ty.to_ty(bcx.tcx());
435+
let discr_ty = rvalue.ty(&*self.mir, bcx.tcx()).unwrap();
436+
let discr_type = type_of::immediate_type_of(bcx.ccx, discr_ty);
437+
// FIXME: inline this
438+
let discr = adt::trans_get_discr(&bcx, enum_ty, discr_lvalue.llval, None, true);
439+
let discr = if common::val_ty(discr) == Type::i1(bcx.ccx) {
440+
bcx.zext(discr, discr_type)
441+
} else {
442+
bcx.trunc(discr, discr_type)
443+
};
444+
(bcx, OperandRef {
445+
val: OperandValue::Immediate(discr),
446+
ty: discr_ty
447+
})
448+
}
449+
432450
mir::Rvalue::Box(content_ty) => {
433451
let content_ty: Ty<'tcx> = self.monomorphize(&content_ty);
434452
let llty = type_of::type_of(bcx.ccx, content_ty);
@@ -657,6 +675,7 @@ pub fn rvalue_creates_operand(rvalue: &mir::Rvalue) -> bool {
657675
mir::Rvalue::BinaryOp(..) |
658676
mir::Rvalue::CheckedBinaryOp(..) |
659677
mir::Rvalue::UnaryOp(..) |
678+
mir::Rvalue::Discriminant(..) |
660679
mir::Rvalue::Box(..) |
661680
mir::Rvalue::Use(..) =>
662681
true,

0 commit comments

Comments
 (0)