about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs3
-rw-r--r--tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs17
-rw-r--r--tests/ui/traits/const-traits/drop-manually-drop.rs24
4 files changed, 47 insertions, 0 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 035bfff89b5..b16f74cd8e4 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -724,6 +724,9 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
     let destruct_def_id = cx.require_lang_item(TraitSolverLangItem::Destruct);
 
     match self_ty.kind() {
+        // `ManuallyDrop` is trivially `~const Destruct` as we do not run any drop glue on it.
+        ty::Adt(adt_def, _) if adt_def.is_manually_drop() => Ok(vec![]),
+
         // An ADT is `~const Destruct` only if all of the fields are,
         // *and* if there is a `Drop` impl, that `Drop` impl is also `~const`.
         ty::Adt(adt_def, args) => {
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index defbafac20b..1b5dcef2e59 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -252,6 +252,9 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
     let self_ty = obligation.predicate.self_ty();
 
     let const_conditions = match *self_ty.kind() {
+        // `ManuallyDrop` is trivially `~const Destruct` as we do not run any drop glue on it.
+        ty::Adt(adt_def, _) if adt_def.is_manually_drop() => thin_vec![],
+
         // An ADT is `~const Destruct` only if all of the fields are,
         // *and* if there is a `Drop` impl, that `Drop` impl is also `~const`.
         ty::Adt(adt_def, args) => {
diff --git a/tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs b/tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs
new file mode 100644
index 00000000000..060a543d6c3
--- /dev/null
+++ b/tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs
@@ -0,0 +1,17 @@
+//@[new] compile-flags: -Znext-solver
+//@ revisions: old new
+//@ check-pass
+
+use std::mem::ManuallyDrop;
+
+struct Moose;
+
+impl Drop for Moose {
+    fn drop(&mut self) {}
+}
+
+struct ConstDropper<T>(ManuallyDrop<T>);
+
+const fn foo(_var: ConstDropper<Moose>) {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.rs b/tests/ui/traits/const-traits/drop-manually-drop.rs
new file mode 100644
index 00000000000..62e8a815f10
--- /dev/null
+++ b/tests/ui/traits/const-traits/drop-manually-drop.rs
@@ -0,0 +1,24 @@
+//@[new] compile-flags: -Znext-solver
+//@ revisions: old new
+//@ check-pass
+
+#![feature(const_destruct)]
+#![feature(const_trait_impl)]
+
+use std::mem::ManuallyDrop;
+
+struct Moose;
+
+impl Drop for Moose {
+    fn drop(&mut self) {}
+}
+
+struct ConstDropper<T>(ManuallyDrop<T>);
+
+impl<T> const Drop for ConstDropper<T> {
+    fn drop(&mut self) {}
+}
+
+const fn foo(_var: ConstDropper<Moose>) {}
+
+fn main() {}