diff options
| author | bors <bors@rust-lang.org> | 2014-10-22 00:22:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-10-22 00:22:04 +0000 |
| commit | 3d2cf60631502567007ea652f8ef299d907ee2c3 (patch) | |
| tree | 7a65e1e976689d56faaa783ae54218cdf4ebffa4 /src/test | |
| parent | 2130f2221600f03129df95f3611444468806b237 (diff) | |
| parent | b066d09be8454d735972e056d6b978cf48a85009 (diff) | |
| download | rust-3d2cf60631502567007ea652f8ef299d907ee2c3.tar.gz rust-3d2cf60631502567007ea652f8ef299d907ee2c3.zip | |
auto merge of #18121 : nikomatsakis/rust/method-call-use-trait-matching-infrastructure-2, r=pcwalton
Convert trait method dispatch to use new trait matching machinery.
This fixes about 90% of #17918. What remains to be done is to make inherent dispatch work with conditional dispatch as well. I plan to do this in a future patch by generalizing the "method match" code slightly to work for inherent impls as well (the basic algorithm is precisely the same).
Fixes #17178.
This is a [breaking-change] for two reasons:
1. The old code was a bit broken. I found various minor cases, particularly around operators, where the old code incorrectly matched, but an extra `*` or other change is now required. (See commit e8cef25 ("Correct case where the old version of method lookup...") for examples.)
2. The old code didn't type check calls against the method signature from the *trait* but rather the *impl*. The two can be different in subtle ways. This makes the new method dispatch both more liberal and more conservative than the original. (See commit 8308332 ("The new method lookup mechanism typechecks...") for examples.)
r? @pcwalton since he's been reviewing most of this series of changes
f? @nick29581 for commit 39df55f ("Permit DST types to unify like other types")
cc @aturon as this relates to library stabilization
Diffstat (limited to 'src/test')
21 files changed, 322 insertions, 34 deletions
diff --git a/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs b/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs index 1e9fd035f44..000e42b9703 100644 --- a/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs +++ b/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs @@ -9,7 +9,7 @@ // except according to those terms. // Check that method bounds declared on traits/impls in a cross-crate -// scenario work. This is the libary portion of the test. +// scenario work. This is the library portion of the test. pub enum MaybeOwned<'a> { Owned(int), @@ -24,10 +24,19 @@ pub struct Inv<'a> { // invariant w/r/t 'a // trait, so I'll use that as the template for this test. pub trait IntoMaybeOwned<'a> { fn into_maybe_owned(self) -> MaybeOwned<'a>; + + // Note: without this `into_inv` method, the trait is + // contravariant w/r/t `'a`, since if you look strictly at the + // interface, it only returns `'a`. This complicates the + // downstream test since it wants invariance to force an error. + // Hence we add this method. + fn into_inv(self) -> Inv<'a>; + fn bigger_region<'b:'a>(self, b: Inv<'b>); } impl<'a> IntoMaybeOwned<'a> for Inv<'a> { fn into_maybe_owned(self) -> MaybeOwned<'a> { fail!() } + fn into_inv(self) -> Inv<'a> { fail!() } fn bigger_region<'b:'a>(self, b: Inv<'b>) { fail!() } } diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs new file mode 100644 index 00000000000..c0d82d35e30 --- /dev/null +++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs @@ -0,0 +1,38 @@ +// Copyright 2014 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. + +use std::fmt::Show; +use std::default::Default; + +// Test that two blanket impls conflict (at least without negative +// bounds). After all, some other crate could implement Even or Odd +// for the same type (though this crate doesn't). + +trait MyTrait { + fn get(&self) -> uint; +} + +trait Even { } + +trait Odd { } + +impl Even for int { } + +impl Odd for uint { } + +impl<T:Even> MyTrait for T { //~ ERROR E0119 + fn get(&self) -> uint { 0 } +} + +impl<T:Odd> MyTrait for T { + fn get(&self) -> uint { 0 } +} + +fn main() { } diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs new file mode 100644 index 00000000000..c44844bcf0b --- /dev/null +++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs @@ -0,0 +1,34 @@ +// Copyright 2014 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. + +use std::fmt::Show; +use std::default::Default; + +// Test that two blanket impls conflict (at least without negative +// bounds). After all, some other crate could implement Even or Odd +// for the same type (though this crate doesn't implement them at all). + +trait MyTrait { + fn get(&self) -> uint; +} + +trait Even { } + +trait Odd { } + +impl<T:Even> MyTrait for T { //~ ERROR E0119 + fn get(&self) -> uint { 0 } +} + +impl<T:Odd> MyTrait for T { + fn get(&self) -> uint { 0 } +} + +fn main() { } diff --git a/src/test/compile-fail/issue-17033.rs b/src/test/compile-fail/issue-17033.rs index 35adb29c949..7590546d40a 100644 --- a/src/test/compile-fail/issue-17033.rs +++ b/src/test/compile-fail/issue-17033.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(overloaded_calls)] + fn f<'r>(p: &'r mut fn(p: &mut ())) { - p(()) //~ ERROR expected function, found `&'r mut fn(&mut ())` + p(()) //~ ERROR mismatched types: expected `&mut ()`, found `()` } fn main() {} diff --git a/src/test/compile-fail/issue-17636.rs b/src/test/compile-fail/issue-17636.rs index 635a184a9d3..ad2ebff59bc 100644 --- a/src/test/compile-fail/issue-17636.rs +++ b/src/test/compile-fail/issue-17636.rs @@ -15,5 +15,5 @@ pub fn build_archive<'a, I: MyItem<&'a (|&uint|:'a)>>(files: I) {} fn main() { build_archive(&(|_| { })); -//~^ ERROR unable to infer enough type information to locate the impl of the trait `MyItem<&|&uint| +//~^ ERROR not implemented } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index 81f57dd9640..19d210f1905 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -18,6 +18,7 @@ impl<A> vec_monad<A> for Vec<A> { let mut r = fail!(); for elt in self.iter() { r = r + f(*elt); } //~^ ERROR the type of this value must be known + //~^^ ERROR not implemented } } fn main() { diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs index 768177785cf..d5a1040d4b4 100644 --- a/src/test/compile-fail/issue-7575.rs +++ b/src/test/compile-fail/issue-7575.rs @@ -8,17 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Test the mechanism for warning about possible missing `self` declarations. + trait CtxtFn { fn f8(self, uint) -> uint; - fn f9(uint) -> uint; //~ NOTE candidate # + fn f9(uint) -> uint; //~ NOTE candidate } trait OtherTrait { - fn f9(uint) -> uint; //~ NOTE candidate # + fn f9(uint) -> uint; //~ NOTE candidate } -trait UnusedTrait { // This should never show up as a candidate - fn f9(uint) -> uint; +// Note: this trait is not implemented, but we can't really tell +// whether or not an impl would match anyhow without a self +// declaration to match against, so we wind up printing it as a +// candidate. This seems not unreasonable -- perhaps the user meant to +// implement it, after all. +trait UnusedTrait { + fn f9(uint) -> uint; //~ NOTE candidate } impl CtxtFn for uint { @@ -40,13 +47,13 @@ impl OtherTrait for uint { struct MyInt(int); impl MyInt { - fn fff(i: int) -> int { //~ NOTE candidate #1 is `MyInt::fff` + fn fff(i: int) -> int { //~ NOTE candidate i } } trait ManyImplTrait { - fn is_str() -> bool { //~ NOTE candidate #1 is + fn is_str() -> bool { //~ NOTE candidate false } } diff --git a/src/test/compile-fail/method-ambig-one-trait-coerce.rs b/src/test/compile-fail/method-ambig-one-trait-coerce.rs new file mode 100644 index 00000000000..e5c3da10df8 --- /dev/null +++ b/src/test/compile-fail/method-ambig-one-trait-coerce.rs @@ -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() { } diff --git a/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs b/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs new file mode 100644 index 00000000000..e211db2dcd2 --- /dev/null +++ b/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs @@ -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() { } diff --git a/src/test/compile-fail/ambig_impl_2_exe.rs b/src/test/compile-fail/method-ambig-two-traits-cross-crate.rs index 13cceaa71ae..30e635149c4 100644 --- a/src/test/compile-fail/ambig_impl_2_exe.rs +++ b/src/test/compile-fail/method-ambig-two-traits-cross-crate.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Test an ambiguity scenario where one copy of the method is available +// from a trait imported from another crate. + // aux-build:ambig_impl_2_lib.rs extern crate ambig_impl_2_lib; use ambig_impl_2_lib::me; trait me2 { fn me(&self) -> uint; } -impl me2 for uint { fn me(&self) -> uint { *self } } //~ NOTE is `uint.me2::me` -fn main() { 1u.me(); } //~ ERROR multiple applicable methods in scope -//~^ NOTE is `ambig_impl_2_lib::uint.me::me` +impl me2 for uint { fn me(&self) -> uint { *self } } +fn main() { 1u.me(); } //~ ERROR E0034 + diff --git a/src/test/compile-fail/ambig_impl_bounds.rs b/src/test/compile-fail/method-ambig-two-traits-from-bounds.rs index 9f26e5ae9b3..184927c0135 100644 --- a/src/test/compile-fail/ambig_impl_bounds.rs +++ b/src/test/compile-fail/method-ambig-two-traits-from-bounds.rs @@ -12,9 +12,7 @@ trait A { fn foo(&self); } trait B { fn foo(&self); } fn foo<T:A + B>(t: T) { - t.foo(); //~ ERROR multiple applicable methods in scope - //~^ NOTE candidate #1 derives from the bound `A` - //~^^ NOTE candidate #2 derives from the bound `B` + t.foo(); //~ ERROR E0034 } fn main() {} diff --git a/src/test/compile-fail/ambig-default-method.rs b/src/test/compile-fail/method-ambig-two-traits-with-default-method.rs index 56ab6d7da3f..87efaed4e3d 100644 --- a/src/test/compile-fail/ambig-default-method.rs +++ b/src/test/compile-fail/method-ambig-two-traits-with-default-method.rs @@ -8,12 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { fn method(&self) {} } //~ NOTE `Foo::method` -trait Bar { fn method(&self) {} } //~ NOTE `Bar::method` +// Test that we correctly report an ambiguity where two applicable traits +// are in scope and the method being invoked is a default method not +// defined directly in the impl. + +trait Foo { fn method(&self) {} } +trait Bar { fn method(&self) {} } impl Foo for uint {} impl Bar for uint {} fn main() { - 1u.method(); //~ ERROR multiple applicable methods in scope + 1u.method(); //~ ERROR E0034 } diff --git a/src/test/compile-fail/method-commit-to-trait.rs b/src/test/compile-fail/method-commit-to-trait.rs new file mode 100644 index 00000000000..6e4b5e088c9 --- /dev/null +++ b/src/test/compile-fail/method-commit-to-trait.rs @@ -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() { } diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs index 06f26800b50..1705cfec6e2 100644 --- a/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs +++ b/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs @@ -18,15 +18,15 @@ use lib::Inv; use lib::MaybeOwned; use lib::IntoMaybeOwned; -fn call_into_maybe_owned<'a,F:IntoMaybeOwned<'a>>(f: F) { +fn call_into_maybe_owned<'x,F:IntoMaybeOwned<'x>>(f: F) { // Exercise a code path I found to be buggy. We were not encoding // the region parameters from the receiver correctly on trait // methods. f.into_maybe_owned(); } -fn call_bigger_region<'a, 'b>(a: Inv<'a>, b: Inv<'b>) { - // Here the value provided for 'y is 'b, and hence 'b:'a does not hold. +fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) { + // Here the value provided for 'y is 'y, and hence 'y:'x does not hold. a.bigger_region(b) //~ ERROR cannot infer } diff --git a/src/test/compile-fail/selftype-traittype.rs b/src/test/compile-fail/selftype-traittype.rs index bf7c3b261fd..44ee5002dce 100644 --- a/src/test/compile-fail/selftype-traittype.rs +++ b/src/test/compile-fail/selftype-traittype.rs @@ -14,7 +14,7 @@ trait add { } fn do_add(x: Box<add+'static>, y: Box<add+'static>) -> Box<add+'static> { - x.plus(y) //~ ERROR cannot call a method whose type contains a self-type through an object + x.plus(y) //~ ERROR E0038 } fn main() {} diff --git a/src/test/compile-fail/unique-pinned-nocopy.rs b/src/test/compile-fail/unique-pinned-nocopy.rs index c812b0d96a2..0e1e66b40ce 100644 --- a/src/test/compile-fail/unique-pinned-nocopy.rs +++ b/src/test/compile-fail/unique-pinned-nocopy.rs @@ -19,6 +19,6 @@ impl Drop for r { fn main() { let i = box r { b: true }; - let _j = i.clone(); //~ ERROR not implemented + let _j = i.clone(); //~ ERROR not implement println!("{}", i); } diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 79f29c6b359..62fabc0b33f 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -35,8 +35,8 @@ fn main() { let r1 = vec!(box r { i: i1 }); let r2 = vec!(box r { i: i2 }); f(r1.clone(), r2.clone()); - //~^ ERROR the trait `core::clone::Clone` is not implemented - //~^^ ERROR the trait `core::clone::Clone` is not implemented + //~^ ERROR does not implement any method in scope named `clone` + //~^^ ERROR does not implement any method in scope named `clone` println!("{}", (r2, i1.get())); println!("{}", (r1, i2.get())); } diff --git a/src/test/compile-fail/vec-res-add.rs b/src/test/compile-fail/vec-res-add.rs index bfd52d69cb2..6221806642c 100644 --- a/src/test/compile-fail/vec-res-add.rs +++ b/src/test/compile-fail/vec-res-add.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[deriving(Show)] struct r { i:int } @@ -23,7 +24,6 @@ fn main() { let i = vec!(r(0)); let j = vec!(r(1)); let k = i + j; - //~^ ERROR not implemented + //~^ ERROR binary operation `+` cannot be applied to type println!("{}", j); - //~^ ERROR not implemented } diff --git a/src/test/compile-fail/wrong-mul-method-signature.rs b/src/test/compile-fail/wrong-mul-method-signature.rs index e3aed148a23..aead739d3e0 100644 --- a/src/test/compile-fail/wrong-mul-method-signature.rs +++ b/src/test/compile-fail/wrong-mul-method-signature.rs @@ -58,7 +58,13 @@ impl Mul<f64, i32> for Vec3 { } pub fn main() { - Vec1 { x: 1.0 } * 2.0; - Vec2 { x: 1.0, y: 2.0 } * 2.0; - Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0; + // Check that the usage goes from the trait declaration: + + let x: Vec1 = Vec1 { x: 1.0 } * 2.0; // this is OK + + let x: Vec2 = Vec2 { x: 1.0, y: 2.0 } * 2.0; // trait had reversed order + //~^ ERROR mismatched types + //~^^ ERROR mismatched types + + let x: i32 = Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0; } diff --git a/src/test/compile-fail/ambig_impl_unify.rs b/src/test/run-pass/method-two-trait-defer-resolution-1.rs index 67b7a5a7f37..e4ae33c1c50 100644 --- a/src/test/compile-fail/ambig_impl_unify.rs +++ b/src/test/run-pass/method-two-trait-defer-resolution-1.rs @@ -8,20 +8,36 @@ // 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 the +// type that is (ultimately) inferred for `x`. trait foo { fn foo(&self) -> int; } impl foo for Vec<uint> { - fn foo(&self) -> int {1} //~ NOTE candidate #1 is `Vec<uint>.foo::foo` + fn foo(&self) -> int {1} } impl foo for Vec<int> { - fn foo(&self) -> int {2} //~ NOTE candidate #2 is `Vec<int>.foo::foo` + fn foo(&self) -> int {2} +} + +fn call_foo_uint() -> int { + let mut x = Vec::new(); + let y = x.foo(); + x.push(0u); + y +} + +fn call_foo_int() -> int { + let mut x = Vec::new(); + let y = x.foo(); + x.push(0i); + y } fn main() { - let x = Vec::new(); - x.foo(); //~ ERROR multiple applicable methods in scope + assert_eq!(call_foo_uint(), 1); + assert_eq!(call_foo_int(), 2); } diff --git a/src/test/run-pass/method-two-trait-defer-resolution-2.rs b/src/test/run-pass/method-two-trait-defer-resolution-2.rs new file mode 100644 index 00000000000..cae783e7ea8 --- /dev/null +++ b/src/test/run-pass/method-two-trait-defer-resolution-2.rs @@ -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); +} |
