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

Better error reporting for CE do! #17779

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@

* Make ILTypeDef interface impls calculation lazy. ([PR #17392](https://github.com/dotnet/fsharp/pull/17392))
* Better ranges for CE `let!` and `use!` error reporting. ([PR #17712](https://github.com/dotnet/fsharp/pull/17712))
* Better ranges for CE `do!` error reporting. ([PR #17779](https://github.com/dotnet/fsharp/pull/17779))

### Breaking Changes
Original file line number Diff line number Diff line change
Expand Up @@ -1592,7 +1592,7 @@ let rec TryTranslateComputationExpression
if ceenv.isQuery && not (innerComp1.IsArbExprAndThusAlreadyReportedError) then
match innerComp1 with
| SynExpr.JoinIn _ -> ()
| SynExpr.DoBang(range = m) -> errorR (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), m))
| SynExpr.DoBang(trivia = { DoBangKeyword = m }) -> errorR (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), m))
| _ -> errorR (Error(FSComp.SR.tcUnrecognizedQueryOperator (), innerComp1.RangeOfFirstPortion))

match
Expand Down Expand Up @@ -1657,7 +1657,7 @@ let rec TryTranslateComputationExpression
| None ->
// "do! expr; cexpr" is treated as { let! () = expr in cexpr }
match innerComp1 with
| SynExpr.DoBang(rhsExpr, m) ->
| SynExpr.DoBang(expr = rhsExpr; range = m) ->
let sp =
match sp with
| DebugPointAtSequential.SuppressExpr -> DebugPointAtBinding.NoneAtDo
Expand Down Expand Up @@ -2867,7 +2867,7 @@ and TranslateComputationExpression (ceenv: ComputationExpressionContext<'a>) fir
// This only occurs in final position in a sequence
match comp with
// "do! expr;" in final position is treated as { let! () = expr in return () } when Return is provided (and no Zero with Default attribute is available) or as { let! () = expr in zero } otherwise
| SynExpr.DoBang(rhsExpr, m) ->
| SynExpr.DoBang(expr = rhsExpr; trivia = { DoBangKeyword = m }) ->
let mUnit = rhsExpr.Range
let rhsExpr = mkSourceExpr rhsExpr ceenv.sourceMethInfo ceenv.builderValName

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6003,10 +6003,10 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
| SynExpr.ImplicitZero m ->
error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m))

| SynExpr.DoBang (_, m)
| SynExpr.DoBang (trivia = { DoBangKeyword = m })
| SynExpr.MatchBang (range = m)
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
| SynExpr.WhileBang (range = m)
| SynExpr.LetOrUseBang (range = m) ->
| SynExpr.LetOrUseBang (trivia = { LetOrUseBangKeyword = m }) ->
error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m))

| SynExpr.IndexFromEnd (rightExpr, m) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT

| SynExpr.ImplicitZero m -> Some(mkSeqEmpty cenv env m genOuterTy, tpenv)

| SynExpr.DoBang(_rhsExpr, m) -> error (Error(FSComp.SR.tcDoBangIllegalInSequenceExpression (), m))
| SynExpr.DoBang(trivia = { DoBangKeyword = m }) -> error (Error(FSComp.SR.tcDoBangIllegalInSequenceExpression (), m))

| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, _) ->
let env1 =
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Driver/GraphChecking/FileContentMapping.fs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list =
visit expr (fun exprNodes ->
[ yield! exprNodes; yield! List.collect visitSynMatchClause clauses ]
|> continuation)
| SynExpr.DoBang(expr, _) -> visit expr continuation
| SynExpr.DoBang(expr = expr) -> visit expr continuation
| SynExpr.WhileBang(whileExpr = whileExpr; doExpr = doExpr) ->
visit whileExpr (fun whileNodes -> visit doExpr (fun doNodes -> whileNodes @ doNodes |> continuation))
| SynExpr.LibraryOnlyILAssembly(typeArgs = typeArgs; args = args; retTy = retTy) ->
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/FSharpParseFileResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
yield! walkExpr false e

| SynExpr.YieldOrReturnFrom(_, e, _)
| SynExpr.DoBang(e, _) ->
| SynExpr.DoBang(expr = e) ->
yield! checkRange e.Range
yield! walkExpr false e

Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/Service/ServiceInterfaceStubGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -952,9 +952,9 @@ module InterfaceStubGenerator =
| SynExpr.Null _range
| SynExpr.ImplicitZero _range -> None

| SynExpr.YieldOrReturn(_, synExpr, _range)
| SynExpr.YieldOrReturnFrom(_, synExpr, _range)
| SynExpr.DoBang(synExpr, _range) -> walkExpr synExpr
| SynExpr.YieldOrReturn(expr = synExpr)
| SynExpr.YieldOrReturnFrom(expr = synExpr)
| SynExpr.DoBang(expr = synExpr) -> walkExpr synExpr

