Fix const qualification when executed after promotion

The const qualification was so far performed before the promotion and
the implementation assumed that it will never encounter a promoted.

With `const_precise_live_drops` feature, checking for live drops is
delayed until after drop elaboration, which in turn runs after
promotion. so the assumption is no longer true. When evaluating
`NeedsNonConstDrop` it is now possible to encounter promoteds.

Use type base qualification for the promoted. It is a sound
approximation in general, and in the specific case of promoteds and
`NeedsNonConstDrop` it is precise.
This commit is contained in:
Tomasz Miąsko 2021-10-19 00:00:00 +00:00
parent 1af55d19c7
commit 7581bae996
2 changed files with 12 additions and 2 deletions

View File

@ -309,8 +309,9 @@ pub fn in_operand<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, operand: &Oper
// 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());
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs_: _, promoted: None }) =
ct.val
{
// Don't peek inside trait associated constants.
if cx.tcx.trait_of_item(def.did).is_none() {
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {

View File

@ -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;
}