From d37ab5407094810d86ee79d738e6846a8885251c Mon Sep 17 00:00:00 2001 From: ncave <777696+ncave@users.noreply.github.com> Date: Mon, 30 Mar 2026 11:13:15 -0700 Subject: [PATCH] [TS/Python] Fix thisArg type for overloads --- src/Fable.Cli/CHANGELOG.md | 1 + src/Fable.Compiler/CHANGELOG.md | 1 + src/Fable.Transforms/Fable2Babel.fs | 7 ++++++- src/Fable.Transforms/Python/Fable2Python.Transforms.fs | 6 ++++++ tests/Beam/TypeTests.fs | 1 + tests/Dart/src/TypeTests.fs | 1 + tests/Js/Main/TypeTests.fs | 1 + tests/Python/TestType.fs | 1 + tests/Rust/tests/src/TypeTests.fs | 1 + 9 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 730272f4fb..bfdd64ed59 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [Python] Add `Math.DivRem` support for int, int64, and bigint (by @dbrattli) * [Python] Fix modulo with negative numbers using Python floored semantics instead of .NET truncated semantics for bigint (fixes #4462) (by @dbrattli) * [Beam] Fix `System.String.Concat` with 4+ arguments not being supported (by @dbrattli) +* [TS/Python] Fix thisArg type for overloads in structs (#4453) (by @ncave) * [TS/Python] Fix invalid `this` argument type in structs (#4453) (by @ncave) * [JS/TS] Fix `N` format specifier (`ToString("N0")`, `String.Format("{0:N0}", ...)`) producing a trailing dot when precision is 0 (fix #2582) (by @MangelMaxime) * [JS/TS] Fix `C0` and `P0` format specifiers producing trailing dot (e.g., `"¤1,000."` → `"¤1,000"`) (by @MangelMaxime) diff --git a/src/Fable.Compiler/CHANGELOG.md b/src/Fable.Compiler/CHANGELOG.md index 8998a6d54c..3f87467b3b 100644 --- a/src/Fable.Compiler/CHANGELOG.md +++ b/src/Fable.Compiler/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [Python] Add `Math.DivRem` support for int, int64, and bigint (by @dbrattli) * [Python] Fix modulo with negative numbers using Python floored semantics instead of .NET truncated semantics for bigint (fixes #4462) (by @dbrattli) * [Beam] Fix `System.String.Concat` with 4+ arguments not being supported (by @dbrattli) +* [TS/Python] Fix thisArg type for overloads in structs (#4453) (by @ncave) * [TS/Python] Fix invalid `this` argument type in structs (#4453) (by @ncave) * [JS/TS] Fix `N` format specifier (`ToString("N0")`, `String.Format("{0:N0}", ...)`) producing a trailing dot when precision is 0 (fix #2582) (by @MangelMaxime) * [JS/TS] Fix `C0` and `P0` format specifiers producing trailing dot (e.g., `"¤1,000."` → `"¤1,000"`) (by @MangelMaxime) diff --git a/src/Fable.Transforms/Fable2Babel.fs b/src/Fable.Transforms/Fable2Babel.fs index a0993e10c5..599777b288 100644 --- a/src/Fable.Transforms/Fable2Babel.fs +++ b/src/Fable.Transforms/Fable2Babel.fs @@ -1346,6 +1346,12 @@ module Util = let body = // TODO: If ident is not captured maybe we can just replace it with "this" if isIdentUsed thisArg.Name body then + let thisArgType = + match thisArg.Type with + | Replacements.Util.IsByRefType com typ -> typ + | typ -> typ + + let thisArg = { thisArg with Type = thisArgType } let thisIdent = Fable.IdentExpr { thisArg with Name = "this" } let thisIdent = @@ -3331,7 +3337,6 @@ but thanks to the optimisation done below we get List.zip args tc.Args |> List.map (fun (id, tcArg) -> let ta = makeArgTypeAnnotation com ctx id - Parameter.parameter (tcArg, ?typeAnnotation = ta) ) diff --git a/src/Fable.Transforms/Python/Fable2Python.Transforms.fs b/src/Fable.Transforms/Python/Fable2Python.Transforms.fs index f430fe0e22..cb2380fbde 100644 --- a/src/Fable.Transforms/Python/Fable2Python.Transforms.fs +++ b/src/Fable.Transforms/Python/Fable2Python.Transforms.fs @@ -83,6 +83,12 @@ let getMemberArgsAndBody (com: IPythonCompiler) ctx kind hasSpread (args: Fable. let body = if isIdentUsed thisArg.Name body then + let thisArgType = + match thisArg.Type with + | Replacements.Util.IsByRefType com typ -> typ + | typ -> typ + + let thisArg = { thisArg with Type = thisArgType } let thisKeyword = Fable.IdentExpr { thisArg with Name = "self" } Fable.Let(thisArg, thisKeyword, body) diff --git a/tests/Beam/TypeTests.fs b/tests/Beam/TypeTests.fs index 461f2e2b19..51a3d08ffb 100644 --- a/tests/Beam/TypeTests.fs +++ b/tests/Beam/TypeTests.fs @@ -48,6 +48,7 @@ type ValueTypeR = val mutable X: float new(x: float) = { X = x } member this.IsEmpty() = this.X < 0.0 + override this.ToString() = $"{this.X}" [] type StructUnion = Value of string diff --git a/tests/Dart/src/TypeTests.fs b/tests/Dart/src/TypeTests.fs index 274fd7de8b..42b9eb81d9 100644 --- a/tests/Dart/src/TypeTests.fs +++ b/tests/Dart/src/TypeTests.fs @@ -269,6 +269,7 @@ open Util // val mutable X: float // new(x: float) = { X = x } // member this.IsEmpty() = this.X < 0.0 +// override this.ToString() = $"{this.X}" // [] // type StructUnion = Value of string diff --git a/tests/Js/Main/TypeTests.fs b/tests/Js/Main/TypeTests.fs index 148b75b1ae..c97a5e73f4 100644 --- a/tests/Js/Main/TypeTests.fs +++ b/tests/Js/Main/TypeTests.fs @@ -272,6 +272,7 @@ type ValueTypeR = val mutable X: float new(x: float) = { X = x } member this.IsEmpty() = this.X < 0.0 + override this.ToString() = $"{this.X}" [] type StructUnion = Value of string diff --git a/tests/Python/TestType.fs b/tests/Python/TestType.fs index 990d2f9e44..3d4e759647 100644 --- a/tests/Python/TestType.fs +++ b/tests/Python/TestType.fs @@ -303,6 +303,7 @@ type ValueTypeR = val mutable X: float new(x: float) = { X = x } member this.IsEmpty() = this.X < 0.0 + override this.ToString() = $"{this.X}" [] type StructUnion = Value of string diff --git a/tests/Rust/tests/src/TypeTests.fs b/tests/Rust/tests/src/TypeTests.fs index 802952dd3f..f3366cbb38 100644 --- a/tests/Rust/tests/src/TypeTests.fs +++ b/tests/Rust/tests/src/TypeTests.fs @@ -269,6 +269,7 @@ type ValueTypeR = val mutable X: float new(x: float) = { X = x } member this.IsEmpty() = this.X < 0.0 + override this.ToString() = $"{this.X}" [] type StructUnion = Value of string