| SynExpr.LetOrUseBang(rhs = synExpr1; andBangs = synExprAndBangs; body = synExpr2) ->
[
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/ServiceStructure.fs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ module Structure =
rcheck Scope.YieldOrReturnBang Collapse.Below r r
parseExpr e

| SynExpr.DoBang(e, r) ->
| SynExpr.DoBang(expr = e; range = r) ->
rcheck Scope.Do Collapse.Below r <| Range.modStart 3 r
parseExpr e

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ type SynExpr =
range: range *
trivia: SynExprMatchBangTrivia

| DoBang of expr: SynExpr * range: range
| DoBang of expr: SynExpr * range: range * trivia: SynExprDoBangTrivia

| WhileBang of whileDebugPoint: DebugPointAtWhile * whileExpr: SynExpr * doExpr: SynExpr * range: range

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ type SynExpr =

/// F# syntax: do! expr
/// Computation expressions only
| DoBang of expr: SynExpr * range: range
| DoBang of expr: SynExpr * range: range * trivia: SynExprDoBangTrivia

/// F# syntax: 'while! ... do ...'
| WhileBang of whileDebugPoint: DebugPointAtWhile * whileExpr: SynExpr * doExpr: SynExpr * range: range
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ let rec synExprContainsError inpExpr =
| SynExpr.TraitCall(_, _, e, _)
| SynExpr.YieldOrReturn(_, e, _)
| SynExpr.YieldOrReturnFrom(_, e, _)
| SynExpr.DoBang(e, _)
| SynExpr.DoBang(e, _, _)
| SynExpr.Fixed(e, _)
| SynExpr.DebugPoint(_, _, e)
| SynExpr.Paren(e, _, _, _) -> walkExpr e
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ type SynExprMatchBangTrivia =
WithKeyword: range
}

[<NoEquality; NoComparison>]
type SynExprDoBangTrivia = { DoBangKeyword: range }

[<NoEquality; NoComparison>]
type SynExprAnonRecdTrivia = { OpeningBraceRange: range }

Expand Down
8 changes: 8 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ type SynExprMatchBangTrivia =
WithKeyword: range
}

/// Represents additional information for SynExpr.DoBang
[<NoEquality; NoComparison>]
type SynExprDoBangTrivia =
{
/// The syntax range of the `do!` keyword
DoBangKeyword: range
}

/// Represents additional information for SynExpr.AnonRecd
[<NoEquality; NoComparison>]
type SynExprAnonRecdTrivia =
Expand Down
9 changes: 6 additions & 3 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -4442,11 +4442,14 @@ declExpr:

| DO_BANG typedSequentialExpr IN opt_OBLOCKSEP typedSequentialExprBlock %prec expr_let
{ let spBind = DebugPointAtBinding.NoneAtDo
let trivia: SynExprLetOrUseBangTrivia = { LetOrUseBangKeyword = Range.Zero; EqualsRange = None }
SynExpr.LetOrUseBang(spBind, false, true, SynPat.Const(SynConst.Unit, $2.Range), $2, [], $5, unionRanges (rhs parseState 1) $5.Range, trivia) }
let trivia: SynExprDoBangTrivia = { DoBangKeyword = rhs parseState 1 }
let m = unionRanges (rhs parseState 1) $5.Range
SynExpr.DoBang($2, m, trivia) }

| ODO_BANG typedSequentialExprBlock hardwhiteDefnBindingsTerminator %prec expr_let
{ SynExpr.DoBang($2, unionRanges (rhs parseState 1) $2.Range) }
{ let trivia: SynExprDoBangTrivia = { DoBangKeyword = rhs parseState 1 }
let m = unionRanges (rhs parseState 1) $2.Range
SynExpr.DoBang($2, m, trivia) }

| FIXED declExpr
{ SynExpr.Fixed($2, (unionRanges (rhs parseState 1) $2.Range)) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ query {
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 3143, Line 3, Col 5, Line 3, Col 20, "'let!', 'use!' and 'do!' expressions may not be used in queries")
(Error 3143, Line 3, Col 5, Line 3, Col 8, "'let!', 'use!' and 'do!' expressions may not be used in queries")
]

[<Fact>]
Expand Down Expand Up @@ -392,7 +392,7 @@ query {
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 3143, Line 4, Col 5, Line 4, Col 20, "'let!', 'use!' and 'do!' expressions may not be used in queries")
(Error 3143, Line 4, Col 5, Line 4, Col 8, "'let!', 'use!' and 'do!' expressions may not be used in queries")
]

[<Fact>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7606,7 +7606,13 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewConst(FSharp.C
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDebugPoint(FSharp.Compiler.Syntax.DebugPointAtLeafExpr, Boolean, FSharp.Compiler.Syntax.SynExpr)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDiscardAfterMissingQualificationAfterDot(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDo(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia get_trivia()
FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia trivia
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia)
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: FSharp.Compiler.Text.Range DoBangKeyword
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: FSharp.Compiler.Text.Range get_DoBangKeyword()
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7606,7 +7606,13 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewConst(FSharp.C
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDebugPoint(FSharp.Compiler.Syntax.DebugPointAtLeafExpr, Boolean, FSharp.Compiler.Syntax.SynExpr)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDiscardAfterMissingQualificationAfterDot(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDo(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia get_trivia()
FSharp.Compiler.Syntax.SynExpr+DoBang: FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia trivia
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia)
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: FSharp.Compiler.Text.Range DoBangKeyword
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: FSharp.Compiler.Text.Range get_DoBangKeyword()
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynExprDoBangTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range)
FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range)
Expand Down
2 changes: 1 addition & 1 deletion tests/fsharp/typecheck/sigs/neg61.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ neg61.fs(92,13,92,70): typecheck error FS3142: 'use' expressions may not be used

neg61.fs(97,13,97,17): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries

neg61.fs(102,13,102,28): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries
neg61.fs(102,13,102,16): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries

neg61.fs(107,13,107,21): typecheck error FS3144: 'return' and 'return!' may not be used in queries

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ ImplFile
Named (SynIdent (a, None), false, None, (2,4--2,5)), None,
Sequential
(SuppressNeither, true, Do (Ident foobar, (3,4--4,14)),
DoBang (Ident foobarBang, (5,4--6,18)), (3,4--6,18),
DoBang
(Ident foobarBang, (5,4--6,18),
{ DoBangKeyword = (5,4--5,7) }), (3,4--6,18),
{ SeparatorRange = None }), (2,4--2,5), NoneAtLet,
{ LeadingKeyword = Let (2,0--2,3)
InlineKeyword = None
Expand Down
Loading