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]
This commit is contained in:
Patrick Walton 2014-07-02 15:38:20 -07:00
parent 169c988d09
commit c3ae64a5cf
4 changed files with 80 additions and 1 deletions

View file

@ -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)
}

View file

@ -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);
}

View file

@ -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)));
}

View file

@ -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() {}