From 782654bc6b26b20d971a46c7800adb8bd1314392 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Fri, 24 Apr 2026 10:16:50 +0200 Subject: [PATCH] fix(extgen): make Go type compatibility check symmetric and drop float32 coercion --- internal/extgen/validator.go | 16 +++++++--------- internal/extgen/validator_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/internal/extgen/validator.go b/internal/extgen/validator.go index 7605d7c8ad..f9b59763de 100644 --- a/internal/extgen/validator.go +++ b/internal/extgen/validator.go @@ -223,21 +223,19 @@ func (v *Validator) phpTypeToGoType(t phpType, isNullable bool) string { } // isCompatibleGoType checks if the actual Go type is compatible with the expected type. +// PHP int maps to Go int64: we also accept plain int for ergonomics on 64-bit platforms +// (where they share the same layout). The relation is symmetric so the direction in which +// the check is written does not matter. func (v *Validator) isCompatibleGoType(expectedType, actualType string) bool { if expectedType == actualType { return true } - switch expectedType { - case "int64": - return actualType == "int" - case "*int64": - return actualType == "*int" - case "*float64": - return actualType == "*float32" - } + return isIntAlias(expectedType, actualType) || isIntAlias(actualType, expectedType) +} - return false +func isIntAlias(a, b string) bool { + return (a == "int64" && b == "int") || (a == "*int64" && b == "*int") } func (v *Validator) phpReturnTypeToGoType(phpReturnType phpType) string { diff --git a/internal/extgen/validator_test.go b/internal/extgen/validator_test.go index b95351519a..7be0f953e4 100644 --- a/internal/extgen/validator_test.go +++ b/internal/extgen/validator_test.go @@ -911,3 +911,29 @@ func TestPhpReturnTypeToGoType(t *testing.T) { }) } } + +func TestIsCompatibleGoType(t *testing.T) { + tests := []struct { + name string + expected string + actual string + compatible bool + }{ + {"exact match int64", "int64", "int64", true}, + {"int accepted for int64", "int64", "int", true}, + {"int64 accepted for int (symmetric)", "int", "int64", true}, + {"pointer int alias symmetric a->b", "*int64", "*int", true}, + {"pointer int alias symmetric b->a", "*int", "*int64", true}, + {"float32 not compatible with float64", "float64", "float32", false}, + {"pointer float32 not compatible with *float64", "*float64", "*float32", false}, + {"unrelated types", "int64", "string", false}, + {"bool vs int", "bool", "int64", false}, + } + + validator := Validator{} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.compatible, validator.isCompatibleGoType(tt.expected, tt.actual)) + }) + } +}