implement valtrees as the type-system representation for constant values
This commit is contained in:
parent
edab34ab2a
commit
705d818bd5
116 changed files with 1606 additions and 1032 deletions
|
@ -6,6 +6,7 @@ use super::*;
|
|||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::project::ProjectAndUnifyResult;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{Region, RegionVid, Term};
|
||||
|
||||
|
@ -834,7 +835,16 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
unevaluated,
|
||||
Some(obligation.cause.span),
|
||||
) {
|
||||
Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty())),
|
||||
Ok(Some(valtree)) => {
|
||||
Ok(ty::Const::from_value(select.tcx(), valtree, c.ty()))
|
||||
}
|
||||
Ok(None) => {
|
||||
let tcx = self.tcx;
|
||||
let def_id = unevaluated.def.did;
|
||||
let reported = tcx.sess.struct_span_err(tcx.def_span(def_id), &format!("unable to construct a constant value for the unevaluated constant {:?}", unevaluated)).emit();
|
||||
|
||||
Err(ErrorHandled::Reported(reported))
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -13,9 +13,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{
|
||||
ConstValue, ErrorHandled, LitToConstError, LitToConstInput, Scalar,
|
||||
};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput};
|
||||
use rustc_middle::thir;
|
||||
use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable};
|
||||
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
||||
|
@ -449,9 +447,8 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
self.nodes.push(Node::Leaf(constant))
|
||||
}
|
||||
&ExprKind::NonHirLiteral { lit , user_ty: _} => {
|
||||
// FIXME Construct a Valtree from this ScalarInt when introducing Valtrees
|
||||
let const_value = ConstValue::Scalar(Scalar::Int(lit));
|
||||
self.nodes.push(Node::Leaf(ty::Const::from_value(self.tcx, const_value, node.ty)))
|
||||
let val = ty::ValTree::from_scalar_int(lit);
|
||||
self.nodes.push(Node::Leaf(ty::Const::from_value(self.tcx, val, node.ty)))
|
||||
}
|
||||
&ExprKind::NamedConst { def_id, substs, user_ty: _ } => {
|
||||
let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs);
|
||||
|
|
|
@ -407,7 +407,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
let pred =
|
||||
ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
|
||||
ProcessResult::Changed(mk_pending(vec![
|
||||
obligation.with(pred.to_predicate(self.selcx.tcx())),
|
||||
obligation.with(pred.to_predicate(self.selcx.tcx()))
|
||||
]))
|
||||
}
|
||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||
|
@ -594,22 +594,24 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
|
||||
let mut evaluate = |c: Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
|
||||
match self.selcx.infcx().const_eval_resolve(
|
||||
match self.selcx.infcx().try_const_eval_resolve(
|
||||
obligation.param_env,
|
||||
unevaluated,
|
||||
c.ty(),
|
||||
Some(obligation.cause.span),
|
||||
) {
|
||||
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty())),
|
||||
Err(ErrorHandled::TooGeneric) => {
|
||||
stalled_on.extend(
|
||||
unevaluated
|
||||
.substs
|
||||
.iter()
|
||||
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
|
||||
);
|
||||
Err(ErrorHandled::TooGeneric)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => match e {
|
||||
ErrorHandled::TooGeneric => {
|
||||
stalled_on.extend(
|
||||
unevaluated.substs.iter().filter_map(
|
||||
TyOrConstInferVar::maybe_from_generic_arg,
|
||||
),
|
||||
);
|
||||
Err(ErrorHandled::TooGeneric)
|
||||
}
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
Ok(c)
|
||||
|
|
|
@ -618,11 +618,14 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
if self.selcx.tcx().lazy_normalization() || !self.eager_inference_replacement {
|
||||
constant
|
||||
} else {
|
||||
let constant = constant.super_fold_with(self);
|
||||
debug!(?constant);
|
||||
debug!("self.param_env: {:?}", self.param_env);
|
||||
constant.eval(self.selcx.tcx(), self.param_env)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Visitor to find the maximum escaping bound var
|
||||
// Visitor to find the maximum escaping bound var
|
||||
struct MaxEscapingBoundVarVisitor {
|
||||
// The index which would count as escaping
|
||||
outer_index: ty::DebruijnIndex,
|
||||
|
@ -336,12 +336,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
Ok(match constant {
|
||||
mir::ConstantKind::Ty(c) => {
|
||||
let const_folded = c.try_fold_with(self)?;
|
||||
let const_folded = c.try_super_fold_with(self)?;
|
||||
match const_folded.kind() {
|
||||
ty::ConstKind::Value(cv) => {
|
||||
// FIXME With Valtrees we need to convert `cv: ValTree`
|
||||
// to a `ConstValue` here.
|
||||
mir::ConstantKind::Val(cv, const_folded.ty())
|
||||
ty::ConstKind::Value(valtree) => {
|
||||
let tcx = self.infcx.tcx;
|
||||
let ty = const_folded.ty();
|
||||
let const_val = tcx.valtree_to_const_val((ty, valtree));
|
||||
debug!(?ty, ?valtree, ?const_val);
|
||||
|
||||
mir::ConstantKind::Val(const_val, ty)
|
||||
}
|
||||
_ => mir::ConstantKind::Ty(const_folded),
|
||||
}
|
||||
|
|
|
@ -636,13 +636,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
let evaluate = |c: ty::Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
|
||||
self.infcx
|
||||
.const_eval_resolve(
|
||||
obligation.param_env,
|
||||
unevaluated,
|
||||
Some(obligation.cause.span),
|
||||
)
|
||||
.map(|val| ty::Const::from_value(self.tcx(), val, c.ty()))
|
||||
match self.infcx.try_const_eval_resolve(
|
||||
obligation.param_env,
|
||||
unevaluated,
|
||||
c.ty(),
|
||||
Some(obligation.cause.span),
|
||||
) {
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
} else {
|
||||
Ok(c)
|
||||
}
|
||||
|
@ -2576,7 +2578,11 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> {
|
|||
}
|
||||
|
||||
fn depth(&self) -> usize {
|
||||
if let Some(head) = self.head { head.depth } else { 0 }
|
||||
if let Some(head) = self.head {
|
||||
head.depth
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue