From 9d31b4d24f2d1783012b465ed01bb433daed015f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 13 Mar 2026 09:01:33 -0700 Subject: [PATCH] unsub-cont --- src/passes/Unsubtyping.cpp | 6 ++- .../passes/unsubtyping-stack-switching.wast | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/passes/Unsubtyping.cpp b/src/passes/Unsubtyping.cpp index ccb9ecda6db..2e341f165cf 100644 --- a/src/passes/Unsubtyping.cpp +++ b/src/passes/Unsubtyping.cpp @@ -949,8 +949,10 @@ struct Unsubtyping : Pass, Noter { noteSubtype(elem.type, super.getArray().element.type); break; } - case HeapTypeKind::Cont: - WASM_UNREACHABLE("TODO: cont"); + case HeapTypeKind::Cont: { + noteSubtype(sub.getContinuation().type, super.getContinuation().type); + break; + } case HeapTypeKind::Basic: WASM_UNREACHABLE("unexpected kind"); } diff --git a/test/lit/passes/unsubtyping-stack-switching.wast b/test/lit/passes/unsubtyping-stack-switching.wast index de8a4179fb4..fd11ecfe92a 100644 --- a/test/lit/passes/unsubtyping-stack-switching.wast +++ b/test/lit/passes/unsubtyping-stack-switching.wast @@ -591,3 +591,50 @@ ) ) +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $super (sub (func))) + (type $super (sub (func))) + ;; CHECK: (type $sub (sub $super (func))) + (type $sub (sub $super (func))) + ;; CHECK: (type $cont-super (sub (cont $super))) + (type $cont-super (sub (cont $super))) + ;; CHECK: (type $cont-sub (sub $cont-super (cont $sub))) + (type $cont-sub (sub $cont-super (cont $sub))) + + ;; CHECK: (type $4 (func (param (ref $cont-sub)) (result (ref $cont-super)))) + + ;; CHECK: (func $cont-new (type $4) (param $sub (ref $cont-sub)) (result (ref $cont-super)) + ;; CHECK-NEXT: (local.get $sub) + ;; CHECK-NEXT: ) + (func $cont-new (param $sub (ref $cont-sub)) (result (ref $cont-super)) + ;; This requires $cont-sub <: $cont-super and $sub <: $super. + (local.get $sub) + ) +) + +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $super (sub (func))) + (type $super (sub (func))) + ;; CHECK: (type $sub (sub (func))) + (type $sub (sub $super (func))) + ;; CHECK: (type $cont-super (sub (cont $super))) + (type $cont-super (sub (cont $super))) + ;; CHECK: (type $cont-sub (sub (cont $sub))) + (type $cont-sub (sub $cont-super (cont $sub))) + + ;; CHECK: (type $4 (func (param (ref $cont-sub)) (result (ref $cont-sub)))) + + ;; CHECK: (func $cont-new (type $4) (param $sub (ref $cont-sub)) (result (ref $cont-sub)) + ;; CHECK-NEXT: (local $keepalive (ref $cont-super)) + ;; CHECK-NEXT: (local.get $sub) + ;; CHECK-NEXT: ) + (func $cont-new (param $sub (ref $cont-sub)) (result (ref $cont-sub)) + (local $keepalive (ref $cont-super)) + ;; As above, but now we return the subtype, so there is no constraint. We + ;; can unsubtype both the continuations and the funcs. + (local.get $sub) + ) +) +