feat: consistent type ABI regardless of transparency (#10610)

This PR ensures that even if a type is marked as `irreducible` the
compiler can see through it in
order to discover functions hidden behind type aliases.
This commit is contained in:
Henrik Böving 2025-09-29 15:31:41 +02:00 committed by GitHub
parent 6f3fef9373
commit b82303e9b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 1 deletions

View file

@ -166,8 +166,12 @@ where
| .proj ``Subtype 0 (.const ``IO.RealWorld.nonemptyType []) =>
return mkConst ``lcRealWorld
| _ => return mkConst ``lcAny
whnfEta (type : Expr) : MetaM Expr := do
let type ← whnf type
-- We increase transparency here to unfold type aliases of functions that are declared as
-- `irreducible`, such that they end up being represented as C functions.
let type ← withTransparency .all do
whnf type
let type' := type.eta
if type' != type then
whnfEta type'

View file

@ -1,5 +1,7 @@
#include "util/options.h"
// please update stage0 good sir
namespace lean {
options get_default_options() {
options opts;

View file

@ -0,0 +1,61 @@
/-!
This test ensures that the code generator sees the same type representation regardless of
transparency setting in the elaborator. If this test ever breaks you should ensure that the IR
between A and B is in sync.
-/
namespace A
@[irreducible] def Function (α β : Type) := α → β
namespace Function
attribute [local semireducible] Function
@[inline]
def id : Function α α := fun x => x
end Function
/--
trace: [Compiler.IR] [result]
def A.foo (x_1 : @& tobj) : tobj :=
inc x_1;
ret x_1
def A.foo._boxed (x_1 : tobj) : tobj :=
let x_2 : tobj := A.foo x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def foo : Function Nat Nat := Function.id
end A
namespace B
def Function (α β : Type) := α → β
namespace Function
@[inline]
def id : Function α α := fun x => x
end Function
/--
trace: [Compiler.IR] [result]
def B.foo (x_1 : @& tobj) : tobj :=
inc x_1;
ret x_1
def B.foo._boxed (x_1 : tobj) : tobj :=
let x_2 : tobj := B.foo x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def foo : Function Nat Nat := Function.id
end B