fixes/working version

This commit is contained in:
b-naber 2022-06-30 11:14:39 +02:00
parent 2554fa1c8e
commit a7735cd329
5 changed files with 36 additions and 23 deletions

View File

@ -585,7 +585,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
uneval: &ty::Unevaluated<'tcx>, uneval: &ty::Unevaluated<'tcx>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
let instance = self.resolve(uneval.def, uneval.substs)?; 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( pub fn mir_const_to_op(

View File

@ -346,32 +346,41 @@ where
}; };
// Check the qualifs of the value of `const` items. // Check the qualifs of the value of `const` items.
if let Some(ct) = constant.literal.const_for_ty() { let uneval = match constant.literal {
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: _ }) = ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Unevaluated(_)) => {
ct.kind() let ty::ConstKind::Unevaluated(uv) = ct.kind() else { unreachable!() };
{
// 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. Some(uv.expand())
if cx.tcx.trait_of_item(def.did).is_none() { }
let qualifs = if let Some((did, param_did)) = def.as_const_arg() { ConstantKind::Ty(_) => None,
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did)) ConstantKind::Unevaluated(uv, _) => Some(uv),
} else { ConstantKind::Val(..) => None,
cx.tcx.at(constant.span).mir_const_qualif(def.did) };
};
if !Q::in_qualifs(&qualifs) { if let Some(ty::Unevaluated { def, substs: _, promoted }) = uneval {
return false; // 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);
// Just in case the type is more specific than // Don't peek inside trait associated constants.
// the definition, e.g., impl associated const if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() {
// with type parameters, take it into account. 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. // Otherwise use the qualifs of the type.
Q::in_any_value_of_ty(cx, constant.literal.ty()) Q::in_any_value_of_ty(cx, constant.literal.ty())
} }

View File

@ -236,7 +236,7 @@ impl<'tcx> TypeSuperFoldable<'tcx> for ConstantKind<'tcx> {
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)), 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::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),
ConstantKind::Unevaluated(uv, t) => { 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)?))
} }
} }
} }

View File

@ -185,6 +185,10 @@ impl<'tcx> TypeSuperVisitable<'tcx> for ConstantKind<'tcx> {
match *self { match *self {
ConstantKind::Ty(c) => c.visit_with(visitor), ConstantKind::Ty(c) => c.visit_with(visitor),
ConstantKind::Val(_, t) => t.visit_with(visitor), ConstantKind::Val(_, t) => t.visit_with(visitor),
ConstantKind::Unevaluated(uv, t) => {
uv.visit_with(visitor)?;
t.visit_with(visitor)
}
} }
} }
} }

View File

@ -313,7 +313,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
} }
match constant { 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) }, _) ConstantKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p) }, _)
// Avoid considering `T` unused when constants are of the form: // Avoid considering `T` unused when constants are of the form:
// `<Self as Foo<T>>::foo::promoted[p]` // `<Self as Foo<T>>::foo::promoted[p]`