Skip to content

Commit cd2f34a

Browse files
authored
Merge pull request rust-lang#143 from oli-obk/master
rustup
2 parents 1af2c39 + 35502fd commit cd2f34a

File tree

5 files changed

+27
-36
lines changed

5 files changed

+27
-36
lines changed

src/eval_context.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
456456

457457
General { discr, ref variants, .. } => {
458458
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
459-
let discr_val = adt_def.variants[variant].disr_val.to_u128_unchecked();
459+
let discr_val = adt_def.variants[variant].disr_val;
460460
let discr_size = discr.size().bytes();
461461
if variants[variant].packed {
462462
let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0;
@@ -529,7 +529,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
529529
CEnum { .. } => {
530530
assert_eq!(operands.len(), 0);
531531
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
532-
let n = adt_def.variants[variant].disr_val.to_u128_unchecked();
532+
let n = adt_def.variants[variant].disr_val;
533533
self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
534534
} else {
535535
bug!("tried to assign {:?} to Layout::CEnum", kind);
@@ -661,7 +661,20 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
661661
}
662662
}
663663

664-
InlineAsm { .. } => return Err(EvalError::InlineAsm),
664+
Discriminant(ref lvalue) => {
665+
let lval = self.eval_lvalue(lvalue)?;
666+
let ty = self.lvalue_ty(lvalue);
667+
let ptr = self.force_allocation(lval)?.to_ptr();
668+
let discr_val = self.read_discriminant_value(ptr, ty)?;
669+
if let ty::TyAdt(adt_def, _) = ty.sty {
670+
if adt_def.variants.iter().all(|v| discr_val != v.disr_val) {
671+
return Err(EvalError::InvalidDiscriminant);
672+
}
673+
} else {
674+
bug!("rustc only generates Rvalue::Discriminant for enums");
675+
}
676+
self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
677+
},
665678
}
666679

667680
if log_enabled!(::log::LogLevel::Trace) {

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![feature(
22
btree_range,
33
collections,
4-
field_init_shorthand,
54
i128_type,
65
pub_restricted,
76
rustc_private,

src/step.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
119119
// Defined to do nothing. These are added by optimization passes, to avoid changing the
120120
// size of MIR constantly.
121121
Nop => {}
122+
123+
InlineAsm { .. } => return Err(EvalError::InlineAsm),
122124
}
123125

124126
self.frame_mut().stmt += 1;

src/terminator/drop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
121121
Layout::General { .. } => {
122122
let discr_val = self.read_discriminant_value(adt_ptr, ty)? as u128;
123123
let ptr = self.force_allocation(lval)?.to_ptr();
124-
match adt_def.variants.iter().position(|v| discr_val == v.disr_val.to_u128_unchecked()) {
124+
match adt_def.variants.iter().position(|v| discr_val == v.disr_val) {
125125
Some(i) => {
126126
lval = Lvalue::Ptr {
127127
ptr,

src/terminator/mod.rs

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
3535

3636
Goto { target } => self.goto_block(target),
3737

38-
If { ref cond, targets: (then_target, else_target) } => {
39-
let cond_val = self.eval_operand_to_primval(cond)?.to_bool()?;
40-
self.goto_block(if cond_val { then_target } else { else_target });
41-
}
42-
4338
SwitchInt { ref discr, ref values, ref targets, .. } => {
44-
let discr_val = self.eval_and_read_lvalue(discr)?;
45-
let discr_ty = self.lvalue_ty(discr);
39+
let discr_val = self.eval_operand(discr)?;
40+
let discr_ty = self.operand_ty(discr);
4641
let discr_prim = self.value_to_primval(discr_val, discr_ty)?;
4742

4843
// Branch to the `otherwise` case by default, if no match is found.
4944
let mut target_block = targets[targets.len() - 1];
5045

51-
for (index, const_val) in values.iter().enumerate() {
52-
let val = self.const_to_value(const_val)?;
53-
let prim = self.value_to_primval(val, discr_ty)?;
46+
for (index, const_int) in values.iter().enumerate() {
47+
let prim = PrimVal::Bytes(const_int.to_u128_unchecked());
5448
if discr_prim.to_bytes()? == prim.to_bytes()? {
5549
target_block = targets[index];
5650
break;
@@ -60,23 +54,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
6054
self.goto_block(target_block);
6155
}
6256

63-
Switch { ref discr, ref targets, adt_def } => {
64-
// FIXME(solson)
65-
let lvalue = self.eval_lvalue(discr)?;
66-
let lvalue = self.force_allocation(lvalue)?;
67-
68-
let adt_ptr = lvalue.to_ptr();
69-
let adt_ty = self.lvalue_ty(discr);
70-
let discr_val = self.read_discriminant_value(adt_ptr, adt_ty)?;
71-
let matching = adt_def.variants.iter()
72-
.position(|v| discr_val == v.disr_val.to_u128_unchecked());
73-
74-
match matching {
75-
Some(i) => self.goto_block(targets[i]),
76-
None => return Err(EvalError::InvalidDiscriminant),
77-
}
78-
}
79-
8057
Call { ref func, ref args, ref destination, .. } => {
8158
let destination = match *destination {
8259
Some((ref lv, target)) => Some((self.eval_lvalue(lv)?, target)),
@@ -216,12 +193,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
216193
trace!("layout({:?}) = {:#?}", dest_ty, dest_layout);
217194
match *dest_layout {
218195
Layout::Univariant { .. } => {
219-
let disr_val = v.disr_val.to_u128_unchecked();
196+
let disr_val = v.disr_val;
220197
assert_eq!(disr_val, 0);
221198
self.assign_fields(lvalue, dest_ty, args)?;
222199
},
223200
Layout::General { discr, ref variants, .. } => {
224-
let disr_val = v.disr_val.to_u128_unchecked();
201+
let disr_val = v.disr_val;
225202
let discr_size = discr.size().bytes();
226203
self.assign_discr_and_fields(
227204
lvalue,
@@ -234,7 +211,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
234211
)?;
235212
},
236213
Layout::StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
237-
let disr_val = v.disr_val.to_u128_unchecked();
214+
let disr_val = v.disr_val;
238215
if nndiscr as u128 == disr_val {
239216
self.assign_fields(lvalue, dest_ty, args)?;
240217
} else {
@@ -325,7 +302,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
325302
}
326303
}
327304

328-
fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
305+
pub fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
329306
use rustc::ty::layout::Layout::*;
330307
let adt_layout = self.type_layout(adt_ty)?;
331308
trace!("read_discriminant_value {:#?}", adt_layout);

0 commit comments

Comments
 (0)