use ty::Unevaluated instead of def substs pair

This commit is contained in:
lcnr 2021-07-19 13:52:43 +02:00
parent 031243898e
commit caa975c89e
19 changed files with 66 additions and 86 deletions

View file

@ -678,10 +678,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
a: ty::Unevaluated<'tcx>, a: ty::Unevaluated<'tcx>,
b: ty::Unevaluated<'tcx>, b: ty::Unevaluated<'tcx>,
) -> bool { ) -> bool {
let canonical = self.canonicalize_query( let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default());
((a.def, a.substs(self.tcx)), (b.def, b.substs(self.tcx))),
&mut OriginalQueryValues::default(),
);
debug!("canonical consts: {:?}", &canonical.value); debug!("canonical consts: {:?}", &canonical.value);
self.tcx.try_unify_abstract_consts(canonical.value) self.tcx.try_unify_abstract_consts(canonical.value)

View file

@ -303,12 +303,11 @@ rustc_queries! {
} }
query try_unify_abstract_consts(key: ( query try_unify_abstract_consts(key: (
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>), ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)
)) -> bool { )) -> bool {
desc { desc {
|tcx| "trying to unify the generic constants {} and {}", |tcx| "trying to unify the generic constants {} and {}",
tcx.def_path_str(key.0.0.did), tcx.def_path_str(key.1.0.did) tcx.def_path_str(key.0.def.did), tcx.def_path_str(key.1.def.did)
} }
} }

View file

@ -18,7 +18,7 @@ use super::ScalarInt;
/// ///
/// We check for all possible substs in `fn default_anon_const_substs`, /// We check for all possible substs in `fn default_anon_const_substs`,
/// so refer to that check for more info. /// so refer to that check for more info.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
#[derive(Hash, HashStable)] #[derive(Hash, HashStable)]
pub struct Unevaluated<'tcx> { pub struct Unevaluated<'tcx> {
pub def: ty::WithOptConstParam<DefId>, pub def: ty::WithOptConstParam<DefId>,

View file

@ -252,8 +252,8 @@ impl FlagComputation {
ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => { ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => {
self.add_substs(substs); self.add_substs(substs);
} }
ty::PredicateKind::ConstEvaluatable(_def_id, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
self.add_substs(substs); self.add_unevaluated_const(uv);
} }
ty::PredicateKind::ConstEquate(expected, found) => { ty::PredicateKind::ConstEquate(expected, found) => {
self.add_const(expected); self.add_const(expected);

View file

@ -406,7 +406,7 @@ crate struct PredicateInner<'tcx> {
} }
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(PredicateInner<'_>, 48); static_assert_size!(PredicateInner<'_>, 56);
#[derive(Clone, Copy, Lift)] #[derive(Clone, Copy, Lift)]
pub struct Predicate<'tcx> { pub struct Predicate<'tcx> {
@ -502,7 +502,7 @@ pub enum PredicateKind<'tcx> {
Coerce(CoercePredicate<'tcx>), Coerce(CoercePredicate<'tcx>),
/// Constant initializer must evaluate successfully. /// Constant initializer must evaluate successfully.
ConstEvaluatable(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>), ConstEvaluatable(ty::Unevaluated<'tcx>),
/// Constants must be equal. The first component is the const that is expected. /// Constants must be equal. The first component is the const that is expected.
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>), ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),

View file

@ -2294,8 +2294,8 @@ define_print_and_forward_display! {
print_value_path(closure_def_id, &[]), print_value_path(closure_def_id, &[]),
write("` implements the trait `{}`", kind)) write("` implements the trait `{}`", kind))
} }
ty::PredicateKind::ConstEvaluatable(def, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
p!("the constant `", print_value_path(def.did, substs), "` can be evaluated") p!("the constant `", print_value_path(uv.def.did, uv.substs_.map_or(&[], |x| x)), "` can be evaluated")
} }
ty::PredicateKind::ConstEquate(c1, c2) => { ty::PredicateKind::ConstEquate(c1, c2) => {
p!("the constant `", print(c1), "` equals `", print(c2), "`") p!("the constant `", print(c1), "` equals `", print(c2), "`")

View file

@ -579,7 +579,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
if tcx.features().const_evaluatable_checked => if tcx.features().const_evaluatable_checked =>
{ {
tcx.try_unify_abstract_consts(((au.def, au.substs(tcx)), (bu.def, bu.substs(tcx)))) tcx.try_unify_abstract_consts((au, bu))
} }
// While this is slightly incorrect, it shouldn't matter for `min_const_generics` // While this is slightly incorrect, it shouldn't matter for `min_const_generics`

View file

@ -190,8 +190,8 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
} }
ty::PredicateKind::ConstEvaluatable(def_id, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) write!(f, "ConstEvaluatable({:?}, {:?})", uv.def, uv.substs_)
} }
ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2), ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
ty::PredicateKind::TypeWellFormedFromEnv(ty) => { ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
@ -447,8 +447,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
ty::PredicateKind::ObjectSafe(trait_def_id) => { ty::PredicateKind::ObjectSafe(trait_def_id) => {
Some(ty::PredicateKind::ObjectSafe(trait_def_id)) Some(ty::PredicateKind::ObjectSafe(trait_def_id))
} }
ty::PredicateKind::ConstEvaluatable(def_id, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
tcx.lift(substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def_id, substs)) tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv))
} }
ty::PredicateKind::ConstEquate(c1, c2) => { ty::PredicateKind::ConstEquate(c1, c2) => {
tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2)) tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2))

