Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Fable.Transforms/FSharp2Fable.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,13 @@ module Helpers =
|| ctx.UsedNamesInDeclarationScope.Contains name

let getIdentUniqueName (com: Compiler) (ctx: Context) name =
// Reserve the emitted Python name so tuple-match temporaries cannot shadow
// existing bindings when camelCase is converted to snake_case.
let name =
match com.Options.Language with
| Python -> Fable.Py.Naming.toPythonNaming name
| _ -> name

let sanitizeIdent =
match com.Options.Language with
| Python -> Fable.Py.Naming.sanitizeIdent
Expand Down
50 changes: 50 additions & 0 deletions tests/Python/TestPatternMatch.fs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,56 @@ let ``test nested match complex`` () =
nestedComplex 2 2 |> equal "x=2, y=other"
nestedComplex 3 1 |> equal "x=other"

// https://github.com/fable-compiler/Fable/issues/5026
module NestedMatchNames =
type Shape =
| Circle of radius: int
| Square

let describe (shapes: Shape list) n =
match List.head shapes with
| Circle radius ->
match n + 1, radius with
| 2, 1 -> "unit circle"
| _ -> "other"
| Square -> "square"

let describeInClosure (shapes: Shape list) =
match List.head shapes with
| Circle radius ->
fun xs ->
match List.tryHead xs, radius with
| Some 2, 1 -> "unit circle"
| _ -> "other"
| Square -> fun _ -> "square"

let describeWithUserBinding (match_value: string) n =
match n + 1, n + 2 with
| 2, 3 -> match_value
| _ -> "other"

[<Fact>]
let ``test nested tuple match preserves outer union fields`` () =
NestedMatchNames.describe [ NestedMatchNames.Circle 1 ] 1 |> equal "unit circle"
NestedMatchNames.describe [ NestedMatchNames.Circle 2 ] 1 |> equal "other"
NestedMatchNames.describe [ NestedMatchNames.Circle 1 ] 2 |> equal "other"
NestedMatchNames.describe [ NestedMatchNames.Square ] 1 |> equal "square"

[<Fact>]
let ``test tuple match in closure preserves captured union fields`` () =
let describe = NestedMatchNames.describeInClosure [ NestedMatchNames.Circle 1 ]
describe [ 2 ] |> equal "unit circle"
describe [ 3 ] |> equal "other"
describe [] |> equal "other"
describe [ 2 ] |> equal "unit circle"
NestedMatchNames.describeInClosure [ NestedMatchNames.Circle 2 ] [ 2 ] |> equal "other"
NestedMatchNames.describeInClosure [ NestedMatchNames.Square ] [ 2 ] |> equal "square"

[<Fact>]
let ``test tuple match temporaries preserve user bindings`` () =
NestedMatchNames.describeWithUserBinding "matched" 1 |> equal "matched"
NestedMatchNames.describeWithUserBinding "matched" 2 |> equal "other"

// ----------------------------------------------------------------------------
// 7. Option Matching
// ----------------------------------------------------------------------------
Expand Down
Loading