Skip to content

Commit fe69a5c

Browse files
committed
dont canonicalize in try_unify_abstract_consts and erase regions instead
1 parent 8ff1edb commit fe69a5c

File tree

2 files changed

+22
-29
lines changed

2 files changed

+22
-29
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ mod sub;
7070
pub mod type_variable;
7171
mod undo_log;
7272

73-
use crate::infer::canonical::OriginalQueryValues;
7473
pub use rustc_middle::infer::unify_key;
7574

7675
#[must_use]
@@ -695,14 +694,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
695694
) -> bool {
696695
// Reject any attempt to unify two unevaluated constants that contain inference
697696
// variables, since inference variables in queries lead to ICEs.
698-
if a.substs.has_infer_types_or_consts() || b.substs.has_infer_types_or_consts() {
699-
debug!("a or b contain infer vars in its substs -> cannot unify");
697+
if a.substs.has_infer_types_or_consts()
698+
|| b.substs.has_infer_types_or_consts()
699+
|| param_env.has_infer_types_or_consts()
700+
{
701+
debug!("a or b or param_env contain infer vars in its substs -> cannot unify");
700702
return false;
701703
}
702704

703-
let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default());
705+
let erased_args = self.tcx.erase_regions((a, b));
706+
let erased_param_env = self.tcx.erase_regions(param_env);
707+
debug!("after erase_regions args: {:?}, param_env: {:?}", erased_args, param_env);
704708

705-
self.tcx.try_unify_abstract_consts(param_env.and(canonical.value))
709+
self.tcx.try_unify_abstract_consts(erased_param_env.and(erased_args))
706710
}
707711

708712
pub fn is_in_snapshot(&self) -> bool {
@@ -1619,9 +1623,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16191623
// variables
16201624
if substs.has_infer_types_or_consts() {
16211625
debug!("substs have infer types or consts: {:?}", substs);
1622-
if substs.has_infer_types_or_consts() {
1623-
return Err(ErrorHandled::TooGeneric);
1624-
}
1626+
return Err(ErrorHandled::TooGeneric);
16251627
}
16261628

16271629
let param_env_erased = self.tcx.erase_regions(param_env);

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,13 @@ fn satisfied_from_param_env<'tcx>(
195195
match pred.kind().skip_binder() {
196196
ty::PredicateKind::ConstEvaluatable(uv) => {
197197
if let Some(b_ct) = AbstractConst::new(tcx, uv)? {
198+
let const_unify_ctxt = ConstUnifyCtxt::new(tcx, param_env);
199+
198200
// Try to unify with each subtree in the AbstractConst to allow for
199201
// `N + 1` being const evaluatable even if theres only a `ConstEvaluatable`
200202
// predicate for `(N + 1) * 2`
201203
let result = walk_abstract_const(tcx, b_ct, |b_ct| {
202-
match try_unify(tcx, ct, b_ct, param_env) {
204+
match const_unify_ctxt.try_unify(ct, b_ct) {
203205
true => ControlFlow::BREAK,
204206
false => ControlFlow::CONTINUE,
205207
}
@@ -569,18 +571,6 @@ pub(super) fn thir_abstract_const<'tcx>(
569571
}
570572
}
571573

572-
/// Tries to unify two abstract constants using structural equality.
573-
#[instrument(skip(tcx), level = "debug")]
574-
pub(super) fn try_unify<'tcx>(
575-
tcx: TyCtxt<'tcx>,
576-
a: AbstractConst<'tcx>,
577-
b: AbstractConst<'tcx>,
578-
param_env: ty::ParamEnv<'tcx>,
579-
) -> bool {
580-
let const_unify_ctxt = ConstUnifyCtxt::new(tcx, param_env);
581-
const_unify_ctxt.try_unify_inner(a, b)
582-
}
583-
584574
pub(super) fn try_unify_abstract_consts<'tcx>(
585575
tcx: TyCtxt<'tcx>,
586576
(a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>),
@@ -589,7 +579,8 @@ pub(super) fn try_unify_abstract_consts<'tcx>(
589579
(|| {
590580
if let Some(a) = AbstractConst::new(tcx, a)? {
591581
if let Some(b) = AbstractConst::new(tcx, b)? {
592-
return Ok(try_unify(tcx, a, b, param_env));
582+
let const_unify_ctxt = ConstUnifyCtxt::new(tcx, param_env);
583+
return Ok(const_unify_ctxt.try_unify(a, b));
593584
}
594585
}
595586

@@ -666,7 +657,7 @@ impl<'tcx> ConstUnifyCtxt<'tcx> {
666657

667658
/// Tries to unify two abstract constants using structural equality.
668659
#[instrument(skip(self), level = "debug")]
669-
fn try_unify_inner(&self, a: AbstractConst<'tcx>, b: AbstractConst<'tcx>) -> bool {
660+
fn try_unify(&self, a: AbstractConst<'tcx>, b: AbstractConst<'tcx>) -> bool {
670661
let a = if let Some(a) = self.try_replace_substs_in_root(a) {
671662
a
672663
} else {
@@ -723,23 +714,23 @@ impl<'tcx> ConstUnifyCtxt<'tcx> {
723714
}
724715
}
725716
(Node::Binop(a_op, al, ar), Node::Binop(b_op, bl, br)) if a_op == b_op => {
726-
self.try_unify_inner(a.subtree(al), b.subtree(bl))
727-
&& self.try_unify_inner(a.subtree(ar), b.subtree(br))
717+
self.try_unify(a.subtree(al), b.subtree(bl))
718+
&& self.try_unify(a.subtree(ar), b.subtree(br))
728719
}
729720
(Node::UnaryOp(a_op, av), Node::UnaryOp(b_op, bv)) if a_op == b_op => {
730-
self.try_unify_inner(a.subtree(av), b.subtree(bv))
721+
self.try_unify(a.subtree(av), b.subtree(bv))
731722
}
732723
(Node::FunctionCall(a_f, a_args), Node::FunctionCall(b_f, b_args))
733724
if a_args.len() == b_args.len() =>
734725
{
735-
self.try_unify_inner(a.subtree(a_f), b.subtree(b_f))
726+
self.try_unify(a.subtree(a_f), b.subtree(b_f))
736727
&& iter::zip(a_args, b_args)
737-
.all(|(&an, &bn)| self.try_unify_inner(a.subtree(an), b.subtree(bn)))
728+
.all(|(&an, &bn)| self.try_unify(a.subtree(an), b.subtree(bn)))
738729
}
739730
(Node::Cast(a_kind, a_operand, a_ty), Node::Cast(b_kind, b_operand, b_ty))
740731
if (a_ty == b_ty) && (a_kind == b_kind) =>
741732
{
742-
self.try_unify_inner(a.subtree(a_operand), b.subtree(b_operand))
733+
self.try_unify(a.subtree(a_operand), b.subtree(b_operand))
743734
}
744735
// use this over `_ => false` to make adding variants to `Node` less error prone
745736
(Node::Cast(..), _)

0 commit comments

Comments
 (0)