From 46990ad1116024ed7e6de00b3678dcd1733df967 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 6 Sep 2012 15:42:59 -0700 Subject: [PATCH] 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 --- src/rustc/middle/kind.rs | 14 +++++++++++--- src/test/{run-pass => compile-fail}/issue-2548.rs | 10 ++++++---- src/test/run-pass/monad.rs | 4 ++-- src/test/run-pass/static-impl.rs | 4 ++-- src/test/run-pass/trait-generic.rs | 6 +++--- 5 files changed, 24 insertions(+), 14 deletions(-) rename src/test/{run-pass => compile-fail}/issue-2548.rs (55%) diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index b1396472d86f2..68cf5ab354c06 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -241,17 +241,25 @@ fn check_arm(a: arm, cx: ctx, v: visit::vt) { fn check_expr(e: @expr, cx: ctx, v: visit::vt) { debug!("kind::check_expr(%s)", expr_to_str(e, cx.tcx.sess.intr())); + let id_to_use = match e.node { + expr_index(*)|expr_assign_op(*)| + expr_unary(*)|expr_binary(*) => e.callee_id, + _ => e.id + }; // Handle any kind bounds on type parameters - do option::iter(cx.tcx.node_type_substs.find(e.id)) |ts| { + do option::iter(cx.tcx.node_type_substs.find(id_to_use)) |ts| { let bounds = match e.node { expr_path(_) => { let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id)); ty::lookup_item_type(cx.tcx, did).bounds } _ => { - // Type substitions should only occur on paths and + // Type substitutions should only occur on paths and // method calls, so this needs to be a method call. + + // Even though the callee_id may have been the id with + // node_type_substs, e.id is correct here. ty::method_call_bounds(cx.tcx, cx.method_map, e.id).expect( ~"non path/method call expr has type substs??") } @@ -265,7 +273,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { *bounds, (*bounds).len()); } do vec::iter2(ts, *bounds) |ty, bound| { - check_bounds(cx, e.id, e.span, ty, bound) + check_bounds(cx, id_to_use, e.span, ty, bound) } } diff --git a/src/test/run-pass/issue-2548.rs b/src/test/compile-fail/issue-2548.rs similarity index 55% rename from src/test/run-pass/issue-2548.rs rename to src/test/compile-fail/issue-2548.rs index 9506bd7eda280..091707065dc17 100644 --- a/src/test/run-pass/issue-2548.rs +++ b/src/test/compile-fail/issue-2548.rs @@ -1,11 +1,8 @@ // A test case for #2548. -// xfail-test - struct foo { x: @mut int; - new(x: @mut int) { self.x = x; } drop { io::println("Goodbye, World!"); @@ -13,6 +10,10 @@ struct foo { } } +fn foo(x: @mut int) -> foo { + foo { x: x } +} + fn main() { let x = @mut 0; @@ -20,7 +21,8 @@ fn main() { let mut res = foo(x); let mut v = ~[mut]; - v <- ~[mut res] + v; + v <- ~[mut res] + v; //~ ERROR instantiating a type parameter with an incompatible type (needs `copy`, got `owned`, missing `copy`) + assert (v.len() == 2); } assert *x == 1; diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 8b47c6bb798ca..d3f8c668edbf4 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -1,9 +1,9 @@ trait vec_monad { - fn bind(f: fn(A) -> ~[B]) -> ~[B]; + fn bind(f: fn(A) -> ~[B]) -> ~[B]; } impl ~[A]: vec_monad { - fn bind(f: fn(A) -> ~[B]) -> ~[B] { + fn bind(f: fn(A) -> ~[B]) -> ~[B] { let mut r = ~[]; for self.each |elt| { r += f(elt); } r diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index 853243d3ea835..f338dcef57712 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -28,13 +28,13 @@ impl uint: uint_utils { trait vec_utils { fn length_() -> uint; fn iter_(f: fn(T)); - fn map_(f: fn(T) -> U) -> ~[U]; + fn map_(f: fn(T) -> U) -> ~[U]; } impl ~[T]: vec_utils { fn length_() -> uint { vec::len(self) } fn iter_(f: fn(T)) { for self.each |x| { f(x); } } - fn map_(f: fn(T) -> U) -> ~[U] { + fn map_(f: fn(T) -> U) -> ~[U] { let mut r = ~[]; for self.each |elt| { r += ~[f(elt)]; } r diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index 4019ca72bd6a3..95709971e03d2 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -5,17 +5,17 @@ impl int: to_str { fn to_str() -> ~str { int::str(self) } } impl ~str: to_str { - fn to_str() -> ~str { self } + fn to_str() -> ~str { copy self } } impl (): to_str { fn to_str() -> ~str { ~"()" } } trait map { - fn map(f: fn(T) -> U) -> ~[U]; + fn map(f: fn(T) -> U) -> ~[U]; } impl ~[T]: map { - fn map(f: fn(T) -> U) -> ~[U] { + fn map(f: fn(T) -> U) -> ~[U] { let mut r = ~[]; for self.each |x| { r += ~[f(x)]; } r