change thir to use mir::ConstantKind instead of ty::Const
This commit is contained in:
parent
9d843171d1
commit
b38077ea0b
29 changed files with 534 additions and 112 deletions
|
@ -37,9 +37,14 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<(), NotConstEvaluatable> {
|
||||
<<<<<<< HEAD
|
||||
let tcx = infcx.tcx;
|
||||
|
||||
if tcx.features().generic_const_exprs {
|
||||
=======
|
||||
if infcx.tcx.features().generic_const_exprs {
|
||||
let tcx = infcx.tcx;
|
||||
>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const)
|
||||
match AbstractConst::new(tcx, uv)? {
|
||||
// We are looking at a generic abstract constant.
|
||||
Some(ct) => {
|
||||
|
@ -244,7 +249,7 @@ impl<'tcx> AbstractConst<'tcx> {
|
|||
Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs }))
|
||||
}
|
||||
|
||||
pub fn from_const(
|
||||
pub fn from_constant(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ct: ty::Const<'tcx>,
|
||||
) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
|
||||
|
@ -376,6 +381,10 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
visit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, ct: mir::ConstantKind<'tcx>) {
|
||||
self.is_poly |= ct.has_param_types_or_consts();
|
||||
}
|
||||
}
|
||||
|
||||
let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
|
||||
|
@ -414,10 +423,10 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
self.recurse_build(self.body_id)?;
|
||||
|
||||
for n in self.nodes.iter() {
|
||||
if let Node::Leaf(ty::Const(Interned(
|
||||
if let Node::Leaf(mir::ConstantKind::Ty(ty::Const(Interned(
|
||||
ty::ConstS { val: ty::ConstKind::Unevaluated(ct), ty: _ },
|
||||
_,
|
||||
))) = n
|
||||
)))) = n
|
||||
{
|
||||
// `AbstractConst`s should not contain any promoteds as they require references which
|
||||
// are not allowed.
|
||||
|
@ -637,6 +646,7 @@ pub(super) fn thir_abstract_const<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub(super) fn try_unify_abstract_consts<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>),
|
||||
|
@ -806,3 +816,51 @@ impl<'tcx> ConstUnifyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Think I need these changes
|
||||
=======
|
||||
match (a_ct, b_ct) {
|
||||
(mir::ConstantKind::Ty(a_ct), mir::ConstantKind::Ty(b_ct)) => {
|
||||
match (a_ct.val(), b_ct.val()) {
|
||||
// We can just unify errors with everything to reduce the amount of
|
||||
// emitted errors here.
|
||||
(ty::ConstKind::Error(_), _) | (_, ty::ConstKind::Error(_)) => true,
|
||||
(ty::ConstKind::Param(a_param), ty::ConstKind::Param(b_param)) => {
|
||||
a_param == b_param
|
||||
}
|
||||
(ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => {
|
||||
a_val == b_val
|
||||
}
|
||||
|
||||
// If we have `fn a<const N: usize>() -> [u8; N + 1]` and `fn b<const M: usize>() -> [u8; 1 + M]`
|
||||
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
|
||||
// means that we only allow inference variables if they are equal.
|
||||
(ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => {
|
||||
a_val == b_val
|
||||
}
|
||||
// We expand generic anonymous constants at the start of this function, so this
|
||||
// branch should only be taking when dealing with associated constants, at
|
||||
// which point directly comparing them seems like the desired behavior.
|
||||
//
|
||||
// FIXME(generic_const_exprs): This isn't actually the case.
|
||||
// We also take this branch for concrete anonymous constants and
|
||||
// expand generic anonymous constants with concrete substs.
|
||||
(ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => {
|
||||
a_uv == b_uv
|
||||
}
|
||||
// FIXME(generic_const_exprs): We may want to either actually try
|
||||
// to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
|
||||
// this, for now we just return false here.
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(mir::ConstantKind::Val(a_val, a_ty), mir::ConstantKind::Val(b_val, b_ty)) => {
|
||||
a_val == b_val && a_ty == b_ty
|
||||
}
|
||||
_ => {
|
||||
// FIXME Can it happen that we need to compare ConstantKind::Ty(ConstKind::Value)
|
||||
// with a ConstantKind::Val and vice versa?
|
||||
false
|
||||
>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const)
|
||||
|
||||
*/
|
|
@ -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(..) => {
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::traits::{self, Obligation, ObligationCause};
|
|||
use rustc_errors::FatalError;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir::ConstantKind;
|
||||
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor};
|
||||
use rustc_middle::ty::{Predicate, ToPredicate};
|
||||
|
@ -836,7 +837,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
|||
if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) {
|
||||
const_evaluatable::walk_abstract_const(self.tcx, ct, |node| {
|
||||
match node.root(self.tcx) {
|
||||
Node::Leaf(leaf) => self.visit_const(leaf),
|
||||
Node::Leaf(leaf) => match leaf {
|
||||
ConstantKind::Ty(c) => self.visit_const(c),
|
||||
ConstantKind::Val(_, ty) => self.visit_ty(ty),
|
||||
},
|
||||
Node::Cast(_, _, ty) => self.visit_ty(ty),
|
||||
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
|
||||
ControlFlow::CONTINUE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue