about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndy Russell <arussell123@gmail.com>2020-01-02 22:24:21 -0500
committerAndy Russell <arussell123@gmail.com>2020-01-03 17:57:24 -0500
commite9990bc65f8e44fd2843478ac685bb79c0a50ed0 (patch)
treed4cbf529170156dc0d51750eba70c51d2a7891b1
parente589358210862cdbb34c124bcc95a67afe09135c (diff)
downloadrust-e9990bc65f8e44fd2843478ac685bb79c0a50ed0.tar.gz
rust-e9990bc65f8e44fd2843478ac685bb79c0a50ed0.zip
clarify that `Drop` can be implemented for enums and unions too
-rw-r--r--src/librustc_typeck/coherence/builtin.rs47
-rw-r--r--src/test/ui/dropck/drop-on-non-struct.rs7
-rw-r--r--src/test/ui/dropck/drop-on-non-struct.stderr14
-rw-r--r--src/test/ui/error-codes/E0117.rs3
-rw-r--r--src/test/ui/error-codes/E0117.stderr4
-rw-r--r--src/test/ui/error-codes/E0120.stderr4
-rw-r--r--src/test/ui/issues/issue-41974.stderr4
7 files changed, 41 insertions, 42 deletions
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 7f7e21838d2..7e016cf7e9a 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -13,7 +13,6 @@ use rustc::ty::util::CopyImplementationError;
 use rustc::ty::TypeFoldable;
 use rustc::ty::{self, Ty, TyCtxt};
 
-use hir::Node;
 use rustc::hir::def_id::DefId;
 use rustc::hir::{self, ItemKind};
 
