about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-03-24 15:27:14 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-03-24 15:27:14 -0700
commit3b13b9c2b4e72d08cb1c68024ccc4f50001f4878 (patch)
treed4efd6426beeeee1f0c543cfe345b9625285f46e /src/test
parent91b633aa038008fdbee658a10182afdd794d2aa6 (diff)
parent1955e052675d4457432da85a00db0ae55be64e83 (diff)
downloadrust-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.rs2
-rw-r--r--src/test/compile-fail/reject-specialized-drops-8142.rs79
-rw-r--r--src/test/run-pass/issue-15858.rs2
-rw-r--r--src/test/run-pass/issue-15924.rs2
-rw-r--r--src/test/run-pass/issue-2718.rs4
-rw-r--r--src/test/run-pass/issue-4252.rs2
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
 }