use ty::Unevaluated<'tcx, ()> in type system
This commit is contained in:
parent
7098c181f8
commit
a4bbb8db5c
32 changed files with 304 additions and 192 deletions
|
@ -565,7 +565,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
let instance = self.resolve(uv.def, uv.substs)?;
|
||||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
|
||||
Ok(self.eval_to_allocation(GlobalId { instance, promoted: None })?.into())
|
||||
}
|
||||
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
||||
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", c)
|
||||
|
@ -578,6 +578,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Tries to evaluate an unevaluated constant from the MIR (and not the type-system).
|
||||
#[inline]
|
||||
pub fn uneval_to_op(
|
||||
&self,
|
||||
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())
|
||||
}
|
||||
|
||||
pub fn mir_const_to_op(
|
||||
&self,
|
||||
val: &mir::ConstantKind<'tcx>,
|
||||
|
@ -586,6 +596,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match val {
|
||||
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
|
||||
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
|
||||
mir::ConstantKind::Unevaluated(uv, _) => self.uneval_to_op(uv),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -347,14 +347,15 @@ 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()
|
||||
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.
|
||||
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() {
|
||||
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 {
|
||||
|
|
|
@ -840,21 +840,15 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
promoted.span = span;
|
||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||
let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did));
|
||||
let _const = tcx.mk_const(ty::ConstS {
|
||||
ty,
|
||||
kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||
def,
|
||||
substs,
|
||||
promoted: Some(promoted_id),
|
||||
}),
|
||||
});
|
||||
let uneval = ty::Unevaluated { def, substs, promoted: Some(promoted_id) };
|
||||
|
||||
Operand::Constant(Box::new(Constant {
|
||||
span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::from_const(_const, tcx),
|
||||
literal: ConstantKind::Unevaluated(uneval, ty),
|
||||
}))
|
||||
};
|
||||
|
||||
let blocks = self.source.basic_blocks.as_mut();
|
||||
let local_decls = &mut self.source.local_decls;
|
||||
let loc = candidate.location;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue