parent
c492a2126f
commit
5209709e46
@ -1701,7 +1701,7 @@ pub fn trans_match_inner(scope_cx: block,
|
||||
None
|
||||
}
|
||||
};
|
||||
let lldiscr = discr_datum.to_ref_llval(bcx);
|
||||
let lldiscr = discr_datum.to_zeroable_ref_llval(bcx);
|
||||
compile_submatch(bcx, matches, [lldiscr], chk);
|
||||
|
||||
let mut arm_cxs = ~[];
|
||||
|
@ -471,6 +471,31 @@ pub impl Datum {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_zeroable_ref_llval(&self, bcx: block) -> ValueRef {
|
||||
/*!
|
||||
* Returns a by-ref llvalue that can be zeroed in order to
|
||||
* cancel cleanup. This is a kind of hokey bridge used
|
||||
* to adapt to the match code. Please don't use it for new code.
|
||||
*/
|
||||
|
||||
match self.mode {
|
||||
// All by-ref datums are zeroable, even if we *could* just
|
||||
// cancel the cleanup.
|
||||
ByRef(_) => self.val,
|
||||
|
||||
// By value datums can't be zeroed (where would you store
|
||||
// the zero?) so we have to spill them. Add a temp cleanup
|
||||
// for this spilled value and cancel the cleanup on this
|
||||
// current value.
|
||||
ByValue => {
|
||||
let slot = self.to_ref_llval(bcx);
|
||||
self.cancel_clean(bcx);
|
||||
add_clean_temp_mem(bcx, slot, self.ty);
|
||||
slot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn appropriate_mode(&self) -> DatumMode {
|
||||
/*! See the `appropriate_mode()` function */
|
||||
|
||||
|
12
src/test/run-pass/match-vec-rvalue.rs
Normal file
12
src/test/run-pass/match-vec-rvalue.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// Tests that matching rvalues with drops does not crash.
|
||||
|
||||
fn main() {
|
||||
match ~[1, 2, 3] {
|
||||
x => {
|
||||
assert_eq!(x.len(), 3);
|
||||
assert_eq!(x[0], 1);
|
||||
assert_eq!(x[1], 2);
|
||||
assert_eq!(x[2], 3);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user