Weird value returned after (maybe failed) overload resolution
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 30/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- fsharp
- Domain
- compilers
Research direction
Start by running the supplied F# repro at Delay.Invoke and compare the output with the first Delay overload enabled and disabled. Investigate how the constrained overload involving struct and not struct is selected; done means the result is [5] or the program reports a compile error, rather than printing [object Object].
Written by the indexing model from the issue text.
Description
This bug is not about taking the wrong overload, which is an ongoing problem not easy to solve, but about returning a value not corresponding to any of the overloads.
I'm under the impression that overload resolution fails and then some buggy code returns a no sense value instead of a compile error.
Here's a repro
open System
type Default6 = class end
type Default5 = class inherit Default6 end
type Default4 = class inherit Default5 end
type Default3 = class inherit Default4 end
type Default2 = class inherit Default3 end
type Default1 = class inherit Default2 end
type [<Struct>]Result2<'T, 'E> = Ok2 of OkField:'T | Error2 of ErrorField:'E
type Bind =
static member (>>=) (source: Lazy<'T> , f: 'T -> Lazy<'U> ) = lazy (f source.Value).Value : Lazy<'U>
static member (>>=) (source: seq<'T> , f: 'T -> seq<'U> ) = Seq.collect f source : seq<'U>
static member (>>=) (source , f: 'T -> _ ) = Option.bind f source : option<'U>
static member (>>=) (source , f: 'T -> _ ) = List.collect f source : list<'U>
static member (>>=) (source , f: 'T -> _ ) = Array.collect f source : 'U []
static member (>>=) (source , f: 'T -> _ ) = async.Bind (source, f) : Async<'U>
static member (>>=) (source , k: 'T -> _ ) = Result.bind k source : Result<'U,'E>
static member (>>=) (source: Result2<'T,'E> , k: 'T -> Result2<'U,'E>) = Unchecked.defaultof<_> : Result2<'U,'E>
static member inline Invoke (source: '``Monad<'T>``) (binder: 'T -> '``Monad<'U>``) : '``Monad<'U>`` =
let inline call (_mthd: 'M, input: 'I, _output: 'R, f) = ((^M or ^I or ^R) : (static member (>>=) : _*_ -> _) input, f)
call (Unchecked.defaultof<Bind>, source, Unchecked.defaultof<'``Monad<'U>``>, binder)
type Return =
inherit Default1
static member inline InvokeOnInstance (x: 'T) = (^``Applicative<'T>`` : (static member Return : ^T -> ^``Applicative<'T>``) x)
static member inline Invoke (x: 'T) : '``Applicative<'T>`` =
let inline call (mthd: ^M, output: ^R) = ((^M or ^R) : (static member Return : _*_ -> _) output, mthd)
call (Unchecked.defaultof<Return>, Unchecked.defaultof<'``Applicative<'T>``>) x
static member Return (_: seq<'a> , _: Default2) = fun x -> Seq.singleton x : seq<'a>
static member inline Return (_: 'R , _: Default1) = fun (x: 'T) -> Return.InvokeOnInstance x : 'R
static member Return (_: Lazy<'a> , _: Return ) = fun x -> Lazy<_>.CreateFromValue x : Lazy<'a>
static member Return (_: option<'a> , _: Return ) = fun x -> Some x : option<'a>
static member Return (_: list<'a> , _: Return ) = fun x -> [ x ] : list<'a>
static member Return (_: 'a [] , _: Return ) = fun x -> [|x|] : 'a []
static member Return (_: 'a Async , _: Return ) = fun (x: 'a) -> async.Return x
static member Return (_: Result<'a,'e> , _: Return ) = fun x -> Ok x : Result<'a,'e>
static member Return (_: ResizeArray<'a>, _: Return ) = fun x -> ResizeArray<'a> (Seq.singleton x)
type Delay =
inherit Default1
static member inline Delay (_mthd: Default3, x: unit-> ^``Monad<'T>`` when ^``Monad<'T>`` : struct , _: Default2) = Bind.Invoke (Return.Invoke ()) x : ^``Monad<'T>``
static member inline Delay (_mthd: Default4, x: unit-> ^``Monad<'T>`` when ^``Monad<'T>`` : not struct , _: Default1) = Bind.Invoke (Return.Invoke ()) x : ^``Monad<'T>``
static member Delay (_mthd: Default2, x: unit-> _ , _ ) = Seq.delay x : seq<'T>
static member Delay (_mthd: Default2, x: unit-> 'R -> _ , _ ) = (fun s -> x () s): 'R -> _
static member inline Invoke (source : unit -> '``Monad<'T>``) : '``Monad<'T>`` =
let inline call (mthd: ^M, input: unit -> ^I) = ((^M or ^I) : (static member Delay : _*_*_ -> _) mthd, input, Unchecked.defaultof<Delay>)
call (Unchecked.defaultof<Delay>, source)
let res = Delay.Invoke (fun () -> [5] )
printfn "res is %A" res
Running this prints res is [object Object], but if we comment out the first overload of Delay, we get res is [5] which is the expected result.
Not sure, but it seems to be a problem when there are constraints in the overload, like not struct.
- Dominant language
- F#
- Stars
- 68
- Forks
- 36
- Avg merge
- 13h 1m
- Merged PRs (30d)
- 2
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from fable-compiler/repl
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
fable-compiler/repl#191 · 1 comment · 1 reaction ·
-
Difficulty 5/5 Over a week Newbie friendliness 28/100
fable-compiler/repl#185 · 1 comment ·
-
Difficulty 3/5 1-2 days Newbie friendliness 30/100
fable-compiler/repl#177 · 4 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
fable-compiler/repl#159 · 2 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 38/100
fable-compiler/repl#158 · 3 comments ·
All issues in fable-compiler/repl
Similar issues
-
compiler/runtime
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
objectionary/eo#8869 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
EricSpencer00/Resilient#4824 · 1 comment ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
objectionary/jeo-maven-plugin#1758 ·
-
generics
Difficulty 2/5 1-3 hours Newbie friendliness 82/100