librustc: Match trait self types exactly.

This can break code that looked like:

    impl Foo for Box<Any> {
        fn f(&self) { ... }
    }

    let x: Box<Any + Send> = ...;
    x.f();

Change such code to:

    impl Foo for Box<Any> {
        fn f(&self) { ... }
    }

    let x: Box<Any> = ...;
    x.f();

That is, upcast before calling methods.

This is a conservative solution to #5781. A more proper treatment (see
the xfail'd `trait-contravariant-self.rs`) would take variance into
account. This change fixes the soundness hole.

Some library changes had to be made to make this work. In particular,
`Box<Any>` is no longer showable, and only `Box<Any+Send>` is showable.
Eventually, this restriction can be lifted; for now, it does not prove
too onerous, because `Any` is only used for propagating the result of
task failure.

This patch also adds a test for the variance inference work in #12828,
which accidentally landed as part of DST.

Closes #5781.

[breaking-change]
This commit is contained in:
Patrick Walton
2014-06-25 18:18:13 -07:00
parent afdfe40aa0
commit 05e3248a79
20 changed files with 214 additions and 84 deletions

View File

@@ -630,9 +630,11 @@ mod test {
let mut reader = ChanReader::new(rx);
let stdout = ChanWriter::new(tx);
TaskBuilder::new().stdout(box stdout as Box<Writer + Send>).try(proc() {
print!("Hello, world!");
}).unwrap();
let r = TaskBuilder::new().stdout(box stdout as Box<Writer + Send>)
.try(proc() {
print!("Hello, world!");
});
assert!(r.is_ok());
let output = reader.read_to_str().unwrap();
assert_eq!(output, "Hello, world!".to_string());