Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return type overloading not supported by op_Implicit. #2564

Open
nimzi opened this issue Oct 10, 2021 · 7 comments · May be fixed by #2583
Open

Return type overloading not supported by op_Implicit. #2564

nimzi opened this issue Oct 10, 2021 · 7 comments · May be fixed by #2583

Comments

@nimzi
Copy link

nimzi commented Oct 10, 2021

Description

Multiple versions of op_Implicit are not supported.

Repro code

type MyType = { Field : int}
        with
        static member op_Implicit(s:string):int = failwith "Unimplemented"
        static member op_Implicit(s:string):float = failwith "Unimplemented"

Expected and actual results

Native dotnet comiles while fable gives an error:
FABLE: Cannot have two module members with same name:

Related information

  • Fable version: 3.4.2
  • Operating system: MacOS
@alfonsogarciacaro
Copy link
Member

Ah, true. Currently the name mangling mechanism in Fable ignores the return type because it's usually not possible to have two overloads differ only because of the return type, but I forgot about the implicit operator (is there any other case?). Probably we should handle this case differently.

@alfonsogarciacaro
Copy link
Member

Actually I don't even know how the implicit operator is used. @nimzi Do you have an example of a use case that we can turn into a test?

@nimzi
Copy link
Author

nimzi commented Oct 14, 2021

@alfonsogarciacaro The example above the minimal unit test. op_Implicit and op_Explicit are there to support conversions (implicit and explicit). This is a somewhat obscure corner of F# and docs from Microsoft (https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/casting-and-conversions) could be better. However, I suspect that as a compiler implementer may not need to deeply understand all the aspects. op_Implicit and its friend are different from the other methods in that the return type is involved in method resolution. Normally you cannot have two static methods with the same name and argument types returning different results in F#. Some languages use return type for signature, but not F#. However, the above methods are special. I believe if you were to fix just that aspect of the compiler the rest of features would just fall in place. I presume that there's method name mangling stage somewhere during generation, so just mapping the multiple instance of the static method to different mangled names in JS might just do the trick.

@nimzi
Copy link
Author

nimzi commented Oct 14, 2021

Also @alfonsogarciacaro, the following article gives a bit more context on the issue (https://robkuz.github.io/Explicit-vs-Implicit/).

@alfonsogarciacaro
Copy link
Member

Thanks for the explanations @nimzi. Although the above code can be included in the tests to make sure it's compilable it would still be preferable to have an assertion. The article is interesting but I'm not sure the F# limitations allow such a pattern to be generally usable. BTW, Fable already includes a similar mechanism to represent erased unions, although it's mainly intended to interop with JS: https://fable.io/docs/communicate/js-from-fable.html#Erase-attribute

Also, with the new open type statement you can write static classes as if they were modules, which makes overloads available.

@alfonsogarciacaro
Copy link
Member

The fix is breaking the tests for some reason so I moved it to another branch until I can investigate.

@jamil7
Copy link

jamil7 commented Jul 27, 2022

Any updates on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants