about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs11
-rw-r--r--src/test/ui/consts/precise-drop-with-promoted.rs9
2 files changed, 18 insertions, 2 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 5418f6fc007..aaeb1eeb043 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -46,6 +46,9 @@ pub trait Qualif {
     /// Whether this `Qualif` is cleared when a local is moved from.
     const IS_CLEARED_ON_MOVE: bool = false;
 
+    /// Whether this `Qualif` might be evaluated after the promotion and can encounter a promoted.
+    const ALLOW_PROMOTED: bool = false;
+
     /// Extracts the field of `ConstQualifs` that corresponds to this `Qualif`.
     fn in_qualifs(qualifs: &ConstQualifs) -> bool;
 
@@ -129,6 +132,7 @@ pub struct NeedsNonConstDrop;
 impl Qualif for NeedsNonConstDrop {
     const ANALYSIS_NAME: &'static str = "flow_needs_nonconst_drop";
     const IS_CLEARED_ON_MOVE: bool = true;
+    const ALLOW_PROMOTED: bool = true;
 
     fn in_qualifs(qualifs: &ConstQualifs) -> bool {
         qualifs.needs_non_const_drop
@@ -310,9 +314,12 @@ where
     // Check the qualifs of the value of `const` items.
     if let Some(ct) = constant.literal.const_for_ty() {
         if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs_: _, promoted }) = ct.val {
-            assert!(promoted.is_none());
+            // Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
+            // only for `NeedsNonConstDrop` with precise drop checking. This is the only const
+            // check performed after the promotion. Verify that with an assertion.
+            assert!(promoted.is_none() || Q::ALLOW_PROMOTED);
             // Don't peek inside trait associated constants.
-            if cx.tcx.trait_of_item(def.did).is_none() {
+            if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
                 let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
                     cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
                 } else {
diff --git a/src/test/ui/consts/precise-drop-with-promoted.rs b/src/test/ui/consts/precise-drop-with-promoted.rs
new file mode 100644
index 00000000000..6f2317a5a27
--- /dev/null
+++ b/src/test/ui/consts/precise-drop-with-promoted.rs
@@ -0,0 +1,9 @@
+// Regression test for issue #89938.
+// check-pass
+// compile-flags: --crate-type=lib
+#![feature(const_precise_live_drops)]
+
+pub const fn f() {
+    let _: Option<String> = None;
+    let _: &'static Option<String> = &None;
+}