mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
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
This commit is contained in:
commit
078844283c
@ -24,8 +24,8 @@ typeck_lifetimes_or_bounds_mismatch_on_trait =
|
|||||||
.generics_label = lifetimes in impl do not match this {$item_kind} in trait
|
.generics_label = lifetimes in impl do not match this {$item_kind} in trait
|
||||||
|
|
||||||
typeck_drop_impl_on_wrong_item =
|
typeck_drop_impl_on_wrong_item =
|
||||||
the `Drop` trait may only be implemented for structs, enums, and unions
|
the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
.label = must be a struct, enum, or union
|
.label = must be a struct, enum, or union in the current crate
|
||||||
|
|
||||||
typeck_field_already_declared =
|
typeck_field_already_declared =
|
||||||
field `{$field_name}` is already declared
|
field `{$field_name}` is already declared
|
||||||
|
@ -47,9 +47,11 @@ impl<'tcx> Checker<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
// Destructors only work on nominal types.
|
// Destructors only work on local ADT types.
|
||||||
if let ty::Adt(..) | ty::Error(_) = tcx.type_of(impl_did).kind() {
|
match tcx.type_of(impl_did).kind() {
|
||||||
return;
|
ty::Adt(def, _) if def.did().is_local() => return,
|
||||||
|
ty::Error(_) => return,
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sp = match tcx.hir().expect_item(impl_did).kind {
|
let sp = match tcx.hir().expect_item(impl_did).kind {
|
||||||
|
23
src/test/ui/drop/drop-foreign-fundamental.rs
Normal file
23
src/test/ui/drop/drop-foreign-fundamental.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
struct Whatever<T>(T);
|
||||||
|
|
||||||
|
impl<T> Deref for Whatever<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
impl Drop for Pin<Whatever<A>> {
|
||||||
|
//~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
|
fn drop(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Pin::new(Whatever(1.0f32));
|
||||||
|
}
|
9
src/test/ui/drop/drop-foreign-fundamental.stderr
Normal file
9
src/test/ui/drop/drop-foreign-fundamental.stderr
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
|
--> $DIR/drop-foreign-fundamental.rs:16:15
|
||||||
|
|
|
||||||
|
LL | impl Drop for Pin<Whatever<A>> {
|
||||||
|
| ^^^^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0120`.
|
@ -1,5 +1,5 @@
|
|||||||
impl<'a> Drop for &'a mut isize {
|
impl<'a> Drop for &'a mut isize {
|
||||||
//~^ ERROR the `Drop` trait may only be implemented for structs, enums, and unions
|
//~^ ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
//~^^ ERROR E0117
|
//~^^ ERROR E0117
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
println!("kaboom");
|
println!("kaboom");
|
||||||
@ -8,8 +8,7 @@ impl<'a> Drop for &'a mut isize {
|
|||||||
|
|
||||||
impl Drop for Nonexistent {
|
impl Drop for Nonexistent {
|
||||||
//~^ ERROR cannot find type `Nonexistent`
|
//~^ ERROR cannot find type `Nonexistent`
|
||||||
fn drop(&mut self) { }
|
fn drop(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {}
|
||||||
}
|
|
||||||
|
@ -15,11 +15,11 @@ LL | impl<'a> Drop for &'a mut isize {
|
|||||||
|
|
|
|
||||||
= note: define and implement a trait or new type instead
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
|
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
--> $DIR/drop-on-non-struct.rs:1:19
|
--> $DIR/drop-on-non-struct.rs:1:19
|
||||||
|
|
|
|
||||||
LL | impl<'a> Drop for &'a mut isize {
|
LL | impl<'a> Drop for &'a mut isize {
|
||||||
| ^^^^^^^^^^^^^ must be a struct, enum, or union
|
| ^^^^^^^^^^^^^ must be a struct, enum, or union in the current crate
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
impl Drop for u32 {} //~ ERROR E0117
|
impl Drop for u32 {} //~ ERROR E0117
|
||||||
//~| ERROR the `Drop` trait may only be implemented for structs, enums, and unions
|
//~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -9,11 +9,11 @@ LL | impl Drop for u32 {}
|
|||||||
|
|
|
|
||||||
= note: define and implement a trait or new type instead
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
|
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
--> $DIR/E0117.rs:1:15
|
--> $DIR/E0117.rs:1:15
|
||||||
|
|
|
|
||||||
LL | impl Drop for u32 {}
|
LL | impl Drop for u32 {}
|
||||||
| ^^^ must be a struct, enum, or union
|
| ^^^ must be a struct, enum, or union in the current crate
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
|
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
--> $DIR/E0120.rs:3:15
|
--> $DIR/E0120.rs:3:15
|
||||||
|
|
|
|
||||||
LL | impl Drop for dyn MyTrait {
|
LL | impl Drop for dyn MyTrait {
|
||||||
| ^^^^^^^^^^^ must be a struct, enum, or union
|
| ^^^^^^^^^^^ must be a struct, enum, or union in the current crate
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@ LL | impl<T> Drop for T where T: A {
|
|||||||
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
|
||||||
= note: only traits defined in the current crate can be implemented for a type parameter
|
= note: only traits defined in the current crate can be implemented for a type parameter
|
||||||
|
|
||||||
error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
|
error[E0120]: the `Drop` trait may only be implemented for local structs, enums, and unions
|
||||||
--> $DIR/issue-41974.rs:7:18
|
--> $DIR/issue-41974.rs:7:18
|
||||||
|
|
|
|
||||||
LL | impl<T> Drop for T where T: A {
|
LL | impl<T> Drop for T where T: A {
|
||||||
| ^ must be a struct, enum, or union
|
| ^ must be a struct, enum, or union in the current crate
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user