View file

@ -134,11 +134,11 @@ where
ty.visit_with(self) ty.visit_with(self)
} }
ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE, ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE,
ty::PredicateKind::ConstEvaluatable(defs, substs) ty::PredicateKind::ConstEvaluatable(uv)
if self.def_id_visitor.tcx().features().const_evaluatable_checked => if self.def_id_visitor.tcx().features().const_evaluatable_checked =>
{ {
let tcx = self.def_id_visitor.tcx(); let tcx = self.def_id_visitor.tcx();
if let Ok(Some(ct)) = AbstractConst::new(tcx, defs, substs) { if let Ok(Some(ct)) = AbstractConst::new(tcx, uv) {
self.visit_abstract_const_expr(tcx, ct)?; self.visit_abstract_const_expr(tcx, ct)?;
} }
ControlFlow::CONTINUE ControlFlow::CONTINUE

View file

@ -217,18 +217,13 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
} }
} }
impl<'tcx> Key impl<'tcx> Key for (ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>) {
for (
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
)
{
#[inline(always)] #[inline(always)]
fn query_crate_is_local(&self) -> bool { fn query_crate_is_local(&self) -> bool {
(self.0).0.did.krate == LOCAL_CRATE (self.0).def.did.krate == LOCAL_CRATE
} }
fn default_span(&self, tcx: TyCtxt<'_>) -> Span { fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
(self.0).0.did.default_span(tcx) (self.0).def.did.default_span(tcx)
} }
} }

View file

