diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2014-07-02 15:38:20 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2014-07-02 15:40:09 -0700 |
| commit | c3ae64a5cff47edcbe73885bc00e715d082ef5ec (patch) | |
| tree | 4005174e5b7ecba5556c18d742eb220852a99724 | |
| parent | 169c988d09a9d4e46de2b7fead9489e94964c7c7 (diff) | |
| download | rust-c3ae64a5cff47edcbe73885bc00e715d082ef5ec.tar.gz rust-c3ae64a5cff47edcbe73885bc00e715d082ef5ec.zip | |
librustc: Take the parameter space into account when combining type
parameters.
This can break code that mistakenly used type parameters in place of
`Self`. For example, this will break:
trait Foo {
fn bar<X>(u: X) -> Self {
u
}
}
Change this code to not contain a type error. For example:
trait Foo {
fn bar<X>(_: X) -> Self {
self
}
}
Closes #15172.
[breaking-change]
4 files changed, 80 insertions, 1 deletions
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index f374f1dc267..2984ea086ef 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -445,7 +445,8 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> { } } - (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if a_p.idx == b_p.idx => { + (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if + a_p.idx == b_p.idx && a_p.space == b_p.space => { Ok(a) } diff --git a/src/test/compile-fail/type-params-in-different-spaces-1.rs b/src/test/compile-fail/type-params-in-different-spaces-1.rs new file mode 100644 index 00000000000..6e32e6e4835 --- /dev/null +++ b/src/test/compile-fail/type-params-in-different-spaces-1.rs @@ -0,0 +1,25 @@ +// 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::num::Num; + +trait BrokenAdd: Num { + fn broken_add<T>(&self, rhs: T) -> Self { + *self + rhs //~ ERROR mismatched types + } +} + +impl<T: Num> BrokenAdd for T {} + +pub fn main() { + let foo: u8 = 0u8; + let x: u8 = foo.broken_add("hello darkness my old friend".to_string()); + println!("{}", x); +} diff --git a/src/test/compile-fail/type-params-in-different-spaces-2.rs b/src/test/compile-fail/type-params-in-different-spaces-2.rs new file mode 100644 index 00000000000..955efeef30d --- /dev/null +++ b/src/test/compile-fail/type-params-in-different-spaces-2.rs @@ -0,0 +1,35 @@ +// 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. + +trait Tr<T> { + fn op(T) -> Self; +} + +// these compile as if Self: Tr<U>, even tho only Self: Tr<Self or T> +trait A: Tr<Self> { + fn test<U>(u: U) -> Self { + Tr::op(u) //~ ERROR expected Tr<U>, but found Tr<Self> + } +} +trait B<T>: Tr<T> { + fn test<U>(u: U) -> Self { + Tr::op(u) //~ ERROR expected Tr<U>, but found Tr<T> + } +} + +impl<T> Tr<T> for T { + fn op(t: T) -> T { t } +} +impl<T> A for T {} + +fn main() { + std::io::println(A::test((&7306634593706211700, 8))); +} + diff --git a/src/test/compile-fail/type-params-in-different-spaces-3.rs b/src/test/compile-fail/type-params-in-different-spaces-3.rs new file mode 100644 index 00000000000..a3d69d53ba9 --- /dev/null +++ b/src/test/compile-fail/type-params-in-different-spaces-3.rs @@ -0,0 +1,18 @@ +// 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. + +trait Tr { + fn test<X>(u: X) -> Self { + u //~ ERROR mismatched types + } +} + +fn main() {} + |