@@ -51,35 +50,25 @@ impl<'tcx> Checker<'tcx> {
 }
 
 fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) {
-    if let ty::Adt(..) = tcx.type_of(impl_did).kind {
-        /* do nothing */
-    } else {
-        // Destructors only work on nominal types.
-        if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_did) {
-            if let Some(Node::Item(item)) = tcx.hir().find(impl_hir_id) {
-                let span = match item.kind {
-                    ItemKind::Impl(.., ref ty, _) => ty.span,
-                    _ => item.span,
-                };
-                struct_span_err!(
-                    tcx.sess,
-                    span,
-                    E0120,
-                    "the Drop trait may only be implemented on \
-                                  structures"
-                )
-                .span_label(span, "implementing Drop requires a struct")
-                .emit();
-            } else {
-                bug!("didn't find impl in ast map");
-            }
-        } else {
-            bug!(
-                "found external impl of Drop trait on \
-                  something other than a struct"
-            );
-        }
+    // Destructors only work on nominal types.
+    if let ty::Adt(..) | ty::Error = tcx.type_of(impl_did).kind {
+        return;
     }
+
+    let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT");
+    let sp = match tcx.hir().expect_item(impl_hir_id).kind {
+        ItemKind::Impl(.., ty, _) => ty.span,
+        _ => bug!("expected Drop impl item"),
+    };
+
+    struct_span_err!(
+        tcx.sess,
+        sp,
+        E0120,
+        "the `Drop` trait may only be implemented for structs, enums, and unions",
+    )
+    .span_label(sp, "must be a struct, enum, or union")
+    .emit();
 }
 
 fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) {
diff --git a/src/test/ui/dropck/drop-on-non-struct.rs b/src/test/ui/dropck/drop-on-non-struct.rs
index 259cdf40ae5..ef5e18126dc 100644
--- a/src/test/ui/dropck/drop-on-non-struct.rs
+++ b/src/test/ui/dropck/drop-on-non-struct.rs
@@ -1,10 +1,15 @@
 impl<'a> Drop for &'a mut isize {
-    //~^ ERROR the Drop trait may only be implemented on structures
+    //~^ ERROR the `Drop` trait may only be implemented for structs, enums, and unions
     //~^^ ERROR E0117
     fn drop(&mut self) {
         println!("kaboom");
     }
 }
 
+impl Drop for Nonexistent {
+    //~^ ERROR cannot find type `Nonexistent`
+    fn drop(&mut self) { }
+}
+
 fn main() {
 }
diff --git a/src/test/ui/dropck/drop-on-non-struct.stderr b/src/test/ui/dropck/drop-on-non-struct.stderr
index a374b0d2636..3991c44f2ed 100644
--- a/src/test/ui/dropck/drop-on-non-struct.stderr
+++ b/src/test/ui/dropck/drop-on-non-struct.stderr
@@ -1,8 +1,14 @@
-error[E0120]: the Drop trait may only be implemented on structures
+error[E0412]: cannot find type `Nonexistent` in this scope
+  --> $DIR/drop-on-non-struct.rs:9:15
+   |
+LL | impl Drop for Nonexistent {
+   |               ^^^^^^^^^^^ not found in this scope
+
+error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
   --> $DIR/drop-on-non-struct.rs:1:19
    |
 LL | impl<'a> Drop for &'a mut isize {
-   |                   ^^^^^^^^^^^^^ implementing Drop requires a struct
+   |                   ^^^^^^^^^^^^^ must be a struct, enum, or union
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
   --> $DIR/drop-on-non-struct.rs:1:1
@@ -15,7 +21,7 @@ LL | impl<'a> Drop for &'a mut isize {
    |
    = note: define and implement a trait or new type instead
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0117, E0120.
+Some errors have detailed explanations: E0117, E0120, E0412.
 For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/error-codes/E0117.rs b/src/test/ui/error-codes/E0117.rs
index 18dd809f3ff..dbbac514801 100644
--- a/src/test/ui/error-codes/E0117.rs
+++ b/src/test/ui/error-codes/E0117.rs
@@ -1,6 +1,5 @@
 impl Drop for u32 {} //~ ERROR E0117
-//~| ERROR the Drop trait may only be implemented on structures
-//~| implementing Drop requires a struct
+//~| ERROR the `Drop` trait may only be implemented for structs, enums, and unions
 
 fn main() {
 }
diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr
index f0cfc8a2533..b48a1d8e50d 100644
--- a/src/test/ui/error-codes/E0117.stderr
+++ b/src/test/ui/error-codes/E0117.stderr
@@ -1,8 +1,8 @@
-error[E0120]: the Drop trait may only be implemented on structures
+error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
   --> $DIR/E0117.rs:1:15
    |
 LL | impl Drop for u32 {}
-   |               ^^^ implementing Drop requires a struct
+   |               ^^^ must be a struct, enum, or union
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
   --> $DIR/E0117.rs:1:1
diff --git a/src/test/ui/error-codes/E0120.stderr b/src/test/ui/error-codes/E0120.stderr
index 68ca7d800d5..6c306455e42 100644
--- a/src/test/ui/error-codes/E0120.stderr
+++ b/src/test/ui/error-codes/E0120.stderr
@@ -1,8 +1,8 @@
-error[E0120]: the Drop trait may only be implemented on structures
+error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
   --> $DIR/E0120.rs:3:15
    |
 LL | impl Drop for dyn MyTrait {
-   |               ^^^^^^^^^^^ implementing Drop requires a struct
+   |               ^^^^^^^^^^^ must be a struct, enum, or union
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr
index 9f164822dea..d082e0a6b5d 100644
--- a/src/test/ui/issues/issue-41974.stderr
+++ b/src/test/ui/issues/issue-41974.stderr
@@ -9,11 +9,11 @@ LL | impl<T> Drop for T where T: A {
              where T: ?Sized;
    = note: downstream crates may implement trait `A` for type `std::boxed::Box<_>`
 
-error[E0120]: the Drop trait may only be implemented on structures
+error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
   --> $DIR/issue-41974.rs:7:18
    |
 LL | impl<T> Drop for T where T: A {
-   |                  ^ implementing Drop requires a struct
+   |                  ^ must be a struct, enum, or union
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
   --> $DIR/issue-41974.rs:7:6