diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-03-24 15:27:14 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-03-24 15:27:14 -0700 |
| commit | 3b13b9c2b4e72d08cb1c68024ccc4f50001f4878 (patch) | |
| tree | d4efd6426beeeee1f0c543cfe345b9625285f46e /src/test | |
| parent | 91b633aa038008fdbee658a10182afdd794d2aa6 (diff) | |
| parent | 1955e052675d4457432da85a00db0ae55be64e83 (diff) | |
| download | rust-3b13b9c2b4e72d08cb1c68024ccc4f50001f4878.tar.gz rust-3b13b9c2b4e72d08cb1c68024ccc4f50001f4878.zip | |
rollup merge of #23638: pnkfelix/fsk-reject-specialized-drops
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.
Fix #8142
Fix #23584
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/auxiliary/issue-2526.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/reject-specialized-drops-8142.rs | 79 | ||||
| -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 |
6 files changed, 85 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/compile-fail/reject-specialized-drops-8142.rs b/src/test/compile-fail/reject-specialized-drops-8142.rs new file mode 100644 index 00000000000..30264c9f218 --- /dev/null +++ b/src/test/compile-fail/reject-specialized-drops-8142.rs @@ -0,0 +1,79 @@ +// 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. + +// Issue 8142: Test that Drop impls cannot be specialized beyond the +// predicates attached to the struct/enum definition itself. + +#![feature(unsafe_destructor)] + +trait Bound { fn foo(&self) { } } +struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } +struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } +struct M<'m> { x: &'m i8 } +struct N<'n> { x: &'n i8 } +struct O<To> { x: *const To } +struct P<Tp> { x: *const Tp } +struct Q<Tq> { x: *const Tq } +struct R<Tr> { x: *const Tr } +struct S<Ts:Bound> { x: *const Ts } +struct T<'t,Ts:'t> { x: &'t Ts } +struct U; +struct V<Tva, Tvb> { x: *const Tva, y: *const Tvb } +struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } + +#[unsafe_destructor] +impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> { // REJECT + //~^ ERROR The requirement `'adds_bnd : 'al` is added only by the Drop impl. + fn drop(&mut self) { } } + +#[unsafe_destructor] +impl<'al,'adds_bnd> Drop for L<'al,'adds_bnd> where 'adds_bnd:'al { // REJECT + //~^ ERROR The requirement `'adds_bnd : 'al` is added only by the Drop impl. + fn drop(&mut self) { } } + +#[unsafe_destructor] +impl<'ml> Drop for M<'ml> { fn drop(&mut self) { } } // ACCEPT + +#[unsafe_destructor] +impl Drop for N<'static> { fn drop(&mut self) { } } // REJECT +//~^ ERROR Implementations of Drop cannot be specialized + +#[unsafe_destructor] +impl<Cok_nobound> Drop for O<Cok_nobound> { fn drop(&mut self) { } } // ACCEPT + +#[unsafe_destructor] +impl Drop for P<i8> { fn drop(&mut self) { } } // REJECT +//~^ ERROR Implementations of Drop cannot be specialized + +#[unsafe_destructor] +impl<Adds_bnd:Bound> Drop for Q<Adds_bnd> { fn drop(&mut self) { } } // REJECT +//~^ ERROR The requirement `Adds_bnd : Bound` is added only by the Drop impl. + +#[unsafe_destructor] +impl<'rbnd,Adds_rbnd:'rbnd> Drop for R<Adds_rbnd> { fn drop(&mut self) { } } // REJECT +//~^ ERROR The requirement `Adds_rbnd : 'rbnd` is added only by the Drop impl. + +#[unsafe_destructor] +impl<Bs:Bound> Drop for S<Bs> { fn drop(&mut self) { } } // ACCEPT + +#[unsafe_destructor] +impl<'t,Bt:'t> Drop for T<'t,Bt> { fn drop(&mut self) { } } // ACCEPT + +impl Drop for U { fn drop(&mut self) { } } // ACCEPT + +#[unsafe_destructor] +impl<One> Drop for V<One,One> { fn drop(&mut self) { } } // REJECT +//~^ERROR Implementations of Drop cannot be specialized + +#[unsafe_destructor] +impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT +//~^ERROR Implementations of Drop cannot be specialized + +pub fn main() { } 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 } |
