Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tests for method resolution in the face of various ambiguities or non…
…-ambiguities. These are mostly new tests though I also revamped (and renamed) some of the existing tests.
- Loading branch information
1 parent
e09fc03
commit 450263d
Showing
8 changed files
with
204 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Test that when we pick a trait based on coercion, versus subtyping, | ||
// we consider all possible coercions equivalent and don't try to pick | ||
// a best one. | ||
|
||
trait Object { } | ||
|
||
trait foo { | ||
fn foo(self) -> int; | ||
} | ||
|
||
impl foo for Box<Object+'static> { | ||
fn foo(self) -> int {1} | ||
} | ||
|
||
impl foo for Box<Object+Send> { | ||
fn foo(self) -> int {2} | ||
} | ||
|
||
fn test1(x: Box<Object+Send+Sync>) { | ||
// Ambiguous because we could coerce to either impl: | ||
x.foo(); //~ ERROR E0034 | ||
} | ||
|
||
fn test2(x: Box<Object+Send>) { | ||
// Not ambiguous because it is a precise match: | ||
x.foo(); | ||
} | ||
|
||
fn test3(x: Box<Object+'static>) { | ||
// Not ambiguous because it is a precise match: | ||
x.foo(); | ||
} | ||
|
||
fn main() { } |
45 changes: 45 additions & 0 deletions
45
src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Test that we invoking `foo()` successfully resolves to the trait `foo` | ||
// (prompting the mismatched types error) but does not influence the choice | ||
// of what kind of `Vec` we have, eventually leading to a type error. | ||
|
||
trait foo { | ||
fn foo(&self) -> int; | ||
} | ||
|
||
impl foo for Vec<uint> { | ||
fn foo(&self) -> int {1} | ||
} | ||
|
||
impl foo for Vec<int> { | ||
fn foo(&self) -> int {2} | ||
} | ||
|
||
// This is very hokey: we have heuristics to suppress messages about | ||
// type annotations required. But placing these two bits of code into | ||
// distinct functions, in this order, causes us to print out both | ||
// errors I'd like to see. | ||
|
||
fn m1() { | ||
// we couldn't infer the type of the vector just based on calling foo()... | ||
let mut x = Vec::new(); //~ ERROR type annotations required | ||
x.foo(); | ||
} | ||
|
||
fn m2() { | ||
let mut x = Vec::new(); | ||
|
||
// ...but we still resolved `foo()` to the trait and hence know the return type. | ||
let y: uint = x.foo(); //~ ERROR mismatched types | ||
} | ||
|
||
fn main() { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Test that we pick `Foo`, and also pick the `impl`, even though in | ||
// this case the vector type `T` is not copyable. This is because | ||
// there is no other reasonable choice. The error you see is thus | ||
// about `T` being non-copyable, not about `Foo` being | ||
// unimplemented. This is better for user too, since it suggests minimal | ||
// diff requird to fix program. | ||
|
||
trait Object { } | ||
|
||
trait Foo { | ||
fn foo(self) -> int; | ||
} | ||
|
||
impl<T:Copy> Foo for Vec<T> { | ||
fn foo(self) -> int {1} | ||
} | ||
|
||
fn test1<T>(x: Vec<T>) { | ||
x.foo(); | ||
//~^ ERROR `core::kinds::Copy` is not implemented for the type `T` | ||
} | ||
|
||
fn main() { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Test that we pick which version of `Foo` to run based on whether | ||
// the type we (ultimately) inferred for `x` is copyable or not. | ||
// | ||
// In this case, the two versions are both impls of same trait, and | ||
// hence we we can resolve method even without knowing yet which | ||
// version will run (note that the `push` occurs after the call to | ||
// `foo()`). | ||
|
||
trait Foo { | ||
fn foo(&self) -> int; | ||
} | ||
|
||
impl<T:Copy> Foo for Vec<T> { | ||
fn foo(&self) -> int {1} | ||
} | ||
|
||
impl<T> Foo for Vec<Box<T>> { | ||
fn foo(&self) -> int {2} | ||
} | ||
|
||
fn call_foo_copy() -> int { | ||
let mut x = Vec::new(); | ||
let y = x.foo(); | ||
x.push(0u); | ||
y | ||
} | ||
|
||
fn call_foo_other() -> int { | ||
let mut x = Vec::new(); | ||
let y = x.foo(); | ||
x.push(box 0i); | ||
y | ||
} | ||
|
||
fn main() { | ||
assert_eq!(call_foo_copy(), 1); | ||
assert_eq!(call_foo_other(), 2); | ||
} |