Fix error in optimization of for loops over strings and lists#742
Fix error in optimization of for loops over strings and lists#742robertpi wants to merge 2 commits intodotnet:masterfrom
Conversation
- Upgrate to latest build tools as version previously used is no longer on nuget - Use F# 4.0 as the comparison compiler as I don't have F# 3.1 on this machine
…ng was relying on the type of the declartion directly before the loop, not necessarily the values being looped over
|
Hi @robertpi, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! TTYL, MSBOT; |
There was a problem hiding this comment.
Yes and no. It's unrelated to the fix, but I think it's needed as the compiler won't build from scratch without it. Seems the old package is no longer available on nuget. It's in a seperate commit.
There was a problem hiding this comment.
Perhaps submit this as a separate PR
|
Thank you for the fix, could you please add a test so we don't regress this. Thanks |
|
Not sure what I should add as a test. The test I was going to add, to check the foreach loop is correctly turned into a for loop are covered in: Tell me what else is needed and I'll add it. |
|
@robertpi, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
So I suppose the test is to ensure this compiles and runs correctly. |
|
According to appveyor the fsharp smoketests fail. More output: |
|
I've provided an alternative implementation of a fix here: #756 . It incorporates some of the ideas from this fix but applies some additional constraints. I've also added the original repro as a test. |
|
Closing as covered by 742 |
|
A not-so-pretty workaround for this issue is here: #759 (comment). (note however it requires changes to user code) |
We recently discovered this issue in FAKE:
fsprojects/FAKE#985
Which actually comes from FAKE's dependency on FSharp.Compiler.Service, which is based on the latest version of visualfsharp, which contains the actual bug :)
The problem is that the optimization looks for code of the form:
let s = "to loop over"
for x in s do
System.Consolve.WriteLine(x)
This works when code loops over the string, as might be expected, but if you declare a string before the for loop and loop over something else the optimization is triggered and produces a bizarre compile error: For example the following program
let configure () =
let aSequence = seq { yield "" }
let aString = new System.String([||])
for _ in aSequence do
System.Console.WriteLine(aString)
configure ()
Give the following compile error:
myrepo.fs(5,65): error FS0971: Undefined value 'aString: string'
This pull request fixes the issue by looping at the expression that GetEnumator is called on, rather than the let declaration before the loop.