Skip to content

Commit e9990bc

Browse files
committed
clarify that Drop can be implemented for enums and unions too
1 parent e589358 commit e9990bc

File tree

7 files changed

+41
-42
lines changed

7 files changed

+41
-42
lines changed

src/librustc_typeck/coherence/builtin.rs

+18-29
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc::ty::util::CopyImplementationError;
1313
use rustc::ty::TypeFoldable;
1414
use rustc::ty::{self, Ty, TyCtxt};
1515

16-
use hir::Node;
1716
use rustc::hir::def_id::DefId;
1817
use rustc::hir::{self, ItemKind};
1918

@@ -51,35 +50,25 @@ impl<'tcx> Checker<'tcx> {
5150
}
5251

5352
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) {
54-
if let ty::Adt(..) = tcx.type_of(impl_did).kind {
55-
/* do nothing */
56-
} else {
57-
// Destructors only work on nominal types.
58-
if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_did) {
59-
if let Some(Node::Item(item)) = tcx.hir().find(impl_hir_id) {
60-
let span = match item.kind {
61-
ItemKind::Impl(.., ref ty, _) => ty.span,
62-
_ => item.span,
63-
};
64-
struct_span_err!(
65-
tcx.sess,
66-
span,
67-
E0120,
68-
"the Drop trait may only be implemented on \
69-
structures"
70-
)
71-
.span_label(span, "implementing Drop requires a struct")
72-
.emit();
73-
} else {
74-
bug!("didn't find impl in ast map");
75-
}
76-
} else {
77-
bug!(
78-
"found external impl of Drop trait on \
79-
something other than a struct"
80-
);
81-
}
53+
// Destructors only work on nominal types.
54+
if let ty::Adt(..) | ty::Error = tcx.type_of(impl_did).kind {
55+
return;
8256
}
57+
58+
let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT");
59+
let sp = match tcx.hir().expect_item(impl_hir_id).kind {
60+
ItemKind::Impl(.., ty, _) => ty.span,
61+
_ => bug!("expected Drop impl item"),
62+
};
63+
64+
struct_span_err!(
65+
tcx.sess,
66+
sp,
67+
E0120,
68+
"the `Drop` trait may only be implemented for structs, enums, and unions",
69+
)
70+
.span_label(sp, "must be a struct, enum, or union")
71+
.emit();
8372
}
8473

8574
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) {
+6-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
impl<'a> Drop for &'a mut isize {
2-
//~^ ERROR the Drop trait may only be implemented on structures
2+
//~^ ERROR the `Drop` trait may only be implemented for structs, enums, and unions
33
//~^^ ERROR E0117
44
fn drop(&mut self) {
55
println!("kaboom");
66
}
77
}
88

9+
impl Drop for Nonexistent {
10+
//~^ ERROR cannot find type `Nonexistent`
11+
fn drop(&mut self) { }
12+
}
13+
914
fn main() {
1015
}

src/test/ui/dropck/drop-on-non-struct.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
error[E0120]: the Drop trait may only be implemented on structures
1+
error[E0412]: cannot find type `Nonexistent` in this scope
2+
--> $DIR/drop-on-non-struct.rs:9:15
3+
|
4+
LL | impl Drop for Nonexistent {
5+
| ^^^^^^^^^^^ not found in this scope
6+
7+
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
28
--> $DIR/drop-on-non-struct.rs:1:19
39
|
410
LL | impl<'a> Drop for &'a mut isize {
5-
| ^^^^^^^^^^^^^ implementing Drop requires a struct
11+
| ^^^^^^^^^^^^^ must be a struct, enum, or union
612

713
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
814
--> $DIR/drop-on-non-struct.rs:1:1
@@ -15,7 +21,7 @@ LL | impl<'a> Drop for &'a mut isize {
1521
|
1622
= note: define and implement a trait or new type instead
1723

18-
error: aborting due to 2 previous errors
24+
error: aborting due to 3 previous errors
1925

20-
Some errors have detailed explanations: E0117, E0120.
26+
Some errors have detailed explanations: E0117, E0120, E0412.
2127
For more information about an error, try `rustc --explain E0117`.

src/test/ui/error-codes/E0117.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
impl Drop for u32 {} //~ ERROR E0117
2-
//~| ERROR the Drop trait may only be implemented on structures
3-
//~| implementing Drop requires a struct
2+
//~| ERROR the `Drop` trait may only be implemented for structs, enums, and unions
43

54
fn main() {
65
}

src/test/ui/error-codes/E0117.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0120]: the Drop trait may only be implemented on structures
1+
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
22
--> $DIR/E0117.rs:1:15
33
|
44
LL | impl Drop for u32 {}
5-
| ^^^ implementing Drop requires a struct
5+
| ^^^ must be a struct, enum, or union
66

77
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
88
--> $DIR/E0117.rs:1:1

src/test/ui/error-codes/E0120.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0120]: the Drop trait may only be implemented on structures
1+
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
22
--> $DIR/E0120.rs:3:15
33
|
44
LL | impl Drop for dyn MyTrait {
5-
| ^^^^^^^^^^^ implementing Drop requires a struct
5+
| ^^^^^^^^^^^ must be a struct, enum, or union
66

77
error: aborting due to previous error
88

src/test/ui/issues/issue-41974.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ LL | impl<T> Drop for T where T: A {
99
where T: ?Sized;
1010
= note: downstream crates may implement trait `A` for type `std::boxed::Box<_>`
1111

12-
error[E0120]: the Drop trait may only be implemented on structures
12+
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
1313
--> $DIR/issue-41974.rs:7:18
1414
|
1515
LL | impl<T> Drop for T where T: A {
16-
| ^ implementing Drop requires a struct
16+
| ^ must be a struct, enum, or union
1717

1818
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
1919
--> $DIR/issue-41974.rs:7:6

0 commit comments

Comments
 (0)