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

The following code prevents the compiler from terminating #351

Closed
LukaHorvat opened this issue Apr 9, 2015 · 9 comments
Closed

The following code prevents the compiler from terminating #351

LukaHorvat opened this issue Apr 9, 2015 · 9 comments
Labels
Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code.

Comments

@LukaHorvat
Copy link

I reported this to fsharp and it was suggested I should report it here as well.

Description:
The idea was to make a function format that can return any function which's type passes a static check. The functions that are valid take parameters (arbitrarily many) of type string or int and produce either a unit or an int.
Including the checker function in another function would make sure that the type parameter is a valid function type, which would then be constructed unsafely via reflection or similar and then finally casted to the appropriate target type.

Unfortunately, this code causes the compiler to hang indefinitely (or as far as my patience extended).
This might not be a bug if it's a design decision to allow non-termination, but I'd find that strange considering my code consists only of valid language constructs.

Repro Steps:
Compile this code

type Switcher = Switcher

let inline checker< ^s, ^r when (^s or ^r) : (static member pass : ^r -> unit)> (s : ^s) (r : ^r) = ()

let inline format () : ^r =
    checker Switcher Unchecked.defaultof< ^r>
    () :> obj :?> ^r

type Switcher with
    static member inline pass(_ : string -> ^r) =
        checker Switcher Unchecked.defaultof< ^r>
    static member inline pass(_ : int -> ^r) =
        checker Switcher Unchecked.defaultof< ^r>
    static member inline pass(_ : unit) = ()
    static member inline pass(_ : int) = ()

[<EntryPoint>]
let main argv = 
    let res : unit = format () "text" 5 "more text" ()
    printfn "%A" res
    Console.ReadKey()
    0 // return an integer exit code

Severity: It's pretty bad that the compiler fails to terminate, but it's a fairly obscure use case.

Version: Visual Studio 2015 Preview, my project targets .NET Framework 4.5.3 and the runtime is F# 4.0 (FSharp.Core, 4.4.0.0)

@latkin
Copy link
Contributor

latkin commented Apr 9, 2015

I can repro. Pasting the code into the editor causes VS to spin CPU indefinitely, too.

@latkin latkin added the Bug label Apr 9, 2015
@rojepp
Copy link
Contributor

rojepp commented Apr 10, 2015

I can repro in Xamarin Studio on OSX, so it's not a F# 4.0 issue.

@dsyme
Copy link
Contributor

dsyme commented May 9, 2015

I've taken a look at this with a view to whether to attempt a fix (or restriction) for F# 4.0. However, it's hard - it involves error paths during very nested overload resolution.

In any case, given where we are with the F# 4.0 RTM milestone, I haven't been able to determine a non-destabilizing fix that's appropriate at this stage. I believe this will need to be fixed at a later stage. The fix could be along the lines of a language restriction that require more complete signatures to be given in some situations,

In this example, it's not clear if progress is being made (though slowly, which would still be an issue) or if there is actually a proper loop. @forki also took a look and may have more to share.

@dsyme dsyme added the pri-3 label May 9, 2015
@forki
Copy link
Contributor

forki commented May 9, 2015

From my limited understanding it didn't made progress. Instead it circled
between two states.
On May 9, 2015 2:29 PM, "Don Syme" notifications@github.com wrote:

I've taken a look at this with a view to whether to attempt a fix (or
restriction) for F# 4.0. However, it's hard - it involves error paths
during very nested overload resolution.

In any case, given where we are with the F# 4.0 RTM milestone, I haven't
been able to determine a non-destabilizing fix that's appropriate at this
stage. I believe this will need to be fixed at a later stage. The fix could
be along the lines of a language restriction that require more complete
signatures to be given in some situations,

In this example, it's not clear if progress is being made (though slowly,
which would still be an issue) or if there is actually a proper loop.
@forki https://github.com/forki also took a look and may have more to
share.


Reply to this email directly or view it on GitHub
#351 (comment)
.

@dsyme
Copy link
Contributor

dsyme commented May 9, 2015

See also #395, which I'm considering a duplicate of this as I suspect the underlying causes to be the same.

@KevinRansom KevinRansom removed the pri-3 label Dec 4, 2015
@dsyme dsyme added Area-Compiler Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code. labels Jan 8, 2016
@dsyme
Copy link
Contributor

dsyme commented Jul 18, 2016

Closing as a duplicate of #343 (it seems the compiler is making progress, just very slowly)

@dsyme dsyme closed this as completed Jul 18, 2016
forki added a commit to forki/visualfsharp that referenced this issue Sep 19, 2016
@forki
Copy link
Contributor

forki commented Sep 19, 2016

with @gmpl's PR 1530 applied this immediatly gives:

image

Is that expected? I tried to put that in #1550

@gusty
Copy link
Contributor

gusty commented Sep 19, 2016

After analyzing and working with the Constraint Solver I'm not surprised that some samples (like this) never ends.
But after the fix I'm proposing they should.
Now, whether they end successfully or with an error is a different thing.
I need to study more this repro, but in principle I would say that if the code in the repro makes sense it should compile and if it don't compile then we're facing another compiler bug, similar to the ones I reported and they should be fixed in a separated pull request.

@forki
Copy link
Contributor

forki commented Sep 19, 2016

@gmpl one thing is for sure: giving a error message immediately is better than compiler going into quasi infinite loop. So from my point of view your pr is a win for this case here.

forki added a commit to forki/visualfsharp that referenced this issue Sep 19, 2016
dsyme pushed a commit that referenced this issue Oct 18, 2016
* Assume the constraint is solved before trying each overload.

* Defer transact member solution.

* Fix previous commit.

* Refactor with an additional function.

* Remove unused parameter.

* Fix test by removing duplicate error message.

* Add comment.

* Try to reproduce #351

* Commit cx solution right after the shortcut.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Impact-Low (Internal MS Team use only) Describes an issue with limited impact on existing code.
Projects
None yet
Development

No branches or pull requests

7 participants