fix: boxing may have to correct let binder types (#11426)

This PR closes #11356.
This commit is contained in:
Henrik Böving 2025-12-01 18:22:32 +01:00 committed by GitHub
parent 2da5b528b7
commit 310abce62b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 0 deletions

View file

@ -267,8 +267,29 @@ def visitVDeclExpr (x : VarId) (ty : IRType) (e : Expr) (b : FnBody) : M FnBody
| _ =>
return .vdecl x ty e b
/--
Up to this point the type system of IR is quite loose so we can for example encounter situations
such as
```
let y : obj := f x
```
where `f : obj -> uint8`. It is the job of the boxing pass to enforce a stricter obj/scalar
separation and as such it needs to correct situations like this.
-/
def tryCorrectVDeclType (ty : IRType) (e : Expr) : M IRType :=
match e with
| .fap f _ => do
let decl ← getDecl f
return decl.resultType
| .pap .. => return .object
| .uproj .. => return .usize
| .ctor .. | .reuse .. | .ap .. | .lit .. | .sproj .. | .proj .. | .reset .. =>
return ty
| .unbox .. | .box .. | .isShared .. => unreachable!
partial def visitFnBody : FnBody → M FnBody
| .vdecl x t v b => do
let t ← tryCorrectVDeclType t v
let b ← withVDecl x t v (visitFnBody b)
visitVDeclExpr x t v b
| .jdecl j xs v b => do

View file

@ -0,0 +1,28 @@
def myCast : NatCast UInt8 where
natCast := UInt8.ofNat
class Semiring (α : Type u) where
[nsmul : SMul Nat α]
/--
trace: [Compiler.IR] [result]
def instSemiringUInt8._lam_0 (x_1 : @& tobj) (x_2 : u8) : u8 :=
let x_3 : u8 := UInt8.ofNat x_1;
let x_4 : u8 := UInt8.mul x_3 x_2;
ret x_4
def instSemiringUInt8 : obj :=
let x_1 : obj := pap instSemiringUInt8._lam_0._boxed;
ret x_1
def instSemiringUInt8._lam_0._boxed (x_1 : tobj) (x_2 : tagged) : tagged :=
let x_3 : u8 := unbox x_2;
let x_4 : u8 := instSemiringUInt8._lam_0 x_1 x_3;
dec x_1;
let x_5 : tagged := box x_4;
ret x_5
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
attribute [local instance] myCast UInt8.intCast in
instance : Semiring UInt8 where
nsmul := ⟨(· * ·)⟩