Skip to content

Commit

Permalink
Improve error reporting: Let as last line in block - fixes dotnet#1162
Browse files Browse the repository at this point in the history
  • Loading branch information
forki committed May 12, 2016
1 parent 2fb5b46 commit 7defc48
Show file tree
Hide file tree
Showing 14 changed files with 25 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/fsharp/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ parsConsiderUsingSeparateRecordType,"Consider using a separate record type inste
584,parsSuccessivePatternsShouldBeSpacedOrTupled,"Successive patterns should be separated by spaces or tupled"
586,parsNoMatchingInForLet,"No matching 'in' found for this 'let'"
587,parsErrorInReturnForLetIncorrectIndentation,"Error in the return expression for this 'let'. Possible incorrect indentation."
588,parsExpectedStatementAfterLet,"Block following this '%s' is unfinished. Expect an expression."
588,parsExpectedExpressionAfterLet,"The block following this '%s' is unfinished. Every code block is an expression and must have a result. '%s' cannot be the final code element in a block. Consider giving this block an explicit result."
589,parsIncompleteIf,"Incomplete conditional. Expected 'if <expr> then <expr>' or 'if <expr> then <expr> else <expr>'."
590,parsAssertIsNotFirstClassValue,"'assert' may not be used as a first class value. Use 'assert <expr>' instead."
594,parsIdentifierExpected,"Identifier expected"
Expand Down
3 changes: 2 additions & 1 deletion src/fsharp/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -2957,7 +2957,8 @@ seqExpr:
| hardwhiteLetBindings %prec prec_args_error
{ let hwlb,m = $1
let mLetKwd,isUse = match hwlb with (BindingSetPreAttrs(m,_,isUse,_,_)) -> m,isUse
reportParseErrorAt mLetKwd (FSComp.SR.parsExpectedStatementAfterLet(if isUse then "use" else "let"))
let usedKeyword = if isUse then "use" else "let"
reportParseErrorAt mLetKwd (FSComp.SR.parsExpectedExpressionAfterLet(usedKeyword,usedKeyword))
let fauxRange = m.EndRange // zero width range at end of m
mkLocalBindings (m,hwlb,arbExpr("seqExpr",fauxRange)) }

Expand Down
2 changes: 1 addition & 1 deletion tests/fsharp/typecheck/sigs/neg75.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ neg75.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: th

neg75.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

neg75.fsx(153,24,153,27): parse error FS0588: Block following this 'let' is unfinished. Expect an expression.
neg75.fsx(153,24,153,27): parse error FS0588: The block following this 'let' is unfinished. 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.
4 changes: 2 additions & 2 deletions tests/fsharp/typecheck/sigs/neg75.vsbsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ neg75.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: th

neg75.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

neg75.fsx(153,24,153,27): parse error FS0588: Block following this 'let' is unfinished. Expect an expression.
neg75.fsx(153,24,153,27): parse error FS0588: The block following this 'let' is unfinished. 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.

neg75.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

Expand All @@ -17,4 +17,4 @@ neg75.fsx(155,24,155,27): parse error FS0058: Possible incorrect indentation: th

