Skip to content

Commit 46990ad

Browse files
committed
Use callee ID when kind-checking expressions that may be overloaded
And fix up test cases that should have failed if not for this bug. Closes #2587
1 parent c5e2cf2 commit 46990ad

File tree

5 files changed

+24
-14
lines changed

5 files changed

+24
-14
lines changed

src/rustc/middle/kind.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,17 +241,25 @@ fn check_arm(a: arm, cx: ctx, v: visit::vt<ctx>) {
241241

242242
fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
243243
debug!("kind::check_expr(%s)", expr_to_str(e, cx.tcx.sess.intr()));
244+
let id_to_use = match e.node {
245+
expr_index(*)|expr_assign_op(*)|
246+
expr_unary(*)|expr_binary(*) => e.callee_id,
247+
_ => e.id
248+
};
244249

245250
// Handle any kind bounds on type parameters
246-
do option::iter(cx.tcx.node_type_substs.find(e.id)) |ts| {
251+
do option::iter(cx.tcx.node_type_substs.find(id_to_use)) |ts| {
247252
let bounds = match e.node {
248253
expr_path(_) => {
249254
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
250255
ty::lookup_item_type(cx.tcx, did).bounds
251256
}
252257
_ => {
253-
// Type substitions should only occur on paths and
258+
// Type substitutions should only occur on paths and
254259
// method calls, so this needs to be a method call.
260+
261+
// Even though the callee_id may have been the id with
262+
// node_type_substs, e.id is correct here.
255263
ty::method_call_bounds(cx.tcx, cx.method_map, e.id).expect(
256264
~"non path/method call expr has type substs??")
257265
}
@@ -265,7 +273,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
265273
*bounds, (*bounds).len());
266274
}
267275
do vec::iter2(ts, *bounds) |ty, bound| {
268-
check_bounds(cx, e.id, e.span, ty, bound)
276+
check_bounds(cx, id_to_use, e.span, ty, bound)
269277
}
270278
}
271279

src/test/run-pass/issue-2548.rs renamed to src/test/compile-fail/issue-2548.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
// A test case for #2548.
22

3-
// xfail-test
4-
53
struct foo {
64
x: @mut int;
75

8-
new(x: @mut int) { self.x = x; }
96

107
drop {
118
io::println("Goodbye, World!");
129
*self.x += 1;
1310
}
1411
}
1512

13+
fn foo(x: @mut int) -> foo {
14+
foo { x: x }
15+
}
16+
1617
fn main() {
1718
let x = @mut 0;
1819

1920
{
2021
let mut res = foo(x);
2122

2223
let mut v = ~[mut];
23-
v <- ~[mut res] + v;
24+
v <- ~[mut res] + v; //~ ERROR instantiating a type parameter with an incompatible type (needs `copy`, got `owned`, missing `copy`)
25+
assert (v.len() == 2);
2426
}
2527

2628
assert *x == 1;

src/test/run-pass/monad.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
trait vec_monad<A> {
2-
fn bind<B>(f: fn(A) -> ~[B]) -> ~[B];
2+
fn bind<B: copy>(f: fn(A) -> ~[B]) -> ~[B];
33
}
44

55
impl<A> ~[A]: vec_monad<A> {
6-
fn bind<B>(f: fn(A) -> ~[B]) -> ~[B] {
6+
fn bind<B: copy>(f: fn(A) -> ~[B]) -> ~[B] {
77
let mut r = ~[];
88
for self.each |elt| { r += f(elt); }
99
r

src/test/run-pass/static-impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ impl uint: uint_utils {
2828
trait vec_utils<T> {
2929
fn length_() -> uint;
3030
fn iter_(f: fn(T));
31-
fn map_<U>(f: fn(T) -> U) -> ~[U];
31+
fn map_<U: copy>(f: fn(T) -> U) -> ~[U];
3232
}
3333

3434
impl<T> ~[T]: vec_utils<T> {
3535
fn length_() -> uint { vec::len(self) }
3636
fn iter_(f: fn(T)) { for self.each |x| { f(x); } }
37-
fn map_<U>(f: fn(T) -> U) -> ~[U] {
37+
fn map_<U: copy>(f: fn(T) -> U) -> ~[U] {
3838
let mut r = ~[];
3939
for self.each |elt| { r += ~[f(elt)]; }
4040
r

src/test/run-pass/trait-generic.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ impl int: to_str {
55
fn to_str() -> ~str { int::str(self) }
66
}
77
impl ~str: to_str {
8-
fn to_str() -> ~str { self }
8+
fn to_str() -> ~str { copy self }
99
}
1010
impl (): to_str {
1111
fn to_str() -> ~str { ~"()" }
1212
}
1313

1414
trait map<T> {
15-
fn map<U>(f: fn(T) -> U) -> ~[U];
15+
fn map<U: copy>(f: fn(T) -> U) -> ~[U];
1616
}
1717
impl<T> ~[T]: map<T> {
18-
fn map<U>(f: fn(T) -> U) -> ~[U] {
18+
fn map<U: copy>(f: fn(T) -> U) -> ~[U] {
1919
let mut r = ~[];
2020
for self.each |x| { r += ~[f(x)]; }
2121
r

0 commit comments

Comments
 (0)