diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index e58c882938..28f20ca2be 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -16,6 +16,7 @@ * Remove non-functional useSyntaxTreeCache option. ([PR #17768](https://github.com/dotnet/fsharp/pull/17768)) * 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)) +* Better ranges for CE `return, yield, return! and yield!` error reporting. ([PR #17792](https://github.com/dotnet/fsharp/pull/17792)) * Better ranges for CE `match!`. ([PR #17789](https://github.com/dotnet/fsharp/pull/17789)) ### Breaking Changes diff --git a/docs/release-notes/.VisualStudio/17.12.md b/docs/release-notes/.VisualStudio/17.12.md index 83df7173b2..690ec481a2 100644 --- a/docs/release-notes/.VisualStudio/17.12.md +++ b/docs/release-notes/.VisualStudio/17.12.md @@ -5,9 +5,10 @@ ### Added ### Changed +* Fix unwanted navigation on hover [PR #17592](https://github.com/dotnet/fsharp/pull/17592) +* Update `RemoveReturnOrYield` code fix range calculation [PR #17792](https://github.com/dotnet/fsharp/pull/17792) * Fix unwanted navigation on hover [PR #17592](https://github.com/dotnet/fsharp/pull/17592)) * Remove non-functional useSyntaxTreeCache option. ([PR #17768](https://github.com/dotnet/fsharp/pull/17768)) - ### Breaking Changes * Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500))) diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index d328f6a310..c1aa4dafc5 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -1545,7 +1545,9 @@ let rec TryTranslateComputationExpression let dataCompPrior = translatedCtxt ( - TranslateComputationExpressionNoQueryOps ceenv (SynExpr.YieldOrReturn((true, false), varSpaceExpr, mClause)) + TranslateComputationExpressionNoQueryOps + ceenv + (SynExpr.YieldOrReturn((true, false), varSpaceExpr, mClause, SynExprYieldOrReturnTrivia.Zero)) ) // Rebind using for ... @@ -1576,7 +1578,9 @@ let rec TryTranslateComputationExpression let isYield = not (customOperationMaintainsVarSpaceUsingBind ceenv nm) translatedCtxt ( - TranslateComputationExpressionNoQueryOps ceenv (SynExpr.YieldOrReturn((isYield, false), varSpaceExpr, mClause)) + TranslateComputationExpressionNoQueryOps + ceenv + (SynExpr.YieldOrReturn((isYield, false), varSpaceExpr, mClause, SynExprYieldOrReturnTrivia.Zero)) ) // Now run the consumeCustomOpClauses @@ -2374,7 +2378,7 @@ let rec TryTranslateComputationExpression Some(translatedCtxt callExpr) - | SynExpr.YieldOrReturnFrom((true, _), synYieldExpr, m) -> + | SynExpr.YieldOrReturnFrom((true, _), synYieldExpr, _, { YieldOrReturnFromKeyword = m }) -> let yieldFromExpr = mkSourceExpr synYieldExpr ceenv.sourceMethInfo ceenv.builderValName @@ -2392,7 +2396,8 @@ let rec TryTranslateComputationExpression then error (Error(FSComp.SR.tcRequireBuilderMethod ("YieldFrom"), m)) - let yieldFromCall = mkSynCall "YieldFrom" m [ yieldFromExpr ] ceenv.builderValName + let yieldFromCall = + mkSynCall "YieldFrom" synYieldExpr.Range [ yieldFromExpr ] ceenv.builderValName let yieldFromCall = if IsControlFlowExpression synYieldExpr then @@ -2402,7 +2407,7 @@ let rec TryTranslateComputationExpression Some(translatedCtxt yieldFromCall) - | SynExpr.YieldOrReturnFrom((false, _), synReturnExpr, m) -> + | SynExpr.YieldOrReturnFrom((false, _), synReturnExpr, _, { YieldOrReturnFromKeyword = m }) -> let returnFromExpr = mkSourceExpr synReturnExpr ceenv.sourceMethInfo ceenv.builderValName @@ -2424,7 +2429,7 @@ let rec TryTranslateComputationExpression error (Error(FSComp.SR.tcRequireBuilderMethod ("ReturnFrom"), m)) let returnFromCall = - mkSynCall "ReturnFrom" m [ returnFromExpr ] ceenv.builderValName + mkSynCall "ReturnFrom" synReturnExpr.Range [ returnFromExpr ] ceenv.builderValName let returnFromCall = if IsControlFlowExpression synReturnExpr then @@ -2434,7 +2439,7 @@ let rec TryTranslateComputationExpression Some(translatedCtxt returnFromCall) - | SynExpr.YieldOrReturn((isYield, _), synYieldOrReturnExpr, m) -> + | SynExpr.YieldOrReturn((isYield, _), synYieldOrReturnExpr, _, { YieldOrReturnKeyword = m }) -> let methName = (if isYield then "Yield" else "Return") if ceenv.isQuery && not isYield then @@ -2452,10 +2457,10 @@ let rec TryTranslateComputationExpression ceenv.builderTy ) then - error (Error(FSComp.SR.tcRequireBuilderMethod (methName), m)) + error (Error(FSComp.SR.tcRequireBuilderMethod methName, m)) let yieldOrReturnCall = - mkSynCall methName m [ synYieldOrReturnExpr ] ceenv.builderValName + mkSynCall methName synYieldOrReturnExpr.Range [ synYieldOrReturnExpr ] ceenv.builderValName let yieldOrReturnCall = if IsControlFlowExpression synYieldOrReturnExpr then @@ -2759,7 +2764,7 @@ and TranslateComputationExpressionBind /// The inner option indicates if a custom operation is involved inside and convertSimpleReturnToExpr (ceenv: ComputationExpressionContext<'a>) comp varSpace innerComp = match innerComp with - | SynExpr.YieldOrReturn((false, _), returnExpr, m) -> + | SynExpr.YieldOrReturn((false, _), returnExpr, m, _) -> let returnExpr = SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, returnExpr) Some(returnExpr, None) @@ -2901,7 +2906,7 @@ and TranslateComputationExpression (ceenv: ComputationExpressionContext<'a>) fir with | minfo :: _ when MethInfoHasAttribute ceenv.cenv.g m ceenv.cenv.g.attrib_DefaultValueAttribute minfo -> SynExpr.ImplicitZero m - | _ -> SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m) + | _ -> SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m, SynExprYieldOrReturnTrivia.Zero) let letBangBind = SynExpr.LetOrUseBang( diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 3a01eaa2ef..4325d50320 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -5991,16 +5991,16 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcQuotationExpr cenv overallTy env tpenv (oper, raw, ast, isFromQueryExpression, m) - | SynExpr.YieldOrReturn ((isTrueYield, _), _, m) - | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, m) when isTrueYield -> + | SynExpr.YieldOrReturn ((isTrueYield, _), _, _m, { YieldOrReturnKeyword = m }) + | SynExpr.YieldOrReturnFrom ((isTrueYield, _), _, _m, { YieldOrReturnFromKeyword = m }) when isTrueYield -> error(Error(FSComp.SR.tcConstructRequiresListArrayOrSequence(), m)) - | SynExpr.YieldOrReturn ((_, isTrueReturn), _, m) - | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, m) when isTrueReturn -> + | SynExpr.YieldOrReturn ((_, isTrueReturn), _, _m, { YieldOrReturnKeyword = m }) + | SynExpr.YieldOrReturnFrom ((_, isTrueReturn), _, _m, { YieldOrReturnFromKeyword = m }) when isTrueReturn -> error(Error(FSComp.SR.tcConstructRequiresComputationExpressions(), m)) - | SynExpr.YieldOrReturn (_, _, m) - | SynExpr.YieldOrReturnFrom (_, _, m) + | SynExpr.YieldOrReturn (trivia = { YieldOrReturnKeyword = m }) + | SynExpr.YieldOrReturnFrom (trivia = { YieldOrReturnFromKeyword = m }) | SynExpr.ImplicitZero m -> error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m)) diff --git a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs index b627eef292..781060c8af 100644 --- a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs @@ -353,43 +353,44 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT Some(combinatorExpr, tpenv) - | SynExpr.YieldOrReturnFrom((isYield, _), synYieldExpr, m) -> + | SynExpr.YieldOrReturnFrom(flags = (isYield, _); expr = synYieldExpr; trivia = { YieldOrReturnFromKeyword = m }) -> let env = { env with eIsControlFlow = false } let resultExpr, genExprTy, tpenv = TcExprOfUnknownType cenv env tpenv synYieldExpr if not isYield then errorR (Error(FSComp.SR.tcUseYieldBangForMultipleResults (), m)) - AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css m NoTrace genOuterTy genExprTy + AddCxTypeMustSubsumeType ContextInfo.NoContext env.DisplayEnv cenv.css synYieldExpr.Range NoTrace genOuterTy genExprTy - let resultExpr = mkCoerceExpr (resultExpr, genOuterTy, m, genExprTy) + let resultExpr = + mkCoerceExpr (resultExpr, genOuterTy, synYieldExpr.Range, genExprTy) let resultExpr = if IsControlFlowExpression synYieldExpr then resultExpr else - mkDebugPoint m resultExpr + mkDebugPoint resultExpr.Range resultExpr Some(resultExpr, tpenv) - | SynExpr.YieldOrReturn((isYield, _), synYieldExpr, m) -> + | SynExpr.YieldOrReturn(flags = (isYield, _); expr = synYieldExpr; trivia = { YieldOrReturnKeyword = m }) -> let env = { env with eIsControlFlow = false } let genResultTy = NewInferenceType g if not isYield then errorR (Error(FSComp.SR.tcSeqResultsUseYield (), m)) - UnifyTypes cenv env m genOuterTy (mkSeqTy cenv.g genResultTy) + UnifyTypes cenv env synYieldExpr.Range genOuterTy (mkSeqTy cenv.g genResultTy) let resultExpr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv synYieldExpr - let resultExpr = mkCallSeqSingleton cenv.g m genResultTy resultExpr + let resultExpr = mkCallSeqSingleton cenv.g synYieldExpr.Range genResultTy resultExpr let resultExpr = if IsControlFlowExpression synYieldExpr then resultExpr else - mkDebugPoint m resultExpr + mkDebugPoint synYieldExpr.Range resultExpr Some(resultExpr, tpenv) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index d00b5fe793..2623cbde34 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -573,11 +573,11 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, yield! checkRange m yield! walkExpr isControlFlow innerExpr - | SynExpr.YieldOrReturn(_, e, m) -> + | SynExpr.YieldOrReturn(_, e, m, _) -> yield! checkRange m yield! walkExpr false e - | SynExpr.YieldOrReturnFrom(_, e, _) + | SynExpr.YieldOrReturnFrom(_, e, _, _) | SynExpr.DoBang(expr = e) -> yield! checkRange e.Range yield! walkExpr false e diff --git a/src/Compiler/Service/ServiceStructure.fs b/src/Compiler/Service/ServiceStructure.fs index 6ca45aa696..5fab5ef9eb 100644 --- a/src/Compiler/Service/ServiceStructure.fs +++ b/src/Compiler/Service/ServiceStructure.fs @@ -246,11 +246,11 @@ module Structure = rcheck Scope.New Collapse.Below r e.Range parseExpr e - | SynExpr.YieldOrReturn(_, e, r) -> + | SynExpr.YieldOrReturn(_, e, r, _) -> rcheck Scope.YieldOrReturn Collapse.Below r r parseExpr e - | SynExpr.YieldOrReturnFrom(_, e, r) -> + | SynExpr.YieldOrReturnFrom(_, e, r, _) -> rcheck Scope.YieldOrReturnBang Collapse.Below r r parseExpr e diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index f97fe05234..fc0c811e55 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -704,9 +704,9 @@ type SynExpr = | SequentialOrImplicitYield of debugPoint: DebugPointAtSequential * expr1: SynExpr * expr2: SynExpr * ifNotStmt: SynExpr * range: range - | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range + | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnTrivia - | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range + | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnFromTrivia | LetOrUseBang of bindDebugPoint: DebugPointAtBinding * diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index 9913863195..45b03ad3b7 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -877,12 +877,12 @@ type SynExpr = /// F# syntax: yield expr /// F# syntax: return expr /// Computation expressions only - | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range + | YieldOrReturn of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnTrivia /// F# syntax: yield! expr /// F# syntax: return! expr /// Computation expressions only - | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range + | YieldOrReturnFrom of flags: (bool * bool) * expr: SynExpr * range: range * trivia: SynExprYieldOrReturnFromTrivia /// F# syntax: let! pat = expr in expr /// F# syntax: use! pat = expr in expr diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 680986ea50..8dc4631334 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -883,8 +883,8 @@ let rec synExprContainsError inpExpr = | SynExpr.InferredDowncast(e, _) | SynExpr.Lazy(e, _) | SynExpr.TraitCall(_, _, e, _) - | SynExpr.YieldOrReturn(_, e, _) - | SynExpr.YieldOrReturnFrom(_, e, _) + | SynExpr.YieldOrReturn(_, e, _, _) + | SynExpr.YieldOrReturnFrom(_, e, _, _) | SynExpr.DoBang(e, _, _) | SynExpr.Fixed(e, _) | SynExpr.DebugPoint(_, _, e) diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs index 7e03572719..10aee26229 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs @@ -117,6 +117,25 @@ type SynExprMatchBangTrivia = WithKeyword: range } +[] +type SynExprYieldOrReturnTrivia = + { + YieldOrReturnKeyword: range + } + + static member Zero: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = Range.Zero } + +[] +type SynExprYieldOrReturnFromTrivia = + { + YieldOrReturnFromKeyword: range + } + + static member Zero: SynExprYieldOrReturnFromTrivia = + { + YieldOrReturnFromKeyword = Range.Zero + } + [] type SynExprDoBangTrivia = { DoBangKeyword: range } diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi index 3c678a7267..fff834beb4 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi @@ -177,6 +177,24 @@ type SynExprDoBangTrivia = DoBangKeyword: range } +/// Represents additional information for SynExpr.YieldOrReturn +[] +type SynExprYieldOrReturnTrivia = + { + /// The syntax range of the `yield` or `return` keyword. + YieldOrReturnKeyword: range + } + + static member Zero: SynExprYieldOrReturnTrivia + +/// Represents additional information for SynExpr.YieldOrReturnFrom +[] +type SynExprYieldOrReturnFromTrivia = + { + /// The syntax range of the `yield!` or `return!` keyword. + YieldOrReturnFromKeyword: range + } + /// Represents additional information for SynExpr.AnonRecd [] type SynExprAnonRecdTrivia = diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 656b75c39f..185bd1ed84 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4402,18 +4402,22 @@ declExpr: exprFromParseError (SynExpr.ForEach(spFor, spIn, SeqExprOnly false, true, $2, arbExpr ("forLoopCollection", mFor), arbExpr ("forLoopBody3", mForLoopBodyArb), mForLoopAll)) } | YIELD declExpr - { SynExpr.YieldOrReturn(($1, not $1), $2, unionRanges (rhs parseState 1) $2.Range) } + { let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } + SynExpr.YieldOrReturn(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) } | YIELD_BANG declExpr - { SynExpr.YieldOrReturnFrom(($1, not $1), $2, unionRanges (rhs parseState 1) $2.Range) } + { let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } + SynExpr.YieldOrReturnFrom(($1, not $1), $2, (unionRanges (rhs parseState 1) $2.Range), trivia) } | YIELD recover { let mYieldAll = rhs parseState 1 - SynExpr.YieldOrReturn(($1, not $1), arbExpr ("yield", mYieldAll), mYieldAll) } + let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } + SynExpr.YieldOrReturn(($1, not $1), arbExpr ("yield", mYieldAll), mYieldAll, trivia) } | YIELD_BANG recover { let mYieldAll = rhs parseState 1 - SynExpr.YieldOrReturnFrom(($1, not $1), arbExpr ("yield!", mYieldAll), mYieldAll) } + let trivia: SynExprYieldOrReturnFromTrivia = { YieldOrReturnFromKeyword = rhs parseState 1 } + SynExpr.YieldOrReturnFrom(($1, not $1), arbExpr ("yield!", mYieldAll), mYieldAll, trivia) } | BINDER headBindingPattern EQUALS typedSequentialExprBlock IN opt_OBLOCKSEP moreBinders typedSequentialExprBlock %prec expr_let { let spBind = DebugPointAtBinding.Yes(rhs2 parseState 1 5) @@ -4458,7 +4462,8 @@ declExpr: { errorR(Error(FSComp.SR.parsArrowUseIsLimited(), lhs parseState)) let mArrow = rhs parseState 1 let expr = $2 mArrow - SynExpr.YieldOrReturn((true, true), expr, (unionRanges mArrow expr.Range)) } + let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = rhs parseState 1 } + SynExpr.YieldOrReturn((true, true), expr, (unionRanges mArrow expr.Range), trivia) } | declExpr COLON_QMARK typ { SynExpr.TypeTest($1, $3, unionRanges $1.Range $3.Range) } @@ -5456,7 +5461,8 @@ arrowThenExprR: | RARROW typedSequentialExprBlockR { let mArrow = rhs parseState 1 let expr = $2 mArrow - SynExpr.YieldOrReturn((true, false), expr, unionRanges mArrow expr.Range) } + let trivia: SynExprYieldOrReturnTrivia = { YieldOrReturnKeyword = mArrow } + SynExpr.YieldOrReturn((true, false), expr, (unionRanges mArrow expr.Range), trivia) } forLoopBinder: | parenPattern IN declExpr diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs index 34263b3f7b..53cb33b5b7 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs @@ -347,7 +347,7 @@ let f4 = |> withDiagnostics [ (Error 1, Line 6, Col 9, Line 6, Col 16, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ") (Error 1, Line 12, Col 13, Line 12, Col 16, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ") - (Error 193, Line 21, Col 9, Line 21, Col 24, "Type constraint mismatch. The type \n 'int list' \nis not compatible with type\n 'string seq' \n") + (Error 193, Line 21, Col 16, Line 21, Col 24, "Type constraint mismatch. The type \n 'int list' \nis not compatible with type\n 'string seq' \n") (Error 1, Line 28, Col 9, Line 28, Col 12, "This expression was expected to have type\n 'int64' \nbut here has type\n 'float' ") ] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 319d79aa8e..9d276c1362 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -493,4 +493,155 @@ let run r2 r3 = |> shouldFail |> withDiagnostics [ (Error 750, Line 3, Col 5, Line 3, Col 11, "This construct may only be used within computation expressions") + ] + + [] + let ``This control construct may only be used if the computation expression builder defines a 'Yield' method`` () = + Fsx """ +let f3 = + async { + if true then + yield "a" + else + yield "b" + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 708, Line 5, Col 13, Line 5, Col 18, "This control construct may only be used if the computation expression builder defines a 'Yield' method") + ] + + [] + let ``This control construct may only be used if the computation expression builder defines a 'YieldFrom' method`` () = + Fsx """ +let f3 = + async { + if true then + yield! "a" + else + yield "b" + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 708, Line 5, Col 13, Line 5, Col 19, "This control construct may only be used if the computation expression builder defines a 'YieldFrom' method") + ] + + + [] + let ``This control construct may only be used if the computation expression builder defines a 'Return' method`` () = + Fsx """ +module Result = + let zip x1 x2 = + match x1,x2 with + | Ok x1res, Ok x2res -> Ok (x1res, x2res) + | Error e, _ -> Error e + | _, Error e -> Error e + +type ResultBuilder() = + member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2 + member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x + member _.Delay(f) = f() + + member _.TryWith(r: Result<'T,'U>, f) = + match r with + | Ok x -> Ok x + | Error e -> f e + +let result = ResultBuilder() + +let run r2 r3 = + result { + match r2 with + | Ok x -> return x + | Error e -> return e + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 708, Line 24, Col 19, Line 24, Col 25, "This control construct may only be used if the computation expression builder defines a 'Return' method") + ] + + + [] + let ``This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method`` () = + Fsx """ +module Result = + let zip x1 x2 = + match x1,x2 with + | Ok x1res, Ok x2res -> Ok (x1res, x2res) + | Error e, _ -> Error e + | _, Error e -> Error e + +type ResultBuilder() = + member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2 + member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x + member _.Delay(f) = f() + + member _.TryWith(r: Result<'T,'U>, f) = + match r with + | Ok x -> Ok x + | Error e -> f e + +let result = ResultBuilder() + +let run r2 r3 = + result { + match r2 with + | Ok x -> return! x + | Error e -> return e + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 708, Line 24, Col 19, Line 24, Col 26, "This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method") + ] + + [] + let ``Type constraint mismatch when using return!`` () = + Fsx """ +open System.Threading.Tasks + +let maybeTask = task { return false } + +let indexHandler (): Task = + task { + return! maybeTask + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 193, Line 8, Col 17, Line 8, Col 26, "Type constraint mismatch. The type \n 'TaskCode' \nis not compatible with type\n 'TaskCode' \n") + ] + + [] + let ``Type constraint mismatch when using return`` () = + Fsx """ +open System.Threading.Tasks + +let maybeTask = task { return false } + +let indexHandler (): Task = + task { + return maybeTask + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 8, Col 16, Line 8, Col 25, "This expression was expected to have type + 'string' +but here has type + 'Task' ") ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs index 982ae0c820..8247eaf60e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs @@ -442,4 +442,29 @@ let typedSeq = |> withErrorCode 30 |> withDiagnosticMessageMatches "Value restriction: The value 'typedSeq' has an inferred generic type" |> withDiagnosticMessageMatches "val typedSeq: '_a seq" - \ No newline at end of file + +[] +let ``yield may only be used within list, array, and sequence expressions``() = + Fsx """ +let f1 = yield [ 3; 4 ] +let f2 = yield! [ 3; 4 ] + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 747, Line 2, Col 10, Line 2, Col 15, "This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq { ... }', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements"); + (Error 747, Line 3, Col 10, Line 3, Col 16, "This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq { ... }', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements") + ] + +[] +let ``return may only be used within list, array, and sequence expressions``() = + Fsx """ +let f1 = return [ 3; 4 ] +let f2 = return! [ 3; 4 ] + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 748, Line 2, Col 10, Line 2, Col 16, "This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'."); + (Error 748, Line 3, Col 10, Line 3, Col 17, "This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.") + ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index da62302304..42ec38ee36 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -7668,8 +7668,22 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.C FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhileBang(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia trivia +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia trivia +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia) +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range YieldOrReturnFromKeyword +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnFromKeyword() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: Void .ctor(FSharp.Compiler.Text.Range) +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia Zero +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_Zero() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range YieldOrReturnKeyword +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnKeyword() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: Void .ctor(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AddressOf FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AnonRecd FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+App diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index da62302304..42ec38ee36 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -7668,8 +7668,22 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.C FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhileBang(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturn: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia trivia +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+YieldOrReturnFrom: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia trivia +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturnFrom(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia) +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range YieldOrReturnFromKeyword +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnFromKeyword() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnFromTrivia: Void .ctor(FSharp.Compiler.Text.Range) +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia Zero +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia get_Zero() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range YieldOrReturnKeyword +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: FSharp.Compiler.Text.Range get_YieldOrReturnKeyword() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprYieldOrReturnTrivia: Void .ctor(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AddressOf FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+AnonRecd FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+App diff --git a/tests/fsharp/typecheck/sigs/neg104.vsbsl b/tests/fsharp/typecheck/sigs/neg104.vsbsl index 8a6059aa12..165b4348e3 100644 --- a/tests/fsharp/typecheck/sigs/neg104.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg104.vsbsl @@ -27,4 +27,4 @@ neg104.fs(20,9,20,15): typecheck error FS0025: Incomplete pattern matches on thi neg104.fs(23,9,23,15): typecheck error FS0025: Incomplete pattern matches on this expression. -neg104.fs(35,9,35,18): typecheck error FS0748: This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'. +neg104.fs(35,9,35,15): typecheck error FS0748: This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'. diff --git a/tests/fsharp/typecheck/sigs/neg107.bsl b/tests/fsharp/typecheck/sigs/neg107.bsl index 30b24d25c5..580233b477 100644 --- a/tests/fsharp/typecheck/sigs/neg107.bsl +++ b/tests/fsharp/typecheck/sigs/neg107.bsl @@ -33,11 +33,11 @@ neg107.fsx(28,55,28,66): typecheck error FS0425: The type of a first-class funct neg107.fsx(30,49,30,54): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(30,57,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(30,64,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. neg107.fsx(31,70,31,75): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(31,78,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(31,85,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. neg107.fsx(32,13,32,30): typecheck error FS3301: The function or method has an invalid return type 'Async>'. This is not permitted by the rules of Common IL. @@ -49,13 +49,13 @@ neg107.fsx(32,48,32,53): typecheck error FS0406: The byref-typed variable 'a' is neg107.fsx(32,48,32,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(32,56,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(32,63,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(32,56,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs +neg107.fsx(32,63,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs neg107.fsx(32,48,32,53): typecheck error FS0425: The type of a first-class function cannot contain byrefs @@ -69,13 +69,13 @@ neg107.fsx(33,56,33,61): typecheck error FS0406: The byref-typed variable 'a' is neg107.fsx(33,56,33,61): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(33,64,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(33,71,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(33,64,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs +neg107.fsx(33,71,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs neg107.fsx(33,56,33,61): typecheck error FS0425: The type of a first-class function cannot contain byrefs diff --git a/tests/fsharp/typecheck/sigs/neg107.vsbsl b/tests/fsharp/typecheck/sigs/neg107.vsbsl index 30b24d25c5..580233b477 100644 --- a/tests/fsharp/typecheck/sigs/neg107.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg107.vsbsl @@ -33,11 +33,11 @@ neg107.fsx(28,55,28,66): typecheck error FS0425: The type of a first-class funct neg107.fsx(30,49,30,54): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(30,57,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(30,64,30,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. neg107.fsx(31,70,31,75): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(31,78,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(31,85,31,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. neg107.fsx(32,13,32,30): typecheck error FS3301: The function or method has an invalid return type 'Async>'. This is not permitted by the rules of Common IL. @@ -49,13 +49,13 @@ neg107.fsx(32,48,32,53): typecheck error FS0406: The byref-typed variable 'a' is neg107.fsx(32,48,32,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(32,56,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(32,63,32,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(32,56,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(32,63,32,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(32,56,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs +neg107.fsx(32,63,32,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs neg107.fsx(32,48,32,53): typecheck error FS0425: The type of a first-class function cannot contain byrefs @@ -69,13 +69,13 @@ neg107.fsx(33,56,33,61): typecheck error FS0406: The byref-typed variable 'a' is neg107.fsx(33,56,33,61): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(33,64,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. +neg107.fsx(33,71,33,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(33,64,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. +neg107.fsx(33,71,33,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg107.fsx(33,64,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs +neg107.fsx(33,71,33,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs neg107.fsx(33,56,33,61): typecheck error FS0425: The type of a first-class function cannot contain byrefs diff --git a/tests/fsharp/typecheck/sigs/neg20.bsl b/tests/fsharp/typecheck/sigs/neg20.bsl index ea20ab65ac..5229dcaacf 100644 --- a/tests/fsharp/typecheck/sigs/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/neg20.bsl @@ -67,7 +67,7 @@ but given a 'B list' The type 'A' does not match the type 'B' -neg20.fs(80,23,80,39): typecheck error FS0193: Type constraint mismatch. The type +neg20.fs(80,30,80,39): typecheck error FS0193: Type constraint mismatch. The type 'C list' is not compatible with type 'B seq' diff --git a/tests/fsharp/typecheck/sigs/neg59.bsl b/tests/fsharp/typecheck/sigs/neg59.bsl index 624750b935..a938f0d271 100644 --- a/tests/fsharp/typecheck/sigs/neg59.bsl +++ b/tests/fsharp/typecheck/sigs/neg59.bsl @@ -41,6 +41,6 @@ neg59.fs(113,15,113,25): typecheck error FS3140: 'while' expressions may not be neg59.fs(118,15,118,25): typecheck error FS3140: 'while' expressions may not be used in queries -neg59.fs(124,17,124,25): typecheck error FS3144: 'return' and 'return!' may not be used in queries +neg59.fs(124,17,124,23): typecheck error FS3144: 'return' and 'return!' may not be used in queries -neg59.fs(128,17,128,26): typecheck error FS3144: 'return' and 'return!' may not be used in queries +neg59.fs(128,17,128,24): typecheck error FS3144: 'return' and 'return!' may not be used in queries diff --git a/tests/fsharp/typecheck/sigs/neg61.bsl b/tests/fsharp/typecheck/sigs/neg61.bsl index 91291a6cb9..b0e6b151a2 100644 --- a/tests/fsharp/typecheck/sigs/neg61.bsl +++ b/tests/fsharp/typecheck/sigs/neg61.bsl @@ -63,9 +63,9 @@ neg61.fs(97,13,97,17): typecheck error FS3143: 'let!', 'use!' and 'do!' expressi 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 +neg61.fs(107,13,107,19): typecheck error FS3144: 'return' and 'return!' may not be used in queries -neg61.fs(111,13,111,24): typecheck error FS3144: 'return' and 'return!' may not be used in queries +neg61.fs(111,13,111,20): typecheck error FS3144: 'return' and 'return!' may not be used in queries neg61.fs(114,13,114,21): typecheck error FS3145: This is not a known query operator. Query operators are identifiers such as 'select', 'where', 'sortBy', 'thenBy', 'groupBy', 'groupValBy', 'join', 'groupJoin', 'sumBy' and 'averageBy', defined using corresponding methods on the 'QueryBuilder' type. diff --git a/tests/fsharp/typecheck/sigs/version50/neg20.bsl b/tests/fsharp/typecheck/sigs/version50/neg20.bsl index 169c18e857..394f7777b2 100644 --- a/tests/fsharp/typecheck/sigs/version50/neg20.bsl +++ b/tests/fsharp/typecheck/sigs/version50/neg20.bsl @@ -98,7 +98,7 @@ but given a 'B list' The type 'A' does not match the type 'B' -neg20.fs(80,23,80,39): typecheck error FS0193: Type constraint mismatch. The type +neg20.fs(80,30,80,39): typecheck error FS0193: Type constraint mismatch. The type 'C list' is not compatible with type 'B seq' diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs index a0bb521f1a..5010e70386 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturn.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ComputationExpressions // Regression test for FSHARP1.0:6149 -//This control construct may only be used if the computation expression builder defines a 'Return' method$ +//This control construct may only be used if the computation expression builder defines a 'Return' method$ type R = S of string diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs index 24f20ffb9a..f8185a9b7f 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingReturnFrom.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ComputationExpressions // Regression test for FSHARP1.0:6149 -//This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method$ +//This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method$ type R = S of string diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs index b731412bfa..7251faf397 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYield.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ComputationExpressions // Regression test for FSHARP1.0:6149 -//This control construct may only be used if the computation expression builder defines a 'Yield' method$ +//This control construct may only be used if the computation expression builder defines a 'Yield' method$ type R = S of string diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs index 63ada5cd6b..3777c375f2 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingYieldFrom.fs @@ -1,6 +1,6 @@ // #Regression #Conformance #DataExpressions #ComputationExpressions // Regression test for FSHARP1.0:6149 -//This control construct may only be used if the computation expression builder defines a 'YieldFrom' method$ +//This control construct may only be used if the computation expression builder defines a 'YieldFrom' method$ type R = S of string diff --git a/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl b/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl index 72f8528c23..16e62c6c1a 100644 --- a/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl +++ b/tests/service/data/SyntaxTree/ComputationExpression/MultipleSynExprAndBangHaveRangeThatStartsAtAndAndEndsAfterExpression.fs.bsl @@ -39,10 +39,12 @@ ImplFile (5,4--5,24), { AndBangKeyword = (5,4--5,8) EqualsRange = (5,13--5,14) InKeyword = None })], - YieldOrReturn ((false, true), Ident bar, (6,4--6,14)), - (3,4--6,14), { LetOrUseBangKeyword = (3,4--3,8) - EqualsRange = Some (3,13--3,14) }), - (2,6--7,1)), (2,0--7,1)), (2,0--7,1))], PreXmlDocEmpty, [], - None, (2,0--7,1), { LeadingKeyword = None })], (true, true), + YieldOrReturn + ((false, true), Ident bar, (6,4--6,14), + { YieldOrReturnKeyword = (6,4--6,10) }), (3,4--6,14), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,13--3,14) }), (2,6--7,1)), + (2,0--7,1)), (2,0--7,1))], PreXmlDocEmpty, [], None, (2,0--7,1), + { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl b/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl index d0dd3083e6..9ee7e15f53 100644 --- a/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl +++ b/tests/service/data/SyntaxTree/ComputationExpression/SynExprAndBangRangeStartsAtAndAndEndsAfterExpression.fs.bsl @@ -28,10 +28,12 @@ ImplFile (5,4--5,24), { AndBangKeyword = (5,4--5,8) EqualsRange = (5,13--5,14) InKeyword = None })], - YieldOrReturn ((false, true), Ident bar, (7,4--7,14)), - (3,4--7,14), { LetOrUseBangKeyword = (3,4--3,8) - EqualsRange = Some (3,13--3,14) }), - (2,6--8,1)), (2,0--8,1)), (2,0--8,1))], PreXmlDocEmpty, [], - None, (2,0--8,1), { LeadingKeyword = None })], (true, true), + YieldOrReturn + ((false, true), Ident bar, (7,4--7,14), + { YieldOrReturnKeyword = (7,4--7,10) }), (3,4--7,14), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,13--3,14) }), (2,6--8,1)), + (2,0--8,1)), (2,0--8,1))], PreXmlDocEmpty, [], None, (2,0--8,1), + { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl index 7cc9b34884..517c835a63 100644 --- a/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/List - Comprehension 01.fs.bsl @@ -12,8 +12,9 @@ ImplFile Named (SynIdent (x, None), false, None, (3,6--3,7)), ArrayOrList (false, [], (3,11--3,13)), YieldOrReturn - ((true, false), Const (Unit, (3,17--3,19)), (3,14--3,19)), - (3,2--3,19)), (3,0--3,21)), (3,0--3,21))], + ((true, false), Const (Unit, (3,17--3,19)), (3,14--3,19), + { YieldOrReturnKeyword = (3,14--3,16) }), (3,2--3,19)), + (3,0--3,21)), (3,0--3,21))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--3,21), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl index 1a89da1b0f..9897592fb0 100644 --- a/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/List - Comprehension 02.fs.bsl @@ -15,7 +15,8 @@ ImplFile ((true, false), ArbitraryAfterError ("typedSequentialExprBlockR1", (3,16--3,16)), - (3,14--3,16)), (3,2--3,16)), (3,0--3,18)), (3,0--3,18))], + (3,14--3,16), { YieldOrReturnKeyword = (3,14--3,16) }), + (3,2--3,16)), (3,0--3,18)), (3,0--3,18))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--3,18), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl index 9d7e7af212..c3c454436c 100644 --- a/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Rarrow 01.fs.bsl @@ -5,8 +5,8 @@ ImplFile ([Module], false, NamedModule, [Expr (YieldOrReturn - ((true, true), Const (Int32 1, (3,3--3,4)), (3,0--3,4)), - (3,0--3,4))], + ((true, true), Const (Int32 1, (3,3--3,4)), (3,0--3,4), + { YieldOrReturnKeyword = (3,0--3,2) }), (3,0--3,4))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--3,4), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl index 54570b3872..3a0af63286 100644 --- a/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Rarrow 02.fs.bsl @@ -7,7 +7,7 @@ ImplFile (YieldOrReturn ((true, true), ArbitraryAfterError ("typedSequentialExprBlockR1", (3,2--3,2)), - (3,0--3,2)), (3,0--3,2))], + (3,0--3,2), { YieldOrReturnKeyword = (3,0--3,2) }), (3,0--3,2))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--3,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl index e0d4104ac0..ceae74bf09 100644 --- a/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/Rarrow 03.fs.bsl @@ -9,8 +9,9 @@ ImplFile YieldOrReturn ((true, true), ArbitraryAfterError - ("typedSequentialExprBlockR1", (3,5--3,5)), (3,3--3,5)), - (3,0--3,5)), (3,0--3,5))], + ("typedSequentialExprBlockR1", (3,5--3,5)), (3,3--3,5), + { YieldOrReturnKeyword = (3,3--3,5) }), (3,0--3,5), + { YieldOrReturnKeyword = (3,0--3,2) }), (3,0--3,5))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--3,5), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl index a0f5402982..0264686482 100644 --- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseBangContainsTheRangeOfTheEqualsSign.fs.bsl @@ -26,10 +26,11 @@ ImplFile EqualsRange = (4,11--4,12) InKeyword = None })], YieldOrReturn - ((false, true), Const (Unit, (5,11--5,13)), (5,4--5,13)), - (3,4--5,13), { LetOrUseBangKeyword = (3,4--3,8) - EqualsRange = Some (3,11--3,12) }), - (2,5--6,1)), (2,0--6,1)), (2,0--6,1))], PreXmlDocEmpty, [], - None, (2,0--6,1), { LeadingKeyword = None })], (true, true), + ((false, true), Const (Unit, (5,11--5,13)), (5,4--5,13), + { YieldOrReturnKeyword = (5,4--5,10) }), (3,4--5,13), + { LetOrUseBangKeyword = (3,4--3,8) + EqualsRange = Some (3,11--3,12) }), (2,5--6,1)), + (2,0--6,1)), (2,0--6,1))], PreXmlDocEmpty, [], None, (2,0--6,1), + { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl index 936525524f..deb6d27aa8 100644 --- a/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/WhileBang 01.fs.bsl @@ -13,8 +13,9 @@ ImplFile (false, YieldOrReturn ((false, true), Const (Bool true, (3,22--3,26)), - (3,15--3,26)), (3,13--3,28)), (3,7--3,28)), - Const (Int32 2, (4,4--4,5)), (3,0--4,5)), (3,0--4,5)); + (3,15--3,26), { YieldOrReturnKeyword = (3,15--3,21) }), + (3,13--3,28)), (3,7--3,28)), Const (Int32 2, (4,4--4,5)), + (3,0--4,5)), (3,0--4,5)); Expr (Const (Int32 3, (6,0--6,1)), (6,0--6,1))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--6,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl index b12f9b0df1..52eaca7bfd 100644 --- a/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/WhileBang 02.fs.bsl @@ -13,8 +13,9 @@ ImplFile (false, YieldOrReturn ((false, true), Const (Bool true, (3,22--3,26)), - (3,15--3,26)), (3,13--3,28)), (3,7--3,28)), - Const (Int32 2, (4,4--4,5)), (3,0--5,4)), (3,0--5,4)); + (3,15--3,26), { YieldOrReturnKeyword = (3,15--3,21) }), + (3,13--3,28)), (3,7--3,28)), Const (Int32 2, (4,4--4,5)), + (3,0--5,4)), (3,0--5,4)); Expr (Const (Int32 3, (7,0--7,1)), (7,0--7,1))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--7,1), { LeadingKeyword = Module (1,0--1,6) })], (true, true), diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl index a5793465b3..437c23a2c6 100644 --- a/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/WhileBang 03.fs.bsl @@ -20,7 +20,9 @@ ImplFile (false, YieldOrReturn ((false, true), Const (Bool true, (4,26--4,30)), - (4,19--4,30)), (4,17--4,32)), (4,11--4,32)), + (4,19--4,30), + { YieldOrReturnKeyword = (4,19--4,25) }), + (4,17--4,32)), (4,11--4,32)), ArbitraryAfterError ("whileBody1", (6,0--6,1)), (4,4--4,35)), (3,4--3,5), Yes (3,0--4,35), { LeadingKeyword = Let (3,0--3,3) InlineKeyword = None diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl index 863c8aaabf..70db990cb0 100644 --- a/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/WhileBang 04.fs.bsl @@ -20,7 +20,9 @@ ImplFile (false, YieldOrReturn ((false, true), Const (Bool true, (4,26--4,30)), - (4,19--4,30)), (4,17--4,32)), (4,11--4,32)), + (4,19--4,30), + { YieldOrReturnKeyword = (4,19--4,25) }), + (4,17--4,32)), (4,11--4,32)), ArbitraryAfterError ("whileBody1", (5,0--5,0)), (4,4--4,35)), (3,4--3,5), Yes (3,0--4,35), { LeadingKeyword = Let (3,0--3,3) InlineKeyword = None diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl index e2f5875ef4..a8b4a21543 100644 --- a/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/WhileBang 05.fs.bsl @@ -20,7 +20,9 @@ ImplFile (false, YieldOrReturn ((false, true), Const (Bool true, (4,26--4,30)), - (4,19--4,30)), (4,17--4,32)), (4,11--4,32)), + (4,19--4,30), + { YieldOrReturnKeyword = (4,19--4,25) }), + (4,17--4,32)), (4,11--4,32)), Const (Int32 2, (5,8--5,9)), (4,4--5,9)), (3,4--3,5), Yes (3,0--5,9), { LeadingKeyword = Let (3,0--3,3) InlineKeyword = None diff --git a/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl b/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl index 3c8ef1cbeb..df87ceb6a9 100644 --- a/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl +++ b/tests/service/data/SyntaxTree/Expression/WhileBang 06.fs.bsl @@ -20,7 +20,9 @@ ImplFile (false, YieldOrReturn ((false, true), Const (Bool true, (4,26--4,30)), - (4,19--4,30)), (4,17--4,32)), (4,11--4,32)), + (4,19--4,30), + { YieldOrReturnKeyword = (4,19--4,25) }), + (4,17--4,32)), (4,11--4,32)), Const (Int32 2, (5,4--5,5)), (4,4--5,5)), (3,4--3,5), Yes (3,0--5,5), { LeadingKeyword = Let (3,0--3,3) InlineKeyword = None diff --git a/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs b/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs index cbc22219a1..ec37655270 100644 --- a/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs +++ b/vsintegration/src/FSharp.Editor/CodeFixes/RemoveReturnOrYield.fs @@ -30,7 +30,11 @@ type internal RemoveReturnOrYieldCodeFixProvider [] () = parseResults.TryRangeOfExprInYieldOrReturn errorRange.Start |> ValueOption.ofOption |> ValueOption.map (fun exprRange -> RoslynHelpers.FSharpRangeToTextSpan(sourceText, exprRange)) - |> ValueOption.map (fun exprSpan -> [ TextChange(context.Span, sourceText.GetSubText(exprSpan).ToString()) ]) + |> ValueOption.map (fun exprSpan -> + [ + // meaning: keyword + spacing before the expression + TextChange(TextSpan(context.Span.Start, exprSpan.Start - context.Span.Start), "") + ]) |> ValueOption.map (fun changes -> let title = let text = sourceText.GetSubText(context.Span).ToString() diff --git a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs index 23d5908d55..a93bd4f6a3 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CodeFixes/RemoveReturnOrYieldTests.fs @@ -102,3 +102,50 @@ let answer question = let actual = codeFix |> tryFix code Auto Assert.Equal(expected, actual) + +[] +let ``Handles spaces`` () = + let code = + """ +let answer question = + yield 42 +""" + + let expected = + Some + { + Message = "Remove 'yield'" + FixedCode = + """ +let answer question = + 42 +""" + } + + let actual = codeFix |> tryFix code Auto + + Assert.Equal(expected, actual) + +[] +let ``Handles new lines`` () = + let code = + """ +let answer question = + return! + 42 +""" + + let expected = + Some + { + Message = "Remove 'return!'" + FixedCode = + """ +let answer question = + 42 +""" + } + + let actual = codeFix |> tryFix code Auto + + Assert.Equal(expected, actual)