neg75.fsx(155,24,155,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

neg75.fsx(153,24,153,27): parse error FS0588: Block following this 'let' is unfinished. Expect an expression.
neg75.fsx(153,24,153,27): parse error FS0588: The block following this 'let' is unfinished. 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.
2 changes: 1 addition & 1 deletion tests/fsharp/typecheck/sigs/neg76.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ neg76.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: th

neg76.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

neg76.fsx(153,24,153,27): parse error FS0588: Block following this 'let' is unfinished. Expect an expression.
neg76.fsx(153,24,153,27): parse error FS0588: The block following this 'let' is unfinished. 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.
4 changes: 2 additions & 2 deletions tests/fsharp/typecheck/sigs/neg76.vsbsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ neg76.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: th

neg76.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

neg76.fsx(153,24,153,27): parse error FS0588: Block following this 'let' is unfinished. Expect an expression.
neg76.fsx(153,24,153,27): parse error FS0588: The block following this 'let' is unfinished. 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.

neg76.fsx(154,24,154,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

Expand All @@ -17,4 +17,4 @@ neg76.fsx(155,24,155,27): parse error FS0058: Possible incorrect indentation: th

neg76.fsx(155,24,155,27): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (153:38). Try indenting this token further or using standard formatting conventions.

neg76.fsx(153,24,153,27): parse error FS0588: Block following this 'let' is unfinished. Expect an expression.
neg76.fsx(153,24,153,27): parse error FS0588: The block following this 'let' is unfinished. 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.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Verify error on unclosed let-block
// Regression for FSB 1616

//<Expects id="FS0588" status="error" span="(10,5)">Block following this 'let' is unfinished\. Expect an expression</Expects>
//<Expects id="FS0588" status="error" span="(10,5)">The block following this 'let' is unfinished. 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.</Expects>

// Note how the compiler is left hanging for what completes the function...

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Regression test for FSHARP1.0:2099
// Regression test for FSHARP1.0:2670
//<Expects id="FS0010" span="(18,50-18,52)" status="error">Unexpected symbol '<-' in pattern</Expects>
//<Expects id="FS0588" span="(18,42-18,45)" status="error">Block following this 'let' is unfinished\. Expect an expression</Expects>
//<Expects id="FS0588" span="(18,42-18,45)" status="error">The block following this 'let' is unfinished. 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.</Expects>
//<Expects status=notin>lambda</Expects>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//<Expects span="(19,19-19,20)" status="error" id="FS0604">Unmatched '\{'$</Expects>
//<Expects span="(22,1-22,1)" status="error" id="FS0528" >Unexpected end of input$</Expects>
//<Expects status="error" span="(18,9-18,12)" id="FS3118">Incomplete value or function definition\. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword\.$</Expects>
//<Expects span="(18,9-18,12)" status="error" id="FS0588">Block following this 'let' is unfinished\. Expect an expression\.$</Expects>
//<Expects span="(18,9-18,12)" status="error" id="FS0588">The block following this 'let' is unfinished. 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.</Expects>
//<Expects span="(22,1-22,1)" status="error" id="FS0528">Unexpected end of input$</Expects>

//<Expects status="error" span="(17,29-17,32)" id="FS3110">Unexpected end of input in body of lambda expression\. Expected 'fun <pat> \.\.\. <pat> -> <expr>'\.$</Expects>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// #Regression #NoMT #FSI
// Regression test for FSHARP1.0:5629
//<Expects status="error" span="(4,9)" id="FS0588">Block following this 'let' is unfinished\. Expect an expression\.$</Expects>
//<Expects status="error" span="(4,9)" id="FS0588">The block following this 'let' is unfinished. 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.</Expects>
let x = let y = 2;;
exit 1;;
8 changes: 8 additions & 0 deletions tests/fsharpqa/Source/Warnings/MissingExpressionAfterLet.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// #Warnings
//<Expects status="Error" span="(6,5)" id="FS0588">The block following this 'let' is unfinished. 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.</Expects>

let sum = 0
for x in 0 .. 10 do
let sum = sum + x

exit 0
1 change: 1 addition & 0 deletions tests/fsharpqa/Source/Warnings/env.lst
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
SOURCE=CommaInRecCtor.fs # CommaInRecCtor.fs
SOURCE=ValidCommaInRecCtor.fs # ValidCommaInRecCtor.fs
SOURCE=ElseBranchHasWrongType.fs # ElseBranchHasWrongType.fs
SOURCE=MissingExpressionAfterLet.fs # MissingExpressionAfterLet.fs
SOURCE=AssignmentOnImmutable.fs # AssignmentOnImmutable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type UsingMSBuild() =
override x.ToString() = ""
let Main() =
let x = MyType()"""
let expectedStr = "Block following this 'let' is unfinished"
let expectedStr = "The block following this 'let' is unfinished. 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."
this.VerifyErrorListContainedExpectedString(fileContent,expectedStr)

// Not a recovery case, but make sure we get a squiggle at the unfinished Main()
Expand All @@ -50,7 +50,7 @@ type UsingMSBuild() =
override x.ToString() = ""
let Main() =
use x = MyType()"""
let expectedStr = "Block following this 'use' is unfinished"
let expectedStr = "The block following this 'use' is unfinished. Every code block is an expression and must have a result. 'use' cannot be the final code element in a block. Consider giving this block an explicit result."
this.VerifyErrorListContainedExpectedString(fileContent,expectedStr)

[<Test>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ type X() =
[<Test>]
member public this.``OrphanFs.ParseErrorsStillShow``() =
let fileContent = """let foo = let(*Mark*)"""
this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "Block following "))
this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "Every code block "))

/// FEATURE: If a .fs file has a BuildAction other than "Compile", it behaves like a
/// single-file-project with regards to intellisense.
Expand Down

0 comments on commit 7defc48

Please sign in to comment.