diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2025-05-27 01:29:18 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-27 01:29:18 +0800 |
| commit | 0e710d0883709d34bfbb76f6813a83fa8fb96c23 (patch) | |
| tree | 84d5b45665cad40db592f0e93bd245b497cd984c | |
| parent | aa9978229eacda5b12f7d18de79f0f72f431f33f (diff) | |
| parent | 11392f4978fe3a81a87e4fd8abcb78a0dcf166e5 (diff) | |
| download | rust-0e710d0883709d34bfbb76f6813a83fa8fb96c23.tar.gz rust-0e710d0883709d34bfbb76f6813a83fa8fb96c23.zip | |
Rollup merge of #141431 - compiler-errors:open-drop, r=oli-obk
Emit dummy open drop for unsafe binder Fixes rust-lang/rust#141394 We can't taint the body in wfcheck when we have a `T: Copy` bound failure, so we end up binding MIR here. Emit a dummy open drop so that drop elaboration doesn't fail. r? oli-obk
| -rw-r--r-- | compiler/rustc_mir_transform/src/elaborate_drop.rs | 17 | ||||
| -rw-r--r-- | tests/ui/unsafe/move-out-of-non-copy.rs | 15 | ||||
| -rw-r--r-- | tests/ui/unsafe/move-out-of-non-copy.stderr | 14 |
3 files changed, 46 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 14f7c2a263b..211e2a92f73 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -1278,6 +1278,23 @@ where } ty::Slice(ety) => self.drop_loop_trio_for_slice(*ety), + ty::UnsafeBinder(_) => { + // Unsafe binders may elaborate drops if their inner type isn't copy. + // This is enforced in typeck, so this should never happen. + self.tcx().dcx().span_delayed_bug( + self.source_info.span, + "open drop for unsafe binder shouldn't be encountered", + ); + self.elaborator.patch().new_block(BasicBlockData { + statements: vec![], + terminator: Some(Terminator { + source_info: self.source_info, + kind: TerminatorKind::Unreachable, + }), + is_cleanup: self.unwind.is_cleanup(), + }) + } + _ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty), } } diff --git a/tests/ui/unsafe/move-out-of-non-copy.rs b/tests/ui/unsafe/move-out-of-non-copy.rs new file mode 100644 index 00000000000..ca6bf4277a1 --- /dev/null +++ b/tests/ui/unsafe/move-out-of-non-copy.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -Zvalidate-mir + +// Regression test for <https://github.com/rust-lang/rust/issues/141394>. + +#![feature(unsafe_binders)] +#![allow(incomplete_features)] + +use std::unsafe_binder::unwrap_binder; + +fn id<T>(x: unsafe<> T) -> T { + //~^ ERROR the trait bound `T: Copy` is not satisfied + unsafe { unwrap_binder!(x) } +} + +fn main() {} diff --git a/tests/ui/unsafe/move-out-of-non-copy.stderr b/tests/ui/unsafe/move-out-of-non-copy.stderr new file mode 100644 index 00000000000..4598742c92b --- /dev/null +++ b/tests/ui/unsafe/move-out-of-non-copy.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `T: Copy` is not satisfied + --> $DIR/move-out-of-non-copy.rs:10:13 + | +LL | fn id<T>(x: unsafe<> T) -> T { + | ^^^^^^^^^^ the trait `Copy` is not implemented for `T` + | +help: consider restricting type parameter `T` with trait `Copy` + | +LL | fn id<T: std::marker::Copy>(x: unsafe<> T) -> T { + | +++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. |
