dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.94k stars 788 forks source link

Syntax error with string interpolation - Unexpected identifier in binding #14394

Open KevinRansom opened 2 years ago

KevinRansom commented 2 years ago

In this PR: https://github.com/dotnet/fsharp/pull/14383 an additional (highly suspect .ToString() was need to get it to compile.

Without ToString(): image With ToString(): image

For the non-ToString() version the compiler produces this:

  FSharp.Compiler.Service -> C:\kevinransom\fsharp\artifacts\bin\FSharp.Compiler.Service\Debug\netstandard2.0\FSharp.Compiler.Service.d
  ll
C:\kevinransom\fsharp\vsintegration\src\FSharp.VS.FSI\fsiSessionToolWindow.fs(538,9): error FS0588: The block following this 'let' is u
nfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving
 this block an explicit result. [C:\kevinransom\fsharp\vsintegration\src\FSharp.VS.FSI\FSharp.VS.FSI.fsproj]
C:\kevinransom\fsharp\vsintegration\src\FSharp.VS.FSI\fsiSessionToolWindow.fs(547,9): error FS0010: Unexpected identifier in binding. E
xpected incomplete structured construct at or before this point or other token. [C:\kevinransom\fsharp\vsintegration\src\FSharp.VS.FSI\
FSharp.VS.FSI.fsproj]
C:\kevinransom\fsharp\vsintegration\src\FSharp.VS.FSI\fsiSessionToolWindow.fs(537,5): error FS3118: Incomplete value or function defini
tion. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword. [C:\kevinransom
\fsharp\vsintegration\src\FSharp.VS.FSI\FSharp.VS.FSI.fsproj]
abonie commented 2 years ago

This is really weird. I can't repro it outside this particular place in https://github.com/dotnet/fsharp/pull/14383 where it initially appeared.

Also seems like this:

let executeInteraction dbgBreak dir (filename: string) topLine text =
    let foo = text.ToString() // Calling ToString out of the interpolated string does not help
    let interaction = $"""
#silentCd @"{dir}";;
{if dbgBreak then "#dbgbreak" else ""}
#{topLine} @"{filename}"
{foo};;
#1 "stdin"
;;
"""

does not help i.e. it still shows the same error, but this:

let executeInteraction dbgBreak dir (filename: string) topLine text =
    let foo = "\n" + text // Prepending newline to `text` and removing newline from interpolated string helps
    let interaction = $"""
#silentCd @"{dir}";;
{if dbgBreak then "#dbgbreak" else ""}
#{topLine} @"{filename}"{foo};;
#1 "stdin"
;;
"""

actually works...

Btw, this error might be relevant:

image

Looks like an issue with parsing