Skip to content

Commit 0788442

Browse files
authored
Rollup merge of #99576 - compiler-errors:foreign-fundamental-drop-is-bad, r=TaKO8Ki
Do not allow `Drop` impl on foreign fundamental types `Drop` should not be implemented on `Pin<T>` even if `T` is local. This does not trigger regular orphan rules is because `Pin` is `#[fundamental]`... but we don't allow specialized `Drop` impls anyways, so these rules are not sufficient to prevent this impl on stable. Let's just choose even stricter rules, since we shouldn't be implementing `Drop` on a foreign ADT ever. Fixes #99575
2 parents 6c943ba + fd934c9 commit 0788442

File tree

10 files changed

+51
-18
lines changed

10 files changed

+51
-18
lines changed

compiler/rustc_error_messages/locales/en-US/typeck.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ typeck_lifetimes_or_bounds_mismatch_on_trait =
2424
.generics_label = lifetimes in impl do not match this {$item_kind} in trait
2525
2626
typeck_drop_impl_on_wrong_item =
27-
the `Drop` trait may only be implemented for structs, enums, and unions
28-
.label = must be a struct, enum, or union
27+
the `Drop` trait may only be implemented for local structs, enums, and unions
28+
.label = must be a struct, enum, or union in the current crate
2929
3030
typeck_field_already_declared =
3131
field `{$field_name}` is already declared

compiler/rustc_typeck/src/coherence/builtin.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ impl<'tcx> Checker<'tcx> {
4747
}
4848

4949
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
50-
// Destructors only work on nominal types.
51-
if let ty::Adt(..) | ty::Error(_) = tcx.type_of(impl_did).kind() {
52-
return;
50+
// Destructors only work on local ADT types.
51+
match tcx.type_of(impl_did).kind() {
52+
ty::Adt(def, _) if def.did().is_local() => return,
53+
ty::Error(_) => return,
54+
_ => {}
5355
}
5456

5557
let sp = match tcx.hir().expect_item(impl_did).kind {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::ops::Deref;
2+
use std::pin::Pin;
3+
4+
struct Whatever<T>(T);
5+
6+
impl<T> Deref for Whatever<T> {
7+
type Target = T;
8+
9+
fn deref(&self) -> &T {
10+
&self.0
11+
}
12+
}
13+
14+
struct A;
15+
16+
impl Drop for Pin<Whatever<A>> {
17+
//~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
18+
fn drop(&mut self) {}
19+
}
20+
21+
fn main() {
22+
let x = Pin::new(Whatever(1.0f32));
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
2+
--> $DIR/drop-foreign-fundamental.rs:16:15
3+
|
4+
LL | impl Drop for Pin<Whatever<A>> {
5+
| ^^^^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0120`.
+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
impl<'a> Drop for &'a mut isize {
2-
//~^ ERROR the `Drop` trait may only be implemented for structs, enums, and unions
2+
//~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
33
//~^^ ERROR E0117
44
fn drop(&mut self) {
55
println!("kaboom");
@@ -8,8 +8,7 @@ impl<'a> Drop for &'a mut isize {
88

99
impl Drop for Nonexistent {
1010
//~^ ERROR cannot find type `Nonexistent`
11-
fn drop(&mut self) { }
11+
fn drop(&mut self) {}
1212
}
1313

14-
fn main() {
15-
}
14+
fn main() {}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ LL | impl<'a> Drop for &'a mut isize {
1515
|
1616
= note: define and implement a trait or new type instead
1717

18-
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
18+
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
1919
--> $DIR/drop-on-non-struct.rs:1:19
2020
|
2121
LL | impl<'a> Drop for &'a mut isize {
22-
| ^^^^^^^^^^^^^ must be a struct, enum, or union
22+
| ^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
2323

2424
error: aborting due to 3 previous errors
2525

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
impl Drop for u32 {} //~ ERROR E0117
2-
//~| ERROR the `Drop` trait may only be implemented for structs, enums, and unions
2+
//~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
33

44
fn main() {}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ LL | impl Drop for u32 {}
99
|
1010
= note: define and implement a trait or new type instead
1111

12-
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
12+
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
1313
--> $DIR/E0117.rs:1:15
1414
|
1515
LL | impl Drop for u32 {}
16-
| ^^^ must be a struct, enum, or union
16+
| ^^^ must be a struct, enum, or union in the current crate
1717

1818
error: aborting due to 2 previous errors
1919

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 for structs, enums, and unions
1+
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
22
--> $DIR/E0120.rs:3:15
33
|
44
LL | impl Drop for dyn MyTrait {
5-
| ^^^^^^^^^^^ must be a struct, enum, or union
5+
| ^^^^^^^^^^^ must be a struct, enum, or union in the current crate
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
@@ -7,11 +7,11 @@ LL | impl<T> Drop for T where T: A {
77
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
88
= note: only traits defined in the current crate can be implemented for a type parameter
99

10-
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
10+
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
1111
--> $DIR/issue-41974.rs:7:18
1212
|
1313
LL | impl<T> Drop for T where T: A {
14-
| ^ must be a struct, enum, or union
14+
| ^ must be a struct, enum, or union in the current crate
1515

1616
error: aborting due to 2 previous errors
1717

0 commit comments

Comments
 (0)