From 662e9c7660403d278a660b25a3c1feec5cbbd275 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Thu, 23 Jul 2026 01:13:06 +0000
Subject: [PATCH 15/30] hir_typeck: compare const generics in
 HMTypeInferrence::pathparams_equal

pathparams_equal only compared type params, so two paths differing only
in const generics (e.g. `Bump<{_/*ivar*/}>` vs `Bump<{MIN_ALIGN}>`)
compared equal. The deref-coercion path in check_unsize_tys uses
types_equal to decide whether an equate is needed after inserting
derefs - with the params "equal" it skipped the equate, leaving the
value ivar unbound and tripping the final !val.is_Infer() assert.

Seen with bumpalo 3.20.2 (`Bump<const MIN_ALIGN: usize = 1>`):
`Bump::shrink(self)` with `self: &mut &Bump<MIN_ALIGN>` ICEd with
"Failure to infer Infer(0)" at expr_cs.cpp:1665.

Values are compared through the value-ivar table (get_value), mirroring
what get_type does for type params; Context::equate_types already
equates m_values, so the previously-skipped equate now binds the ivar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wCVW89GjmNyYviEcANPHM
---
 src/hir_typeck/helpers.cpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 7f87d94c..8b12328d 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1150,7 +1150,20 @@ namespace {
 }
 bool HMTypeInferrence::pathparams_equal(const ::HIR::PathParams& pps_l, const ::HIR::PathParams& pps_r) const
 {
-    return type_list_equal(*this, pps_l.m_types, pps_r.m_types);
+    if( !type_list_equal(*this, pps_l.m_types, pps_r.m_types) )
+        return false;
+    // Also compare const generics (through the value ivar table) - an unbound value
+    // ivar must not compare equal to a concrete value, otherwise coercion paths skip
+    // the equate that would bind it (seen with `Bump::<{_}>::shrink(self)` in bumpalo
+    // 3.20, where the receiver's `MIN_ALIGN` never got unified).
+    if( pps_l.m_values.size() != pps_r.m_values.size() )
+        return false;
+    for( size_t i = 0; i < pps_l.m_values.size(); i ++ )
+    {
+        if( !(this->get_value(pps_l.m_values[i]) == this->get_value(pps_r.m_values[i])) )
+            return false;
+    }
+    return true;
 }
 bool HMTypeInferrence::types_equal(const ::HIR::TypeRef& rl, const ::HIR::TypeRef& rr) const
 {
-- 
2.43.0

