-
Notifications
You must be signed in to change notification settings - Fork 803
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
Oddities in statically resolved method constraints and method overloading #3814
Comments
@greatim Thanks for the clean report, I will be looking into this closely |
In case 2 there's certainly the bug that our type constrains either get lost or are ignored. |
@dsyme
Now we get super fancy weird compiler errors:
This isn't an oddity @dsyme this is a clear bug. |
I do have a fix for this consisting mainly of your code with removing 4 lines. It also would fix Case 1. To my understanding the problem lies in that the compiler either
Please note that this behaviour is reproducable with my branch of your fix https://github.com/Microsoft/visualfsharp/pull/5141/files |
This is unrelated to this bug.I was investigating case 1 further and realized that this oddity is realted to overload resolution within inheritance. This example should print the same as case one but uses different code for reproduction: type FooBase() =
member __.Foo(_: obj) = false
type Test() =
inherit FooBase()
member __.Foo(_: Test) = true
let inline Foo(a: FooBase) (b: ^t) =
match a with
| :? ^t as x ->
(^t: (member Foo: ^t -> bool) (b, x))
| x ->
printfn "Not what we want"
false
let a: Test = Test()
let b:Test = Test()
//b <- null
printfn "%A" (Foo a b) Expecting that this code prints "true" because Foo with Test as type argument would be expected here. @dsyme Is this information helpful for finding the root cause? |
@realvictorprm Yes, helpful, thanks. The question isn't the root cause but whether we can change existing behaviour without busting existing code, and if not then what to do about it. |
From discussion with @realvictorprm Both of these bugs are really hard to fix without breaking existing code.
One possible way to make progress is as follows:
|
Notes for @realvictorprm to add tests that would grab and build a known commit of FSharpPlus as part of the test process In module Commands =
let dotnet workDir exec (dotNetExe: FilePath) flags srcFiles =
let args = (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " "))
ignore workDir
exec dotNetExe args
let dotnet cfg arg = Printf.ksprintf (Commands.dotnet cfg.Directory (exec cfg) cfg.DotNetExe) arg
And in [<Test>]
let testFSharpPlusBuild () =
let cfg = testConfig "repos"
git cfg "clone http://github.com/fsprojects/FSharpPlus f309032020892r30 repodir"
let cfg2 = testConfig "repos/repodir"
dotnet cfg2 "build" [ "FSharpPlus.sln" ]
|
Hi @dsyme I'll work today and tomorrow many hours on this. From my recent work I need to report, that right now there isn't a correct
Phillip Carter:
Relying on this comment I'll work on creating a build script picking the source files of FSharpPlus and invoke the compiler directly on it instead of using the sln file to build the project. |
OK another case of trying to delay overload resolution. The case 2 can be "workedaround" through using this code: type X =
static member Method (a: int) = 2
static member Method (a: int64) = 3
let inline Test< ^t, ^a when (^t or ^a): (static member Method: ^a -> int)> (value: ^a) =
( (^t or ^a): (static member Method: ^a -> int)(value))
let inline Test2< ^t when (X or ^t) : (static member Method : ^t -> int)> a = Test<X, ^t> a
printfn "%d" (Test2<int> 0) |
Still not workable... |
Nothing has been done in this area to my knowledge |
Case 1
I expected to call Test.Equals: Test->unit, (Equals a b) return true
but actually it call Object.Equals: obj->unit, return false
Case 2:
I expected return 2, but actually it return 1
The text was updated successfully, but these errors were encountered: