about summary refs log tree commit diff
diff options
context:
space:
mode:
authorb-naber <bn263@gmx.de>2022-06-30 11:14:39 +0200
committerb-naber <bn263@gmx.de>2022-09-13 17:41:02 +0200
commita7735cd329da6f9a75c15bb86e5789925c860f31 (patch)
tree1ef46827b6ccadf1c53a52f5c49b008ea529d51d
parent2554fa1c8e14f2b34f10e87c115388d5498ffc0c (diff)
downloadrust-a7735cd329da6f9a75c15bb86e5789925c860f31.tar.gz
rust-a7735cd329da6f9a75c15bb86e5789925c860f31.zip
fixes/working version
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs53
-rw-r--r--compiler/rustc_middle/src/mir/type_foldable.rs2
-rw-r--r--compiler/rustc_middle/src/mir/type_visitable.rs4
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
5 files changed, 38 insertions, 25 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 9784de1fffc..a5f00d0aff2 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -585,7 +585,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         uneval: &ty::Unevaluated<'tcx>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         let instance = self.resolve(uneval.def, uneval.substs)?;
-        Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into())
+        Ok(self.eval_to_allocation(GlobalId { instance, promoted: uneval.promoted })?.into())
     }
 
     pub fn mir_const_to_op(
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 fce799d47ec..23a013980be 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -346,32 +346,41 @@ 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.kind()
-        {
-            // 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.
-
-            // 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() {
-                    cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
-                } else {
-                    cx.tcx.at(constant.span).mir_const_qualif(def.did)
-                };
-
-                if !Q::in_qualifs(&qualifs) {
-                    return false;
-                }
+    let uneval = match constant.literal {
+        ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => {
+            let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() };
 
-                // Just in case the type is more specific than
-                // the definition, e.g., impl associated const
-                // with type parameters, take it into account.
+            Some(uv.expand())
+        }
+        ConstantKind::Ty(_) => None,
+        ConstantKind::Unevaluated(uv, _) => Some(uv),
+        ConstantKind::Val(..) => None,
+    };
+
+    if let Some(ty::Unevaluated { def, substs: _, promoted }) = uneval {
+        // 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 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 {
+                cx.tcx.at(constant.span).mir_const_qualif(def.did)
+            };
+
+            if !Q::in_qualifs(&qualifs) {
+                return false;
             }
+
+            // Just in case the type is more specific than
+            // the definition, e.g., impl associated const
+            // with type parameters, take it into account.
         }
     }
+
     // Otherwise use the qualifs of the type.
     Q::in_any_value_of_ty(cx, constant.literal.ty())
 }
diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs
index e5aadac8739..022ec6f074d 100644
--- a/compiler/rustc_middle/src/mir/type_foldable.rs
+++ b/compiler/rustc_middle/src/mir/type_foldable.rs
@@ -236,7 +236,7 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> {
             ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)),
             ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),
             ConstantKind::Unevaluated(uv, t) => {
-                Ok(ConstantKind::Unevaluated(uv, t.try_fold_with(folder)?))
+                Ok(ConstantKind::Unevaluated(uv.try_fold_with(folder)?, t.try_fold_with(folder)?))
             }
         }
     }
diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs
index 6a0801cb0dd..4b3ad9cc5da 100644
--- a/compiler/rustc_middle/src/mir/type_visitable.rs
+++ b/compiler/rustc_middle/src/mir/type_visitable.rs
@@ -185,6 +185,10 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> {
         match *self {
             ConstantKind::Ty(c) => c.visit_with(visitor),
             ConstantKind::Val(_, t) => t.visit_with(visitor),
+            ConstantKind::Unevaluated(uv, t) => {
+                uv.visit_with(visitor)?;
+                t.visit_with(visitor)
+            }
         }
     }
 }
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index d083a3e00b6..b4bda57ba83 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -313,7 +313,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
         }
 
         match constant {
-            ConstantKind::Ty(_) => constant.super_visit_with(self),
+            ConstantKind::Ty(ct) => ct.visit_with(self),
             ConstantKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p) }, _)
                 // Avoid considering `T` unused when constants are of the form:
                 //   `<Self as Foo<T>>::foo::promoted[p]`