Skip to content

Commit ba922a4

Browse files
committed
Fix handling of temp cleanups for the "self" argument
The code that tried to revoke the cleanup for the self argument tried to use "llself" to do so, but the cleanup might actually be registered with a different ValueRef due to e.g. casting. Currently, this is worked around by early revocation of the cleanup for self in trans_self_arg. To handle this correctly, we have to put the ValueRef for the cleanup into the MethodData, so trans_call_inner can use it to revoke the cleanup when it's actually supposed to.
1 parent 2a40c5d commit ba922a4

File tree

2 files changed

+23
-25
lines changed

2 files changed

+23
-25
lines changed

src/librustc/middle/trans/callee.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub struct FnData {
6262
pub struct MethodData {
6363
llfn: ValueRef,
6464
llself: ValueRef,
65+
temp_cleanup: Option<ValueRef>,
6566
self_ty: ty::t,
6667
self_mode: ty::SelfMode,
6768
explicit_self: ast::explicit_self_
@@ -646,9 +647,10 @@ pub fn trans_call_inner(in_cx: block,
646647
// Now that the arguments have finished evaluating, we need to revoke
647648
// the cleanup for the self argument, if it exists
648649
match callee.data {
649-
Method(d) if d.self_mode == ty::ByCopy ||
650-
d.explicit_self == ast::sty_value => {
651-
revoke_clean(bcx, d.llself);
650+
Method(d) => {
651+
for d.temp_cleanup.iter().advance |&v| {
652+
revoke_clean(bcx, v);
653+
}
652654
}
653655
_ => {}
654656
}

src/librustc/middle/trans/meth.rs

+18-22
Original file line numberDiff line numberDiff line change
@@ -129,28 +129,20 @@ pub fn trans_method(ccx: @mut CrateContext,
129129

130130
pub fn trans_self_arg(bcx: block,
131131
base: @ast::expr,
132+
temp_cleanups: &mut ~[ValueRef],
132133
mentry: typeck::method_map_entry) -> Result {
133134
let _icx = push_ctxt("impl::trans_self_arg");
134-
let mut temp_cleanups = ~[];
135135

136136
// self is passed as an opaque box in the environment slot
137137
let self_ty = ty::mk_opaque_box(bcx.tcx());
138-
let result = trans_arg_expr(bcx,
139-
self_ty,
140-
mentry.self_mode,
141-
mentry.explicit_self,
142-
base,
143-
&mut temp_cleanups,
144-
None,
145-
DontAutorefArg);
146-
147-
// FIXME(#3446)---this is wrong, actually. The temp_cleanups
148-
// should be revoked only after all arguments have been passed.
149-
for temp_cleanups.iter().advance |c| {
150-
revoke_clean(bcx, *c)
151-
}
152-
153-
return result;
138+
trans_arg_expr(bcx,
139+
self_ty,
140+
mentry.self_mode,
141+
mentry.explicit_self,
142+
base,
143+
temp_cleanups,
144+
None,
145+
DontAutorefArg)
154146
}
155147

156148
pub fn trans_method_callee(bcx: block,
@@ -203,12 +195,14 @@ pub fn trans_method_callee(bcx: block,
203195
match origin {
204196
typeck::method_static(did) => {
205197
let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
206-
let Result {bcx, val} = trans_self_arg(bcx, this, mentry);
198+
let mut temp_cleanups = ~[];
199+
let Result {bcx, val} = trans_self_arg(bcx, this, &mut temp_cleanups, mentry);
207200
Callee {
208201
bcx: bcx,
209202
data: Method(MethodData {
210203
llfn: callee_fn.llfn,
211204
llself: val,
205+
temp_cleanup: temp_cleanups.head_opt().map(|&v| *v),
212206
self_ty: node_id_type(bcx, this.id),
213207
self_mode: mentry.self_mode,
214208
explicit_self: mentry.explicit_self
@@ -254,9 +248,8 @@ pub fn trans_method_callee(bcx: block,
254248
store,
255249
mentry.explicit_self)
256250
}
257-
typeck::method_super(*) => {
258-
fail!("method_super should have been handled \
259-
above")
251+
typeck::method_super(*) => {
252+
fail!("method_super should have been handled above")
260253
}
261254
}
262255
}
@@ -413,8 +406,9 @@ pub fn trans_monomorphized_callee(bcx: block,
413406
bcx.ccx(), impl_did, mname);
414407

415408
// obtain the `self` value:
409+
let mut temp_cleanups = ~[];
416410
let Result {bcx, val: llself_val} =
417-
trans_self_arg(bcx, base, mentry);
411+
trans_self_arg(bcx, base, &mut temp_cleanups, mentry);
418412

419413
// create a concatenated set of substitutions which includes
420414
// those from the impl and those from the method:
@@ -441,6 +435,7 @@ pub fn trans_monomorphized_callee(bcx: block,
441435
data: Method(MethodData {
442436
llfn: llfn_val,
443437
llself: llself_val,
438+
temp_cleanup: temp_cleanups.head_opt().map(|&v| *v),
444439
self_ty: node_id_type(bcx, base.id),
445440
self_mode: mentry.self_mode,
446441
explicit_self: mentry.explicit_self
@@ -636,6 +631,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
636631
data: Method(MethodData {
637632
llfn: mptr,
638633
llself: llself,
634+
temp_cleanup: None,
639635
self_ty: ty::mk_opaque_box(bcx.tcx()),
640636
self_mode: ty::ByRef,
641637
explicit_self: explicit_self

0 commit comments

Comments
 (0)