Open gusty opened 3 years ago
And here's a repro to send to FSI in one shot
type A = A with
static member ($) (A, a: float ) = 0.0
static member ($) (A, a: decimal) = 0M
static member ($) (A, a: 't ) = 0
let inline call x = ($) A x
call 42. + 1.1
Which results in
type A =
| A
with
static member ( $ ) : A:A * a:'t -> int + 2 overloads
end
val inline call :
x: ^a -> ^_arg3
when (A or ^a) : (static member ( $ ) : A * ^a -> ^_arg3)
val it : float = nan
when the expeced result should be 1.1
@gusty I have tried today with on a script and on fsi and seems to be fixed now :) FYI @vzarytovskii
Yes, it works for me as well. I wonder what was the fixing PR.
Yes, it works for me as well. I wonder what was the fixing PR.
It is likely that the work on the static abstract interface methods
Hmm, I don't think so. I'm still on F# 6 and it seems fixed.
Hmm, I don't think so. I'm still on F# 6 and it seems fixed.
Only feature itself is tied to language version, some changes and fixes are not.
Thought if you're on 6.x.x, then it's not it yes
Might be worth adding a regression test 😀
I just tried it again in both F#6 and F#7 my second repro works well.
But the original repro (the one in the issue step by step) still fails in both, surprisingly in different ways:
> type A = A with
- static member ($) (A, a: float ) = 0.0
- static member ($) (A, a: decimal) = 0M
- static member ($) (A, a: 't ) = 0
-
- let inline call x = ($) A x
- ;;
type A =
| A
static member ($) : A: A * a: 't -> int + 2 overloads
val inline call:
x: ^a -> ^_arg3 when (A or ^a) : (static member ($) : A * ^a -> ^_arg3)
call 42. ;; val it: obj =
> type A = A with
static member ($) (A, a: float ) = 0.0
static member ($) (A, a: decimal) = 0M
static member ($) (A, a: 't ) = 0
let inline call x = ($) A x;;
type A =
| A
static member ($) : A: A * a: 't -> int + 2 overloads
val inline call:
x: ^a -> '_arg3 when (A or ^a) : (static member ($) : A * ^a -> '_arg3)
> call 42. ;;
call 42. ;;
^^^^^^^^
stdin(7,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it: '_a
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
@edgarfgp I think you tried sending all the code to fsi at once. Try it in steps as described in the issue.
@gusty You are right I can reproduce it by sending line by line . But works when sending all at once, seems to be a FSI bug/limitation
Note: I have tried with dotnet fsi --multiemit
and does NOT make a difference
@edgarfgp note that this difference between sending all at once is not that uncommon: type inference uses "last minute" information to specialize generic functions. When you create the function and immediately after you use it, the "use" is taken into account. If you send both fragments separately type inference is independent.
Confirmed to be reproducing in F# 8 Microsoft (R) F# Interactive version 12.8.0.0 for F# 8.0
with the value restriction variant described above https://github.com/dotnet/fsharp/issues/12386#issuecomment-1251868590
There are some cases where an invalid value is returned from a trait call.
Repro steps
try in fsi
send it
Now try this
call 42.
Expected behavior
val it : float = 0.0
Actual behavior
val it : obj = <null>
Known workarounds
I haven't found one so far.
I didn't try in older versions, but I'm under the impression that this is a regression.