fix: make lcAny-producing arrow types lower to tobj rather than obj (#9972)

This PR fixes an issue when running Mathlib's `FintypeCat` as code,
where an erased type former is passed to a polymorphic function. We were
lowering the arrow type to`object`, which conflicts with the runtime
representation of an erased value as a tagged scalar.
This commit is contained in:
Cameron Zwarich 2025-08-18 15:18:26 -07:00 committed by GitHub
parent 2d4bcf202f
commit b8fa6f17ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 5 deletions

View file

@ -79,6 +79,12 @@ where fillCache : CoreM IRType := do
else
return .tobject
private def isAnyProducingType (type : Lean.Expr) : Bool :=
match type with
| .const ``lcAny _ => true
| .forallE _ _ b _ => isAnyProducingType b
| _ => false
def toIRType (type : Lean.Expr) : CoreM IRType := do
match type with
| .const name _ => nameToIRType name
@ -86,7 +92,15 @@ def toIRType (type : Lean.Expr) : CoreM IRType := do
-- All mono types are in headBeta form.
let .const name _ := type.getAppFn | unreachable!
nameToIRType name
| .forallE .. => return .object
| .forallE _ _ b _ =>
-- Type formers are erased, but can be used polymorphically as
-- an arrow type producing `lcAny`. The runtime representation of
-- erased values is a tagged scalar, so this means that any such
-- polymorphic type must be represented as `.tobject`.
if isAnyProducingType b then
return .tobject
else
return .object
| .mdata _ b => toIRType b
| _ => unreachable!

View file

@ -0,0 +1,8 @@
@[noinline]
def foo (α : Type 0) (β : Type 1) (f : α → β) (a : α) : α × β × (α → β) × (α → β) :=
⟨a, f a, f, f⟩
def alwaysNat (_ : Nat) : Type 0 := Nat
def main : IO Unit :=
IO.println f!"{foo Nat (Type 0) alwaysNat 42 |>.1}"

View file

@ -0,0 +1 @@
42

View file

@ -1,5 +1,5 @@
[Compiler.IR] [result]
def Exp.casesOn._override._redArg (x_1 : tobj) (x_2 : obj) (x_3 : obj) (x_4 : @& tobj) (x_5 : @& tobj) (x_6 : @& tobj) (x_7 : @& tobj) (x_8 : @& tobj) : tobj :=
def Exp.casesOn._override._redArg (x_1 : tobj) (x_2 : tobj) (x_3 : tobj) (x_4 : @& tobj) (x_5 : @& tobj) (x_6 : @& tobj) (x_7 : @& tobj) (x_8 : @& tobj) : tobj :=
case x_1 : tobj of
Exp.var._impl →
dec x_3;
@ -42,7 +42,7 @@
dec x_2;
inc x_8;
ret x_8
def Exp.casesOn._override (x_1 : ◾) (x_2 : tobj) (x_3 : obj) (x_4 : obj) (x_5 : @& tobj) (x_6 : @& tobj) (x_7 : @& tobj) (x_8 : @& tobj) (x_9 : @& tobj) : tobj :=
def Exp.casesOn._override (x_1 : ◾) (x_2 : tobj) (x_3 : tobj) (x_4 : tobj) (x_5 : @& tobj) (x_6 : @& tobj) (x_7 : @& tobj) (x_8 : @& tobj) (x_9 : @& tobj) : tobj :=
case x_2 : tobj of
Exp.var._impl →
dec x_4;
@ -85,7 +85,7 @@
dec x_3;
inc x_9;
ret x_9
def Exp.casesOn._override._redArg._boxed (x_1 : tobj) (x_2 : obj) (x_3 : obj) (x_4 : tobj) (x_5 : tobj) (x_6 : tobj) (x_7 : tobj) (x_8 : tobj) : tobj :=
def Exp.casesOn._override._redArg._boxed (x_1 : tobj) (x_2 : tobj) (x_3 : tobj) (x_4 : tobj) (x_5 : tobj) (x_6 : tobj) (x_7 : tobj) (x_8 : tobj) : tobj :=
let x_9 : tobj := Exp.casesOn._override._redArg x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8;
dec x_8;
dec x_7;
@ -93,7 +93,7 @@
dec x_5;
dec x_4;
ret x_9
def Exp.casesOn._override._boxed (x_1 : tobj) (x_2 : tobj) (x_3 : obj) (x_4 : obj) (x_5 : tobj) (x_6 : tobj) (x_7 : tobj) (x_8 : tobj) (x_9 : tobj) : tobj :=
def Exp.casesOn._override._boxed (x_1 : tobj) (x_2 : tobj) (x_3 : tobj) (x_4 : tobj) (x_5 : tobj) (x_6 : tobj) (x_7 : tobj) (x_8 : tobj) (x_9 : tobj) : tobj :=
let x_10 : tobj := Exp.casesOn._override x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8 x_9;
dec x_9;
dec x_8;