diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2015-03-21 13:12:08 +0100 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2015-03-24 22:27:23 +0100 |
| commit | 5b2e8693e42dee545d336c0364773b3fbded93a5 (patch) | |
| tree | 7506fd891d4f5ec60bed07cccd7c3c6a33b1d927 /src/test | |
| parent | 290c8de0a6f233b1d30c8a97cb41614fce989d30 (diff) | |
| download | rust-5b2e8693e42dee545d336c0364773b3fbded93a5.tar.gz rust-5b2e8693e42dee545d336c0364773b3fbded93a5.zip | |
Reject specialized Drop impls.
See Issue 8142 for discussion.
This makes it illegal for a Drop impl to be more specialized than the
original item.
So for example, all of the following are now rejected (when they would
have been blindly accepted before):
```rust
struct S<A> { ... };
impl Drop for S<i8> { ... } // error: specialized to concrete type
struct T<'a> { ... };
impl Drop for T<'static> { ... } // error: specialized to concrete region
struct U<A> { ... };
impl<A:Clone> Drop for U<A> { ... } // error: added extra type requirement
struct V<'a,'b>;
impl<'a,'b:a> Drop for V<'a,'b> { ... } // error: added extra region requirement
```
Due to examples like the above, this is a [breaking-change].
(The fix is to either remove the specialization from the `Drop` impl,
or to transcribe the requirements into the struct/enum definition;
examples of both are shown in the PR's fixed to `libstd`.)
----
This is likely to be the last thing blocking the removal of the
`#[unsafe_destructor]` attribute.
Includes two new error codes for the new dropck check.
Update run-pass tests to accommodate new dropck pass.
Update tests and docs to reflect new destructor restriction.
----
Implementation notes:
We identify Drop impl specialization by not being as parametric as the
struct/enum definition via unification.
More specifically:
1. Attempt unification of a skolemized instance of the struct/enum
with an instance of the Drop impl's type expression where all of
the impl's generics (i.e. the free variables of the type
expression) have been replaced with unification variables.
2. If unification fails, then reject Drop impl as specialized.
3. If unification succeeds, check if any of the skolemized
variables "leaked" into the constraint set for the inference
context; if so, then reject Drop impl as specialized.
4. Otherwise, unification succeeded without leaking skolemized
variables: accept the Drop impl.
We identify whether a Drop impl is injecting new predicates by simply
looking whether the predicate, after an appropriate substitution,
appears on the struct/enum definition.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/auxiliary/issue-2526.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/issue-15858.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/issue-15924.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/issue-2718.rs | 4 | ||||
| -rw-r--r-- | src/test/run-pass/issue-4252.rs | 2 |
5 files changed, 6 insertions, 6 deletions
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index 89b3b56121a..832665abdc2 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -15,7 +15,7 @@ use std::marker; -struct arc_destruct<T> { +struct arc_destruct<T: Sync> { _data: int, _marker: marker::PhantomData<T> } diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs index 9b300deaa49..265db3fe133 100644 --- a/src/test/run-pass/issue-15858.rs +++ b/src/test/run-pass/issue-15858.rs @@ -25,7 +25,7 @@ impl Bar for BarImpl { } -struct Foo<B>(B); +struct Foo<B: Bar>(B); #[unsafe_destructor] impl<B: Bar> Drop for Foo<B> { diff --git a/src/test/run-pass/issue-15924.rs b/src/test/run-pass/issue-15924.rs index 6af07c422ef..e544585745d 100644 --- a/src/test/run-pass/issue-15924.rs +++ b/src/test/run-pass/issue-15924.rs @@ -18,7 +18,7 @@ use std::fmt; use serialize::{Encoder, Encodable}; use serialize::json; -struct Foo<T> { +struct Foo<T: Encodable> { v: T, } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 8d0e0654933..7ca0ee01015 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -162,7 +162,7 @@ pub mod pipes { } } - pub struct send_packet<T> { + pub struct send_packet<T:Send> { p: Option<*const packet<T>>, } @@ -192,7 +192,7 @@ pub mod pipes { } } - pub struct recv_packet<T> { + pub struct recv_packet<T:Send> { p: Option<*const packet<T>>, } diff --git a/src/test/run-pass/issue-4252.rs b/src/test/run-pass/issue-4252.rs index 9d5f8576c63..08ee955cabb 100644 --- a/src/test/run-pass/issue-4252.rs +++ b/src/test/run-pass/issue-4252.rs @@ -21,7 +21,7 @@ trait X { struct Y(int); #[derive(Debug)] -struct Z<T> { +struct Z<T: X+std::fmt::Debug> { x: T } |
