From 73dfe3b423ec13c67d5802debfb61070e955d6a6 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 19 Aug 2024 11:56:36 -0700 Subject: [PATCH] Print explicit typeuses for non-MVP function types We previously printed explicit typeuses (e.g. `(type $f)`) in function signatures when GC was enabled. But even when GC is not enabled, function types may use non-MVP features that require the explicit typeuse to be printed. Fix the printer to always print the explicit type use for such types. Fixes #6850. --- src/passes/Print.cpp | 13 +++++- test/lit/basic/print-explicit-typeuse.wast | 51 ++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 test/lit/basic/print-explicit-typeuse.wast diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 3abe1f73821..6350347c46d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2804,13 +2804,21 @@ bool PrintSExpression::maybePrintUnreachableOrNullReplacement(Expression* curr, return maybePrintUnreachableReplacement(curr, type); } +static bool requiresExplicitFuncType(HeapType type) { + // When the `(type $f)` in a function's typeuse is omitted, the typeuse + // matches or declares an MVP function type. When the intended type is not an + // MVP function type, we therefore need the explicit `(type $f)`. + return type.isOpen() || type.isShared() || type.getRecGroup().size() > 1; +} + void PrintSExpression::handleSignature(HeapType curr, Name name) { Signature sig = curr.getSignature(); o << "(func"; if (name.is()) { o << ' '; name.print(o); - if (currModule && currModule->features.hasGC()) { + if ((currModule && currModule->features.hasGC()) || + requiresExplicitFuncType(curr)) { o << " (type "; printHeapType(curr) << ')'; } @@ -2947,7 +2955,8 @@ void PrintSExpression::visitDefinedFunction(Function* curr) { o << '('; printMajor(o, "func "); curr->name.print(o); - if (currModule && currModule->features.hasGC()) { + if ((currModule && currModule->features.hasGC()) || + requiresExplicitFuncType(curr->type)) { o << " (type "; printHeapType(curr->type) << ')'; } diff --git a/test/lit/basic/print-explicit-typeuse.wast b/test/lit/basic/print-explicit-typeuse.wast new file mode 100644 index 00000000000..d299a3eb430 --- /dev/null +++ b/test/lit/basic/print-explicit-typeuse.wast @@ -0,0 +1,51 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt %s --no-validation -S -o - | filecheck %s + +;; Check that we print explicit type uses for function signatures when the +;; function type uses non-MVP features, whether or not those features are +;; actually enabled. + +(module + ;; CHECK: (type $mvp (func)) + (type $mvp (func)) + ;; CHECK: (type $open (sub (func))) + (type $open (sub (func))) + ;; CHECK: (type $shared (shared (func))) + (type $shared (shared (func))) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $rec (func)) + (type $rec (func)) + ;; CHECK: (type $other (struct)) + (type $other (struct)) + ) + + ;; CHECK: (import "" "" (func $mvp-import)) + (import "" "" (func $mvp-import)) + + ;; CHECK: (import "" "" (func $open-import (type $open))) + (import "" "" (func $open-import (type $open))) + + ;; CHECK: (import "" "" (func $shared-import (type $shared))) + (import "" "" (func $shared-import (type $shared))) + + ;; CHECK: (import "" "" (func $rec-import (type $rec))) + (import "" "" (func $rec-import (type $rec))) + + ;; CHECK: (func $mvp + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $mvp (type $mvp)) + ;; CHECK: (func $open (type $open) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $open (type $open)) + ;; CHECK: (func $shared (type $shared) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $shared (type $shared)) + ;; CHECK: (func $rec (type $rec) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $rec (type $rec)) +)