Skip to content

Commit afb2077

Browse files
committed
Fix freezing of @mut Objects when passing as argument
1 parent 0d817ee commit afb2077

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

src/librustc/middle/typeck/infer/coercion.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ impl Coerce {
121121
};
122122
}
123123

124-
ty::ty_trait(_, _, ty::RegionTraitStore(*), _, _) => {
124+
ty::ty_trait(_, _, ty::RegionTraitStore(*), m, _) => {
125125
return do self.unpack_actual_value(a) |sty_a| {
126-
self.coerce_borrowed_object(a, sty_a, b)
126+
self.coerce_borrowed_object(a, sty_a, b, m)
127127
};
128128
}
129129

@@ -274,24 +274,23 @@ impl Coerce {
274274
fn coerce_borrowed_object(&self,
275275
a: ty::t,
276276
sty_a: &ty::sty,
277-
b: ty::t) -> CoerceResult
277+
b: ty::t,
278+
b_mutbl: ast::mutability) -> CoerceResult
278279
{
279280
debug!("coerce_borrowed_object(a=%s, sty_a=%?, b=%s)",
280281
a.inf_str(self.infcx), sty_a,
281282
b.inf_str(self.infcx));
282283

283284
let tcx = self.infcx.tcx;
284285
let r_a = self.infcx.next_region_var(Coercion(self.trace));
285-
let trt_mut;
286286

287287
let a_borrowed = match *sty_a {
288288
ty::ty_trait(_, _, ty::RegionTraitStore(_), _, _) => {
289289
return self.subtype(a, b);
290290
}
291-
ty::ty_trait(did, ref substs, _, m, b) => {
292-
trt_mut = m;
291+
ty::ty_trait(did, ref substs, _, _, b) => {
293292
ty::mk_trait(tcx, did, substs.clone(),
294-
ty::RegionTraitStore(r_a), m, b)
293+
ty::RegionTraitStore(r_a), b_mutbl, b)
295294
}
296295
_ => {
297296
return self.subtype(a, b);
@@ -301,7 +300,7 @@ impl Coerce {
301300
if_ok!(self.tys(a_borrowed, b));
302301
Ok(Some(@AutoDerefRef(AutoDerefRef {
303302
autoderefs: 0,
304-
autoref: Some(AutoBorrowObj(r_a, trt_mut))
303+
autoref: Some(AutoBorrowObj(r_a, b_mutbl))
305304
})))
306305
}
307306

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// error-pattern:borrowed
2+
3+
trait Foo {
4+
fn foo(&self, @mut int);
5+
}
6+
7+
impl Foo for int {
8+
fn foo(&self, x: @mut int) {
9+
*x += *self;
10+
}
11+
}
12+
13+
fn it_takes_two(f: &Foo, g: &mut Foo) {
14+
}
15+
16+
fn main() {
17+
let x = @mut 3_i;
18+
let y = x as @mut Foo;
19+
let z = y;
20+
21+
it_takes_two(y, z);
22+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we can coerce an `@Object` to an `&Object`
12+
13+
trait Foo {
14+
fn foo(&self) -> uint;
15+
fn bar(&mut self) -> uint;
16+
}
17+
18+
impl Foo for uint {
19+
fn foo(&self) -> uint {
20+
*self
21+
}
22+
23+
fn bar(&mut self) -> uint {
24+
*self += 1;
25+
*self
26+
}
27+
}
28+
29+
fn do_it_mut(obj: &mut Foo) {
30+
let x = obj.bar();
31+
let y = obj.foo();
32+
assert_eq!(x, y);
33+
}
34+
35+
fn do_it_imm(obj: &Foo, v: uint) {
36+
let y = obj.foo();
37+
assert_eq!(v, y);
38+
}
39+
40+
fn main() {
41+
let x = @mut 22u as @mut Foo;
42+
do_it_mut(x);
43+
do_it_imm(x, 23u);
44+
}

0 commit comments

Comments
 (0)