Auto merge of #23423 - nikomatsakis:issue-18737-trait-subtyping, r=nrc

This upcast coercion currently never requires vtable changes. It should be generalized. 

This is a [breaking-change] -- if you have an impl on an object type like `impl SomeTrait`, then this will no longer be applicable to object types like `SomeTrait+Send`. In the standard library, this primarily affected `Any`, and this PR adds impls for `Any+Send` as to keep the API the same in practice. An alternate workaround is to use UFCS form or standalone fns. For more details, see <https://github.com/rust-lang/rust/issues/18737#issuecomment-78450798>.

r? @nrc
This commit is contained in:
bors 2015-03-17 13:29:48 +00:00
commit c64d671671
21 changed files with 248 additions and 122 deletions

View file

@ -0,0 +1,22 @@
// Copyright 2015 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.
// Check that we report an error if an upcast box is moved twice.
fn consume(_: Box<[i32]>) {
}
fn foo(b: Box<[i32;5]>) {
consume(b);
consume(b); //~ ERROR use of moved value
}
fn main() {
}

View file

@ -0,0 +1,24 @@
// Copyright 2015 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.
// Check that we report an error if an upcast box is moved twice.
trait Foo { fn dummy(&self); }
fn consume(_: Box<Foo>) {
}
fn foo(b: Box<Foo+Send>) {
consume(b);
consume(b); //~ ERROR use of moved value
}
fn main() {
}

View file

@ -12,9 +12,15 @@
#![allow(warnings)]
pub fn fail(x: Option<& (Iterator+Send)>) -> Option<&Iterator> {
// This call used to trigger an LLVM assertion because the return slot had type
// "Option<&Iterator>"* instead of "Option<&(Iterator+Send)>"*
inner(x)
// This call used to trigger an LLVM assertion because the return
// slot had type "Option<&Iterator>"* instead of
// "Option<&(Iterator+Send)>"* -- but this now yields a
// compilation error and I'm not sure how to create a comparable
// test. To ensure that this PARTICULAR failure doesn't occur
// again, though, I've left this test here, so if this ever starts
// to compile again, we can adjust the test appropriately (clearly
// it should never ICE...). -nmatsakis
inner(x) //~ ERROR mismatched types
}
pub fn inner(x: Option<& (Iterator+Send)>) -> Option<&(Iterator+Send)> {
@ -22,4 +28,4 @@ pub fn inner(x: Option<& (Iterator+Send)>) -> Option<&(Iterator+Send)> {
}
#[rustc_error]
fn main() {} //~ ERROR compilation successful
fn main() {}