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
1 change: 1 addition & 0 deletions src/Fable.Transforms/Beam/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5779,6 +5779,7 @@ let tryCall
match info.DeclaringEntityFullName with
// Implicit cast for erased unions (U2, U3...) via `!^`; the cast is erased.
| _ when info.CompiledName = "op_ErasedCast" -> List.tryHead args
| Naming.StartsWith "Fable.Core.U" _ when info.CompiledName = "op_Implicit" -> List.tryHead args
| "Microsoft.FSharp.Core.Operators"
| "Microsoft.FSharp.Core.Operators.Checked"
| "Microsoft.FSharp.Core.ExtraTopLevelOperators"
Expand Down
3 changes: 2 additions & 1 deletion src/Fable.Transforms/Replacements.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,8 @@ let (|RegexFlags|_|) e =
[<return: Struct>]
let (|UniversalFableCoreHelpers|_|) (com: ICompiler) (ctx: Context) r t (i: CallInfo) args error =
function
| "op_ErasedCast" ->
| "op_ErasedCast"
| "op_Implicit" ->
match List.tryHead args with
| Some x -> ValueSome x
| None -> ValueNone
Expand Down
Binary file modified src/fable-metadata/lib/Fable.Core.dll
Binary file not shown.
17 changes: 17 additions & 0 deletions tests/Beam/InteropTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,23 @@ let ``test !^ implicit cast for erased unions works`` () =
()
#endif

[<Fact>]
let ``test implicit conversion to erased unions works`` () =
#if FABLE_COMPILER
let strify (x: U3<int, string, bool>) =
match x with
| U3.Case1 i -> "i: " + string i
| U3.Case2 s -> "s: " + s
| U3.Case3 b -> if b then "b: yes" else "b: no"
let s: U2<int, string> = "foo"
s |> equal (U2.Case2 "foo")
strify 42 |> equal "i: 42"
strify "foo" |> equal "s: foo"
strify true |> equal "b: yes"
#else
()
#endif

[<Fact>]
let ``test StringEnum works`` () =
#if FABLE_COMPILER
Expand Down
12 changes: 12 additions & 0 deletions tests/Js/Main/UnionTypeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,18 @@ let tests =
let x : U9<T1,T2,T3,int,T5,T6,T7,T8,
U9<T1 more, T2 more, T3 more, int, T5 more, T6 more, T7 more, T8 more, T9 more>> = !^42
x |> equal (U9.Case4 42)

testCase "Implicit conversion to erased unions works" <| fun () ->
let strify (x: U3<int, string, bool>) =
match x with
| U3.Case1 i -> "i: " + string i
| U3.Case2 s -> "s: " + s
| U3.Case3 b -> if b then "b: yes" else "b: no"
let s: U2<int, string> = "foo"
s |> equal (U2.Case2 "foo")
strify 42 |> equal "i: 42"
strify "foo" |> equal "s: foo"
strify true |> equal "b: yes"
#endif

testCase "Verify that union cases can have `-` in their names" <| fun () ->
Expand Down
13 changes: 13 additions & 0 deletions tests/Python/TestUnionType.fs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,19 @@ let ``test Erased union type testing works`` () =
U3.Case1 "HELLO" |> toString |> equal "HELLO"
U3.Case2 3 |> toString |> equal "6"
"HELLO" |> Wrapper |> U3.Case3 |> toString |> equal "OLLEH"

[<Fact>]
let ``test Implicit conversion to erased unions works`` () =
let strify (x: U3<int, string, bool>) =
match x with
| U3.Case1 i -> "i: " + string i
| U3.Case2 s -> "s: " + s
| U3.Case3 b -> if b then "b: yes" else "b: no"
let s: U2<int, string> = "foo"
s |> equal (U2.Case2 "foo")
strify 42 |> equal "i: 42"
strify "foo" |> equal "s: foo"
strify true |> equal "b: yes"
#endif

[<Fact>]
Expand Down
7 changes: 7 additions & 0 deletions tests/Rust/tests/src/UnionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -476,4 +476,11 @@ let ``Compiler does not complain if the same type appears twice in nested U9`` (
U9<T1 more, T2 more, T3 more, int, T5 more, T6 more, T7 more, T8 more, T9 more>> = !^42
x |> equal (U9.Case4 42)

[<Fact>]
let ``Implicit conversion to erased unions works`` () =
let s: U2<int, string> = "foo"
s |> equal (U2.Case2 "foo")
let b: U3<int, string, bool> = true
b |> equal (U3.Case3 true)

#endif
Loading