@@ -609,9 +609,29 @@ where
609
609
/// Tries to unify two abstract constants using structural equality.
610
610
pub ( super ) fn try_unify < ' tcx > (
611
611
tcx : TyCtxt < ' tcx > ,
612
- a : AbstractConst < ' tcx > ,
613
- b : AbstractConst < ' tcx > ,
612
+ mut a : AbstractConst < ' tcx > ,
613
+ mut b : AbstractConst < ' tcx > ,
614
614
) -> bool {
615
+ // We substitute generics repeatedly to allow AbstractConsts to unify where a
616
+ // ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
617
+ // Param(N) should unify with Param(T), substs: [Unevaluated("T2", [Unevaluated("T3", [Param(N)])])]
618
+ while let Node :: Leaf ( a_ct) = a. root ( ) {
619
+ let a_ct = a_ct. subst ( tcx, a. substs ) ;
620
+ match AbstractConst :: from_const ( tcx, a_ct) {
621
+ Ok ( Some ( a_act) ) => a = a_act,
622
+ Ok ( None ) => break ,
623
+ Err ( _) => return true ,
624
+ }
625
+ }
626
+ while let Node :: Leaf ( b_ct) = b. root ( ) {
627
+ let b_ct = b_ct. subst ( tcx, b. substs ) ;
628
+ match AbstractConst :: from_const ( tcx, b_ct) {
629
+ Ok ( Some ( b_act) ) => b = b_act,
630
+ Ok ( None ) => break ,
631
+ Err ( _) => return true ,
632
+ }
633
+ }
634
+
615
635
match ( a. root ( ) , b. root ( ) ) {
616
636
( Node :: Leaf ( a_ct) , Node :: Leaf ( b_ct) ) => {
617
637
let a_ct = a_ct. subst ( tcx, a. substs ) ;
@@ -632,8 +652,6 @@ pub(super) fn try_unify<'tcx>(
632
652
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
633
653
// means that we only allow inference variables if they are equal.
634
654
( ty:: ConstKind :: Infer ( a_val) , ty:: ConstKind :: Infer ( b_val) ) => a_val == b_val,
635
- // We may want to instead recurse into unevaluated constants here. That may require some
636
- // care to prevent infinite recursion, so let's just ignore this for now.
637
655
(
638
656
ty:: ConstKind :: Unevaluated ( a_def, a_substs, None ) ,
639
657
ty:: ConstKind :: Unevaluated ( b_def, b_substs, None ) ,
0 commit comments