ConstKind::Unevaluated
This commit is contained in:
parent
08865d94e5
commit
58031c7cb2
14 changed files with 53 additions and 37 deletions
|
|
@ -25,10 +25,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
constant: &mir::Constant<'tcx>,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self.monomorphize(&constant.literal).val {
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => self
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => self
|
||||
.cx
|
||||
.tcx()
|
||||
.const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None)
|
||||
.const_eval_resolve(ty::ParamEnv::reveal_all(), def.did, substs, promoted, None)
|
||||
.map_err(|err| {
|
||||
if promoted.is_none() {
|
||||
self.cx
|
||||
|
|
|
|||
|
|
@ -1586,12 +1586,24 @@ impl<T> WithOptParam<T> {
|
|||
}
|
||||
|
||||
impl WithOptParam<LocalDefId> {
|
||||
pub fn to_global(self) -> WithOptParam<DefId> {
|
||||
WithOptParam { did: self.did.to_def_id(), param_did: self.param_did }
|
||||
}
|
||||
|
||||
pub fn ty_def_id(self) -> DefId {
|
||||
if let Some(did) = self.param_did { did } else { self.did.to_def_id() }
|
||||
}
|
||||
}
|
||||
|
||||
impl WithOptParam<DefId> {
|
||||
pub fn as_local(self) -> Option<WithOptParam<LocalDefId>> {
|
||||
self.did.as_local().map(|did| WithOptParam { did, param_did: self.param_did })
|
||||
}
|
||||
|
||||
pub fn is_local(self) -> bool {
|
||||
self.did.is_local()
|
||||
}
|
||||
|
||||
pub fn ty_def_id(self) -> DefId {
|
||||
self.param_did.unwrap_or(self.did)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -883,18 +883,18 @@ pub trait PrettyPrinter<'tcx>:
|
|||
}
|
||||
|
||||
match ct.val {
|
||||
ty::ConstKind::Unevaluated(did, substs, promoted) => {
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
if let Some(promoted) = promoted {
|
||||
p!(print_value_path(did, substs));
|
||||
p!(print_value_path(def.did, substs));
|
||||
p!(write("::{:?}", promoted));
|
||||
} else {
|
||||
match self.tcx().def_kind(did) {
|
||||
match self.tcx().def_kind(def.did) {
|
||||
DefKind::Static | DefKind::Const | DefKind::AssocConst => {
|
||||
p!(print_value_path(did, substs))
|
||||
p!(print_value_path(def.did, substs))
|
||||
}
|
||||
_ => {
|
||||
if did.is_local() {
|
||||
let span = self.tcx().def_span(did);
|
||||
if def.is_local() {
|
||||
let span = self.tcx().def_span(def.did);
|
||||
if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
|
||||
{
|
||||
p!(write("{}", snip))
|
||||
|
|
|
|||
|
|
@ -2278,7 +2278,7 @@ impl<'tcx> Const<'tcx> {
|
|||
ty::ConstKind::Param(ty::ParamConst::new(index, name))
|
||||
}
|
||||
_ => ty::ConstKind::Unevaluated(
|
||||
def.did.to_def_id(),
|
||||
def.to_global(),
|
||||
InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
None,
|
||||
),
|
||||
|
|
@ -2347,7 +2347,7 @@ impl<'tcx> Const<'tcx> {
|
|||
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
|
||||
/// unevaluated constant.
|
||||
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
|
||||
if let ConstKind::Unevaluated(did, substs, promoted) = self.val {
|
||||
if let ConstKind::Unevaluated(def, substs, promoted) = self.val {
|
||||
use crate::mir::interpret::ErrorHandled;
|
||||
|
||||
let param_env_and_substs = param_env.with_reveal_all().and(substs);
|
||||
|
|
@ -2363,7 +2363,7 @@ impl<'tcx> Const<'tcx> {
|
|||
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
|
||||
// we can call `infcx.const_eval_resolve` which handles inference variables.
|
||||
let param_env_and_substs = if param_env_and_substs.needs_infer() {
|
||||
tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did))
|
||||
tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did))
|
||||
} else {
|
||||
param_env_and_substs
|
||||
};
|
||||
|
|
@ -2373,7 +2373,7 @@ impl<'tcx> Const<'tcx> {
|
|||
let (param_env, substs) = param_env_and_substs.into_parts();
|
||||
// try to resolve e.g. associated constants to their definition on an impl, and then
|
||||
// evaluate the const.
|
||||
match tcx.const_eval_resolve(param_env, did, substs, promoted, None) {
|
||||
match tcx.const_eval_resolve(param_env, def.did, substs, promoted, None) {
|
||||
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
|
||||
// and we use the original type, so nothing from `substs`
|
||||
// (which may be identity substs, see above),
|
||||
|
|
@ -2433,7 +2433,7 @@ pub enum ConstKind<'tcx> {
|
|||
|
||||
/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
|
||||
/// variants when the code is monomorphic enough for that.
|
||||
Unevaluated(DefId, SubstsRef<'tcx>, Option<Promoted>),
|
||||
Unevaluated(ty::WithOptParam<DefId>, SubstsRef<'tcx>, Option<Promoted>),
|
||||
|
||||
/// Used to hold computed value.
|
||||
Value(ConstValue<'tcx>),
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
}
|
||||
} else {
|
||||
let tcx = self.tcx();
|
||||
if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val {
|
||||
if let Some(promoted) = promoted {
|
||||
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
|
||||
promoted: &Body<'tcx>,
|
||||
|
|
@ -357,7 +357,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
|||
ConstraintCategory::Boring,
|
||||
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
|
||||
constant.literal.ty,
|
||||
def_id,
|
||||
def.did,
|
||||
UserSubsts { substs, user_self_ty: None },
|
||||
)),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -549,8 +549,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let val_val = match val.val {
|
||||
ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
|
||||
ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)),
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
let instance = self.resolve(def.did, substs)?;
|
||||
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
|
||||
// The reason we use `const_eval_raw` everywhere else is to prevent cycles during
|
||||
// validation, because validation automatically reads through any references, thus
|
||||
|
|
|
|||
|
|
@ -622,12 +622,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
|
||||
match substituted_constant.val {
|
||||
ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) {
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
match self.tcx.const_eval_resolve(param_env, def.did, substs, promoted, None) {
|
||||
Ok(val) => collect_const_value(self.tcx, val, self.output),
|
||||
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
|
||||
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||
self.tcx.def_span(def_id),
|
||||
self.tcx.def_span(def.did),
|
||||
"collection encountered polymorphic constant",
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,11 +244,11 @@ where
|
|||
};
|
||||
|
||||
// Check the qualifs of the value of `const` items.
|
||||
if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val {
|
||||
if let ty::ConstKind::Unevaluated(def, _, promoted) = constant.literal.val {
|
||||
assert!(promoted.is_none());
|
||||
// Don't peek inside trait associated constants.
|
||||
if cx.tcx.trait_of_item(def_id).is_none() {
|
||||
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def_id);
|
||||
if cx.tcx.trait_of_item(def.did).is_none() {
|
||||
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did);
|
||||
if !Q::in_qualifs(&qualifs) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -955,7 +955,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
literal: tcx.mk_const(ty::Const {
|
||||
ty,
|
||||
val: ty::ConstKind::Unevaluated(
|
||||
def_id,
|
||||
ty::WithOptParam::dummy(def_id),
|
||||
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||
tcx.lifetimes.re_erased.into()
|
||||
|
|
|
|||
|
|
@ -600,7 +600,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
|||
// and not the beginning of discriminants (which is always `0`)
|
||||
let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
|
||||
let lhs = mk_const(cx.tcx().mk_const(ty::Const {
|
||||
val: ty::ConstKind::Unevaluated(did, substs, None),
|
||||
val: ty::ConstKind::Unevaluated(
|
||||
ty::WithOptParam::dummy(did),
|
||||
substs,
|
||||
None,
|
||||
),
|
||||
ty: var_ty,
|
||||
}));
|
||||
let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
|
||||
|
|
@ -796,7 +800,7 @@ fn convert_path_expr<'a, 'tcx>(
|
|||
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
|
||||
ExprKind::Literal {
|
||||
literal: cx.tcx.mk_const(ty::Const {
|
||||
val: ty::ConstKind::Unevaluated(def_id, substs, None),
|
||||
val: ty::ConstKind::Unevaluated(ty::WithOptParam::dummy(def_id), substs, None),
|
||||
ty: cx.tables().node_type(expr.hir_id),
|
||||
}),
|
||||
user_ty,
|
||||
|
|
|
|||
|
|
@ -524,10 +524,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||
let stalled_on = &mut pending_obligation.stalled_on;
|
||||
|
||||
let mut evaluate = |c: &'tcx Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
|
||||
match self.selcx.infcx().const_eval_resolve(
|
||||
obligation.param_env,
|
||||
def_id,
|
||||
def.did,
|
||||
substs,
|
||||
promoted,
|
||||
Some(obligation.cause.span),
|
||||
|
|
|
|||
|
|
@ -507,11 +507,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
debug!("evaluate_predicate_recursively: equating consts c1={:?} c2={:?}", c1, c2);
|
||||
|
||||
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
|
||||
self.infcx
|
||||
.const_eval_resolve(
|
||||
obligation.param_env,
|
||||
def_id,
|
||||
def.did,
|
||||
substs,
|
||||
promoted,
|
||||
Some(obligation.cause.span),
|
||||
|
|
|
|||
|
|
@ -359,13 +359,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
|
||||
GenericArgKind::Const(constant) => {
|
||||
match constant.val {
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
assert!(promoted.is_none());
|
||||
|
||||
let obligations = self.nominal_obligations(def_id, substs);
|
||||
let obligations = self.nominal_obligations(def.did, substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
let predicate = ty::PredicateKind::ConstEvaluatable(def_id, substs)
|
||||
let predicate = ty::PredicateKind::ConstEvaluatable(def.did, substs)
|
||||
.to_predicate(self.tcx());
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
self.out.push(traits::Obligation::new(
|
||||
|
|
|
|||
|
|
@ -466,12 +466,12 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
|
|||
|
||||
pub fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
|
||||
match n.val {
|
||||
ty::ConstKind::Unevaluated(def_id, _, promoted) => {
|
||||
let mut s = if let Some(def_id) = def_id.as_local() {
|
||||
let hir_id = cx.tcx.hir().as_local_hir_id(def_id);
|
||||
ty::ConstKind::Unevaluated(def, _, promoted) => {
|
||||
let mut s = if let Some(def) = def.as_local() {
|
||||
let hir_id = cx.tcx.hir().as_local_hir_id(def.did);
|
||||
print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id))
|
||||
} else {
|
||||
inline::print_inlined_const(cx, def_id)
|
||||
inline::print_inlined_const(cx, def.did)
|
||||
};
|
||||
if let Some(promoted) = promoted {
|
||||
s.push_str(&format!("::{:?}", promoted))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue