diff --git a/src/Fable.Transforms/Beam/Replacements.fs b/src/Fable.Transforms/Beam/Replacements.fs index 8408d3b4d8..b2cbd10078 100644 --- a/src/Fable.Transforms/Beam/Replacements.fs +++ b/src/Fable.Transforms/Beam/Replacements.fs @@ -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" diff --git a/src/Fable.Transforms/Replacements.Util.fs b/src/Fable.Transforms/Replacements.Util.fs index 30009f5914..98df0aef12 100644 --- a/src/Fable.Transforms/Replacements.Util.fs +++ b/src/Fable.Transforms/Replacements.Util.fs @@ -1298,7 +1298,8 @@ let (|RegexFlags|_|) e = [] 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 diff --git a/src/fable-metadata/lib/Fable.Core.dll b/src/fable-metadata/lib/Fable.Core.dll index cabadd25bf..ad480fca01 100644 Binary files a/src/fable-metadata/lib/Fable.Core.dll and b/src/fable-metadata/lib/Fable.Core.dll differ diff --git a/tests/Beam/InteropTests.fs b/tests/Beam/InteropTests.fs index 1c0d4282bf..749714d495 100644 --- a/tests/Beam/InteropTests.fs +++ b/tests/Beam/InteropTests.fs @@ -456,6 +456,23 @@ let ``test !^ implicit cast for erased unions works`` () = () #endif +[] +let ``test implicit conversion to erased unions works`` () = +#if FABLE_COMPILER + let strify (x: U3) = + 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 = "foo" + s |> equal (U2.Case2 "foo") + strify 42 |> equal "i: 42" + strify "foo" |> equal "s: foo" + strify true |> equal "b: yes" +#else + () +#endif + [] let ``test StringEnum works`` () = #if FABLE_COMPILER diff --git a/tests/Js/Main/UnionTypeTests.fs b/tests/Js/Main/UnionTypeTests.fs index 3c6a311449..002d57dcda 100644 --- a/tests/Js/Main/UnionTypeTests.fs +++ b/tests/Js/Main/UnionTypeTests.fs @@ -282,6 +282,18 @@ let tests = let x : U9> = !^42 x |> equal (U9.Case4 42) + + testCase "Implicit conversion to erased unions works" <| fun () -> + let strify (x: U3) = + 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 = "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 () -> diff --git a/tests/Python/TestUnionType.fs b/tests/Python/TestUnionType.fs index a9775b681c..385e098bf2 100644 --- a/tests/Python/TestUnionType.fs +++ b/tests/Python/TestUnionType.fs @@ -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" + +[] +let ``test Implicit conversion to erased unions works`` () = + let strify (x: U3) = + 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 = "foo" + s |> equal (U2.Case2 "foo") + strify 42 |> equal "i: 42" + strify "foo" |> equal "s: foo" + strify true |> equal "b: yes" #endif [] diff --git a/tests/Rust/tests/src/UnionTests.fs b/tests/Rust/tests/src/UnionTests.fs index f9cb755fde..7d1e4cd87a 100644 --- a/tests/Rust/tests/src/UnionTests.fs +++ b/tests/Rust/tests/src/UnionTests.fs @@ -476,4 +476,11 @@ let ``Compiler does not complain if the same type appears twice in nested U9`` ( U9> = !^42 x |> equal (U9.Case4 42) +[] +let ``Implicit conversion to erased unions works`` () = + let s: U2 = "foo" + s |> equal (U2.Case2 "foo") + let b: U3 = true + b |> equal (U3.Case3 true) + #endif