@ -19,7 +19,7 @@ use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind};
use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::subst::{Subst, SubstsRef};
use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::def_id::LocalDefId;
use rustc_span::Span; use rustc_span::Span;
use std::cmp; use std::cmp;
@ -29,26 +29,20 @@ use std::ops::ControlFlow;
/// Check if a given constant can be evaluated. /// Check if a given constant can be evaluated.
pub fn is_const_evaluatable<'cx, 'tcx>( pub fn is_const_evaluatable<'cx, 'tcx>(
infcx: &InferCtxt<'cx, 'tcx>, infcx: &InferCtxt<'cx, 'tcx>,
def: ty::WithOptConstParam<DefId>, uv: ty::Unevaluated<'tcx>,
substs: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
span: Span, span: Span,
) -> Result<(), NotConstEvaluatable> { ) -> Result<(), NotConstEvaluatable> {
debug!("is_const_evaluatable({:?}, {:?})", def, substs); debug!("is_const_evaluatable({:?})", uv);
if infcx.tcx.features().const_evaluatable_checked { if infcx.tcx.features().const_evaluatable_checked {
let tcx = infcx.tcx; let tcx = infcx.tcx;
match AbstractConst::new(tcx, def, substs)? { match AbstractConst::new(tcx, uv)? {
// We are looking at a generic abstract constant. // We are looking at a generic abstract constant.
Some(ct) => { Some(ct) => {
for pred in param_env.caller_bounds() { for pred in param_env.caller_bounds() {
match pred.kind().skip_binder() { match pred.kind().skip_binder() {
ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
if b_def == def && b_substs == substs { if let Some(b_ct) = AbstractConst::new(tcx, uv)? {
debug!("is_const_evaluatable: caller_bound ~~> ok");
return Ok(());
}
if let Some(b_ct) = AbstractConst::new(tcx, b_def, b_substs)? {
// Try to unify with each subtree in the AbstractConst to allow for // Try to unify with each subtree in the AbstractConst to allow for
// `N + 1` being const evaluatable even if theres only a `ConstEvaluatable` // `N + 1` being const evaluatable even if theres only a `ConstEvaluatable`
// predicate for `(N + 1) * 2` // predicate for `(N + 1) * 2`
@ -134,7 +128,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
} }
let future_compat_lint = || { let future_compat_lint = || {
if let Some(local_def_id) = def.did.as_local() { if let Some(local_def_id) = uv.def.did.as_local() {
infcx.tcx.struct_span_lint_hir( infcx.tcx.struct_span_lint_hir(
lint::builtin::CONST_EVALUATABLE_UNCHECKED, lint::builtin::CONST_EVALUATABLE_UNCHECKED,
infcx.tcx.hir().local_def_id_to_hir_id(local_def_id), infcx.tcx.hir().local_def_id_to_hir_id(local_def_id),
@ -155,13 +149,12 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
// and hopefully soon change this to an error. // and hopefully soon change this to an error.
// //
// See #74595 for more details about this. // See #74595 for more details about this.
let concrete = let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
infcx.const_eval_resolve(param_env, ty::Unevaluated::new(def, substs), Some(span));
if concrete.is_ok() && substs.has_param_types_or_consts(infcx.tcx) { if concrete.is_ok() && uv.substs(infcx.tcx).has_param_types_or_consts(infcx.tcx) {
match infcx.tcx.def_kind(def.did) { match infcx.tcx.def_kind(uv.def.did) {
DefKind::AnonConst => { DefKind::AnonConst => {
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(def); let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
if mir_body.is_polymorphic { if mir_body.is_polymorphic {
future_compat_lint(); future_compat_lint();
@ -173,7 +166,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
debug!(?concrete, "is_const_evaluatable"); debug!(?concrete, "is_const_evaluatable");
match concrete { match concrete {
Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() { Err(ErrorHandled::TooGeneric) => Err(match uv.has_infer_types_or_consts() {
true => NotConstEvaluatable::MentionsInfer, true => NotConstEvaluatable::MentionsInfer,
false => NotConstEvaluatable::MentionsParam, false => NotConstEvaluatable::MentionsParam,
}), }),
@ -198,15 +191,14 @@ pub struct AbstractConst<'tcx> {
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
} }
impl AbstractConst<'tcx> { impl<'tcx> AbstractConst<'tcx> {
pub fn new( pub fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<DefId>, uv: ty::Unevaluated<'tcx>,
substs: SubstsRef<'tcx>,
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> { ) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
let inner = tcx.mir_abstract_const_opt_const_arg(def)?; let inner = tcx.mir_abstract_const_opt_const_arg(uv.def)?;
debug!("AbstractConst::new({:?}) = {:?}", def, inner); debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
Ok(inner.map(|inner| AbstractConst { inner, substs })) Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs(tcx) }))
} }
pub fn from_const( pub fn from_const(
@ -214,7 +206,7 @@ impl AbstractConst<'tcx> {
ct: &ty::Const<'tcx>, ct: &ty::Const<'tcx>,
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> { ) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
match ct.val { match ct.val {
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.def, uv.substs(tcx)), ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv),
ty::ConstKind::Error(_) => Err(ErrorReported), ty::ConstKind::Error(_) => Err(ErrorReported),
_ => Ok(None), _ => Ok(None),
} }
@ -564,14 +556,11 @@ pub(super) fn mir_abstract_const<'tcx>(
pub(super) fn try_unify_abstract_consts<'tcx>( pub(super) fn try_unify_abstract_consts<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
((a, a_substs), (b, b_substs)): ( (a, b): (ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>),
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
),
) -> bool { ) -> bool {
(|| { (|| {
if let Some(a) = AbstractConst::new(tcx, a, a_substs)? { if let Some(a) = AbstractConst::new(tcx, a)? {
if let Some(b) = AbstractConst::new(tcx, b, b_substs)? { if let Some(b) = AbstractConst::new(tcx, b)? {
return Ok(try_unify(tcx, a, b)); return Ok(try_unify(tcx, a, b));
} }
} }

View file

@ -811,10 +811,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
} }
match obligation.predicate.kind().skip_binder() { match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::ConstEvaluatable(def, _) => { ty::PredicateKind::ConstEvaluatable(uv) => {
let mut err = let mut err =
self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
let const_span = self.tcx.def_span(def.did); let const_span = self.tcx.def_span(uv.def.did);
match self.tcx.sess.source_map().span_to_snippet(const_span) { match self.tcx.sess.source_map().span_to_snippet(const_span) {
Ok(snippet) => err.help(&format!( Ok(snippet) => err.help(&format!(
"try adding a `where` bound using this expression: `where [(); {}]:`", "try adding a `where` bound using this expression: `where [(); {}]:`",

View file

@ -543,11 +543,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
} }
} }
ty::PredicateKind::ConstEvaluatable(def_id, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
match const_evaluatable::is_const_evaluatable( match const_evaluatable::is_const_evaluatable(
self.selcx.infcx(), self.selcx.infcx(),
def_id, uv,
substs,
obligation.param_env, obligation.param_env,
obligation.cause.span, obligation.cause.span,
) { ) {
@ -555,7 +554,9 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
Err(NotConstEvaluatable::MentionsInfer) => { Err(NotConstEvaluatable::MentionsInfer) => {
pending_obligation.stalled_on.clear(); pending_obligation.stalled_on.clear();
pending_obligation.stalled_on.extend( pending_obligation.stalled_on.extend(
substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg), uv.substs(infcx.tcx)
.iter()
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
); );
ProcessResult::Unchanged ProcessResult::Unchanged
} }

View file

@ -854,12 +854,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
} }
fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::PredicateKind::ConstEvaluatable(def, substs) = pred.kind().skip_binder() { if let ty::PredicateKind::ConstEvaluatable(ct) = pred.kind().skip_binder() {
// FIXME(const_evaluatable_checked): We should probably deduplicate the logic for // FIXME(const_evaluatable_checked): We should probably deduplicate the logic for
// `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to
// take a `ty::Const` instead. // take a `ty::Const` instead.
use rustc_middle::mir::abstract_const::Node; use rustc_middle::mir::abstract_const::Node;
if let Ok(Some(ct)) = AbstractConst::new(self.tcx, def, substs) { if let Ok(Some(ct)) = AbstractConst::new(self.tcx, ct) {
const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() {
Node::Leaf(leaf) => { Node::Leaf(leaf) => {
let leaf = leaf.subst(self.tcx, ct.substs); let leaf = leaf.subst(self.tcx, ct.substs);

View file

@ -598,11 +598,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
} }
ty::PredicateKind::ConstEvaluatable(def_id, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
match const_evaluatable::is_const_evaluatable( match const_evaluatable::is_const_evaluatable(
self.infcx, self.infcx,
def_id, uv,
substs,
obligation.param_env, obligation.param_env,
obligation.cause.span, obligation.cause.span,
) { ) {

View file

@ -132,8 +132,9 @@ pub fn predicate_obligations<'a, 'tcx>(
wf.compute(a.into()); wf.compute(a.into());
wf.compute(b.into()); wf.compute(b.into());
} }
ty::PredicateKind::ConstEvaluatable(def, substs) => { ty::PredicateKind::ConstEvaluatable(uv) => {
let obligations = wf.nominal_obligations(def.did, substs); let substs = uv.substs(wf.tcx());
let obligations = wf.nominal_obligations(uv.def.did, substs);
wf.out.extend(obligations); wf.out.extend(obligations);
for arg in substs.iter() { for arg in substs.iter() {
@ -442,7 +443,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let obligations = self.nominal_obligations(uv.def.did, substs); let obligations = self.nominal_obligations(uv.def.did, substs);
self.out.extend(obligations); self.out.extend(obligations);
let predicate = ty::PredicateKind::ConstEvaluatable(uv.def, substs) let predicate = ty::PredicateKind::ConstEvaluatable(
ty::Unevaluated::new(uv.def, substs),
)
.to_predicate(self.tcx()); .to_predicate(self.tcx());
let cause = self.cause(traits::MiscObligation); let cause = self.cause(traits::MiscObligation);
self.out.push(traits::Obligation::with_depth( self.out.push(traits::Obligation::with_depth(

View file

@ -236,9 +236,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok() relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
} }
( (
ty::PredicateKind::ConstEvaluatable(def_a, substs_a), ty::PredicateKind::ConstEvaluatable(a),
ty::PredicateKind::ConstEvaluatable(def_b, substs_b), ty::PredicateKind::ConstEvaluatable(b),
) => tcx.try_unify_abstract_consts(((def_a, substs_a), (def_b, substs_b))), ) => tcx.try_unify_abstract_consts((a, b)),
(ty::PredicateKind::TypeOutlives(a), ty::PredicateKind::TypeOutlives(b)) => { (ty::PredicateKind::TypeOutlives(a), ty::PredicateKind::TypeOutlives(b)) => {
relator.relate(predicate.rebind(a.0), p.rebind(b.0)).is_ok() relator.relate(predicate.rebind(a.0), p.rebind(b.0)).is_ok()
} }

View file

@ -541,10 +541,10 @@ fn check_type_defn<'tcx, F>(
fcx.register_predicate(traits::Obligation::new( fcx.register_predicate(traits::Obligation::new(
cause, cause,
fcx.param_env, fcx.param_env,
ty::PredicateKind::ConstEvaluatable( ty::PredicateKind::ConstEvaluatable(ty::Unevaluated::new(
ty::WithOptConstParam::unknown(discr_def_id.to_def_id()), ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
discr_substs, discr_substs,
) ))
.to_predicate(tcx), .to_predicate(tcx),
)); ));
} }

View file

@ -2355,11 +2355,8 @@ fn const_evaluatable_predicates_of<'tcx>(
if let ty::ConstKind::Unevaluated(uv) = ct.val { if let ty::ConstKind::Unevaluated(uv) = ct.val {
assert_eq!(uv.promoted, None); assert_eq!(uv.promoted, None);
let span = self.tcx.hir().span(c.hir_id); let span = self.tcx.hir().span(c.hir_id);
self.preds.insert(( self.preds
ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs(self.tcx)) .insert((ty::PredicateKind::ConstEvaluatable(uv).to_predicate(self.tcx), span));
.to_predicate(self.tcx),
span,
));
} }
} }