Fix orphan checking (cc #19470). (This is not a complete fix of #19470 because of the backwards compatibility feature gate.)
This is a [breaking-change]. The new rules require that, for an impl of a trait defined
in some other crate, two conditions must hold:
1. Some type must be local.
2. Every type parameter must appear "under" some local type.
Here are some examples that are legal:
```rust
struct MyStruct<T> { ... }
// Here `T` appears "under' `MyStruct`.
impl<T> Clone for MyStruct<T> { }
// Here `T` appears "under' `MyStruct` as well. Note that it also appears
// elsewhere.
impl<T> Iterator<T> for MyStruct<T> { }
```
Here is an illegal example:
```rust
// Here `U` does not appear "under" `MyStruct` or any other local type.
// We call `U` "uncovered".
impl<T,U> Iterator<U> for MyStruct<T> { }
```
There are a couple of ways to rewrite this last example so that it is
legal:
1. In some cases, the uncovered type parameter (here, `U`) should be converted
into an associated type. This is however a non-local change that requires access
to the original trait. Also, associated types are not fully baked.
2. Add `U` as a type parameter of `MyStruct`:
```rust
struct MyStruct<T,U> { ... }
impl<T,U> Iterator<U> for MyStruct<T,U> { }
```
3. Create a newtype wrapper for `U`
```rust
impl<T,U> Iterator<Wrapper<U>> for MyStruct<T,U> { }
```
Because associated types are not fully baked, which in the case of the
`Hash` trait makes adhering to this rule impossible, you can
temporarily disable this rule in your crate by using
`#![feature(old_orphan_check)]`. Note that the `old_orphan_check`
feature will be removed before 1.0 is released.
This commit is contained in:
parent
77723d24a8
commit
c61a0092bc
26 changed files with 172 additions and 96 deletions
|
|
@ -9,6 +9,8 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![feature(opt_out_copy)]
|
||||
//~^ WARNING feature is deprecated
|
||||
//~| WARNING feature is deprecated
|
||||
|
||||
// Test that when using the `opt-out-copy` feature we still consider
|
||||
// destructors to be non-movable
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
|
||||
use serialize::{Encodable, Decodable};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
// This briefly tests the capability of `Cell` and `RefCell` to implement the
|
||||
// `Encodable` and `Decodable` traits via `#[deriving(Encodable, Decodable)]`
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
extern crate rand;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate rbml;
|
||||
extern crate serialize;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// If `Index` used an associated type for its output, this test would
|
||||
// work more smoothly.
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
struct Mat<T> { data: Vec<T>, cols: uint, }
|
||||
|
||||
impl<T> Mat<T> {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// If `Mul` used an associated type for its output, this test would
|
||||
// work more smoothly.
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
struct Vec2 {
|
||||
x: f64,
|
||||
y: f64
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
use std::ops::Fn;
|
||||
|
||||
struct G;
|
||||
struct G<A>;
|
||||
|
||||
impl<'a, A: Add<int, int>> Fn<(A,), int> for G {
|
||||
impl<'a, A: Add<int, int>> Fn<(A,), int> for G<A> {
|
||||
extern "rust-call" fn call(&self, (arg,): (A,)) -> int {
|
||||
arg.add(1)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue