about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-07 17:28:38 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-07 17:28:38 -0800
commit773fdb3dbec7d8d2ace01a0e2025e1592925c285 (patch)
tree4e39c8098f6d454f95556428bcf1cb6971fa5ed7
parent6e806bdefde91af102567ef4b5dbd3ccf0c5c2ec (diff)
parent3c1ca175d131011d87a9db0ffbb833b1d884f900 (diff)
downloadrust-773fdb3dbec7d8d2ace01a0e2025e1592925c285.tar.gz
rust-773fdb3dbec7d8d2ace01a0e2025e1592925c285.zip
rollup merge of #20631: huon/no-drop-and-copy
-rw-r--r--src/librustc/middle/ty.rs9
-rw-r--r--src/librustc_typeck/coherence/mod.rs5
-rw-r--r--src/librustc_typeck/diagnostics.rs3
-rw-r--r--src/test/compile-fail/drop-on-non-struct.rs2
-rw-r--r--src/test/compile-fail/exclusive-drop-and-copy.rs30
5 files changed, 46 insertions, 3 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index be883ffdd59..e15f3a37ddb 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -6915,6 +6915,7 @@ pub enum CopyImplementationError {
     FieldDoesNotImplementCopy(ast::Name),
     VariantDoesNotImplementCopy(ast::Name),
     TypeIsStructural,
+    TypeHasDestructor,
 }
 
 pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
@@ -6924,7 +6925,7 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
 {
     let tcx = param_env.tcx;
 
-    match self_type.sty {
+    let did = match self_type.sty {
         ty::ty_struct(struct_did, substs) => {
             let fields = ty::struct_fields(tcx, struct_did, substs);
             for field in fields.iter() {
@@ -6932,6 +6933,7 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
                     return Err(FieldDoesNotImplementCopy(field.name))
                 }
             }
+            struct_did
         }
         ty::ty_enum(enum_did, substs) => {
             let enum_variants = ty::enum_variants(tcx, enum_did);
@@ -6944,8 +6946,13 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
                     }
                 }
             }
+            enum_did
         }
         _ => return Err(TypeIsStructural),
+    };
+
+    if ty::has_dtor(tcx, did) {
+        return Err(TypeHasDestructor)
     }
 
     Ok(())
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index cb52795670f..c29cc1bef1b 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -507,6 +507,11 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
                                   for this type; type is not a structure or \
                                   enumeration")
                 }
+                Err(ty::TypeHasDestructor) => {
+                    span_err!(tcx.sess, span, E0184,
+                              "the trait `Copy` may not be implemented for this type; \
+                               the type has a destructor");
+                }
             }
         }
     }
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 9657bf82a8b..c9e15b93ad4 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -157,5 +157,6 @@ register_diagnostics! {
     E0180,
     E0181,
     E0182,
-    E0183
+    E0183,
+    E0184
 }
diff --git a/src/test/compile-fail/drop-on-non-struct.rs b/src/test/compile-fail/drop-on-non-struct.rs
index 238700254b8..8d2ca0b0a6b 100644
--- a/src/test/compile-fail/drop-on-non-struct.rs
+++ b/src/test/compile-fail/drop-on-non-struct.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-impl Drop for int {
+impl<'a> Drop for &'a mut int {
     //~^ ERROR the Drop trait may only be implemented on structures
     //~^^ ERROR E0117
     fn drop(&mut self) {
diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs
new file mode 100644
index 00000000000..17453bc677f
--- /dev/null
+++ b/src/test/compile-fail/exclusive-drop-and-copy.rs
@@ -0,0 +1,30 @@
+// 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.
+
+#![feature(unsafe_destructor)]
+
+// issue #20126
+
+#[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+#[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
+struct Bar<T>;
+
+#[unsafe_destructor]
+impl<T> Drop for Bar<T> {
+    fn drop(&mut self) {}
+}
+
+fn main() {}