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 28f20ca2be2..fe3cde0444a 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
@@ -18,5 +18,6 @@
* 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))
+* Better ranges for CE `use` error reporting. ([PR #17811](https://github.com/dotnet/fsharp/pull/17811))
### Breaking Changes
diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
index c1aa4dafc5d..645897a6793 100644
--- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
@@ -1805,11 +1805,8 @@ let rec TryTranslateComputationExpression
| SynExpr.LetOrUse(
isUse = true
bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ]
- body = innerComp) ->
- let mBind =
- match spBind with
- | DebugPointAtBinding.Yes m -> m
- | _ -> rhsExpr.Range
+ body = innerComp
+ trivia = { LetOrUseKeyword = mBind }) ->
if ceenv.isQuery then
error (Error(FSComp.SR.tcUseMayNotBeUsedInQueries (), mBind))
diff --git a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
index 781060c8af4..3154d3e1e74 100644
--- a/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
@@ -232,9 +232,10 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
// 'use x = expr in expr'
| SynExpr.LetOrUse(
isUse = true
- bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ]
+ bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr) ]
body = innerComp
- range = wholeExprMark) ->
+ range = wholeExprMark
+ trivia = { LetOrUseKeyword = mBind }) ->
let bindPatTy = NewInferenceType g
let inputExprTy = NewInferenceType g
@@ -252,11 +253,6 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
let envinner = { envinner with eIsControlFlow = true }
tcSequenceExprBody envinner genOuterTy tpenv innerComp
- let mBind =
- match spBind with
- | DebugPointAtBinding.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Binding)
- | _ -> inputExpr.Range
-
let inputExprMark = inputExpr.Range
let matchv, matchExpr =
diff --git a/src/Compiler/Service/service.fs b/src/Compiler/Service/service.fs
index 525faf3be3d..5f6588bd770 100644
--- a/src/Compiler/Service/service.fs
+++ b/src/Compiler/Service/service.fs
@@ -72,10 +72,10 @@ module CompileHelpers =
try
f exiter
- 0
+ None
with e ->
stopProcessingRecovery e range0
- 1
+ Some e
/// Compile using the given flags. Source files names are resolved via the FileSystem API. The output file must be given by a -o flag.
let compileFromArgs (ctok, argv: string[], legacyReferenceResolver, tcImportsCapture, dynamicAssemblyCreator) =
diff --git a/src/Compiler/Service/service.fsi b/src/Compiler/Service/service.fsi
index 0e48a0d6360..3e4fde2229c 100644
--- a/src/Compiler/Service/service.fsi
+++ b/src/Compiler/Service/service.fsi
@@ -400,11 +400,12 @@ type public FSharpChecker =
/// Compile using the given flags. Source files names are resolved via the FileSystem API.
/// The output file must be given by a -o flag.
/// The first argument is ignored and can just be "fsc.exe".
+ /// The method returns the collected diagnostics, and (possibly) a terminating exception.
///
///
/// The command line arguments for the project build.
/// An optional string used for tracing compiler operations associated with this request.
- member Compile: argv: string[] * ?userOpName: string -> Async
+ member Compile: argv: string[] * ?userOpName: string -> Async
///
/// Try to get type check results for a file. This looks up the results of recent type checks of the
diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs
index 8d62a724972..1d26a1b2ba9 100644
--- a/src/Compiler/SyntaxTree/ParseHelpers.fs
+++ b/src/Compiler/SyntaxTree/ParseHelpers.fs
@@ -1049,7 +1049,22 @@ let mkLocalBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs,
else
Some mIn)
- SynExpr.LetOrUse(isRec, isUse, decls, body, mWhole, { InKeyword = mIn })
+ let mLetOrUse =
+ match decls with
+ | SynBinding(trivia = trivia) :: _ -> trivia.LeadingKeyword.Range
+ | _ -> Range.Zero
+
+ SynExpr.LetOrUse(
+ isRec,
+ isUse,
+ decls,
+ body,
+ mWhole,
+ {
+ LetOrUseKeyword = mLetOrUse
+ InKeyword = mIn
+ }
+ )
let mkDefnBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) =
if isUse then
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
index 10aee262292..6a550c3b1a8 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
@@ -85,10 +85,15 @@ type SynExprDotLambdaTrivia =
[]
type SynExprLetOrUseTrivia =
{
+ LetOrUseKeyword: range
InKeyword: range option
}
- static member Zero: SynExprLetOrUseTrivia = { InKeyword = None }
+ static member Zero: SynExprLetOrUseTrivia =
+ {
+ InKeyword = None
+ LetOrUseKeyword = Range.Zero
+ }
[]
type SynExprLetOrUseBangTrivia =
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
index fff834beb41..f16294b0a1d 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
@@ -129,6 +129,8 @@ type SynExprDotLambdaTrivia =
[]
type SynExprLetOrUseTrivia =
{
+ /// The syntax range of the `let` or `use` keyword.
+ LetOrUseKeyword: range
/// The syntax range of the `in` keyword.
InKeyword: range option
}
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs
new file mode 100644
index 00000000000..99d019504d6
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Ifdef.fs
@@ -0,0 +1,57 @@
+namespace CompilerDirectives
+
+open Xunit
+open FSharp.Test.Compiler
+
+module Ifdef =
+
+ let ifdefSource = """
+[]
+let main _ =
+ #if MYDEFINE1
+ 1
+ #else
+ 2
+ #endif
+"""
+
+ []
+ []
+ []
+ let ifdefTest (mydefine, expectedExitCode) =
+
+ FSharp ifdefSource
+ |> withDefines [mydefine]
+ |> compileExeAndRun
+ |> withExitCode expectedExitCode
+
+
+ let sourceExtraEndif = """
+#if MYDEFINE1
+printf "1"
+#endif
+(**)#endif(**)
+0
+"""
+
+ []
+ let extraEndif () =
+
+ FSharp sourceExtraEndif
+ |> withDefines ["MYDEFINE1"]
+ |> asExe
+ |> compile
+ |> withDiagnosticMessage "#endif has no matching #if in implementation file"
+
+ let sourceUnknownHash = """
+module A
+#ifxx
+#abc
+"""
+
+ []
+ let unknownHashDirectiveIsIgnored () =
+
+ FSharp sourceUnknownHash
+ |> compile
+ |> shouldSucceed
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
index b3c33031acb..c560008da0c 100644
--- a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs
@@ -45,7 +45,6 @@ else ()
|> compile
|> run
|> shouldSucceed
- |> withExitCode 0
[]
let ``Respect nowarn 957 for extension method`` () =
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs
index d2dc41a3235..1477db7754c 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs
@@ -176,37 +176,118 @@ let [] x = System.Int32.MaxValue + 1
}
[]
- let ``Arithmetic can be used for constructing decimal literals``() =
+ let ``Decimal literals are properly initialized``() =
FSharp """
-module LiteralArithmetic
+module DecimalInit
[]
-let x = 1m + 2m
+let x = 5.5m
"""
|> withLangVersion80
|> compile
|> shouldSucceed
|> verifyIL [
- """.field public static initonly valuetype [runtime]System.Decimal x"""
- """.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ """
+.class public abstract auto ansi sealed DecimalInit
+ extends [runtime]System.Object
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .field public static initonly valuetype [runtime]System.Decimal x
+ .custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
uint8,
int32,
int32,
- int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00
- 00 00 )"""
- """.maxstack 8"""
- """IL_0000: ldc.i4.3"""
- """IL_0001: ldc.i4.0"""
- """IL_0002: ldc.i4.0"""
- """IL_0003: ldc.i4.0"""
- """IL_0004: ldc.i4.0"""
- """IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32,
+ int32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 37 00 00 00
+ 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 ''.$DecimalInit::init@
+ IL_0006: ldsfld int32 ''.$DecimalInit::init@
+ IL_000b: pop
+ IL_000c: ret
+ }
+
+ .method assembly specialname static void staticInitialization@() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldc.i4.s 55
+ IL_0002: ldc.i4.0
+ IL_0003: ldc.i4.0
+ IL_0004: ldc.i4.0
+ IL_0005: ldc.i4.1
+ IL_0006: newobj instance void [runtime]System.Decimal::.ctor(int32,
int32,
int32,
bool,
- uint8)"""
- """IL_000a: stsfld valuetype [runtime]System.Decimal LiteralArithmetic::x"""
- """IL_000f: ret"""
+ uint8)
+ IL_000b: stsfld valuetype [runtime]System.Decimal DecimalInit::x
+ IL_0010: ret
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$DecimalInit
+ extends [runtime]System.Object
+{
+ .field static assembly int32 init@
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
+ .method private specialname rtspecialname static void .cctor() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: call void DecimalInit::staticInitialization@()
+ IL_0005: ret
+ }
+
+}
+"""
+ ]
+
+ []
+ let ``Arithmetic can be used for constructing decimal literals``() =
+ FSharp """
+module LiteralArithmetic
+
+[]
+let x = 1m + 2m
+ """
+ |> withLangVersion80
+ |> compile
+ |> shouldSucceed
+ |> verifyIL [
+ """.field public static initonly valuetype [runtime]System.Decimal x
+.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ uint8,
+ int32,
+ int32,
+ int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00
+ 00 00 )"""
+ """
+.method assembly specialname static void staticInitialization@() cil managed
+{
+
+.maxstack 8
+IL_0000: ldc.i4.3
+IL_0001: ldc.i4.0
+IL_0002: ldc.i4.0
+IL_0003: ldc.i4.0
+IL_0004: ldc.i4.0
+IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)
+IL_000a: stsfld valuetype [runtime]System.Decimal LiteralArithmetic::x
+IL_000f: ret
+}
+"""
]
[]
@@ -226,28 +307,45 @@ let test () =
|> compile
|> shouldSucceed
|> verifyIL [
- """.field public static initonly valuetype [runtime]System.Decimal x"""
- """ .custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
- uint8,
- int32,
- int32,
- int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00
- 00 00 )"""
- """IL_0016: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal,
- valuetype [netstandard]System.Decimal)"""
- """.maxstack 8"""
- """IL_0000: ldc.i4.5"""
- """IL_0001: ldc.i4.0"""
- """IL_0002: ldc.i4.0"""
- """IL_0003: ldc.i4.0"""
- """IL_0004: ldc.i4.0"""
- """IL_0005: newobj instance void [runtime]System.Decimal::.ctor(int32,
- int32,
- int32,
- bool,
- uint8)"""
- """IL_000a: stsfld valuetype [runtime]System.Decimal PatternMatch::x"""
- """IL_000f: ret"""
+ """
+.field public static initonly valuetype [runtime]System.Decimal x
+.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ uint8,
+ int32,
+ int32,
+ int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00
+ 00 00 )"""
+ """
+.method public static int32 test() cil managed
+ {
+
+.maxstack 8
+.locals init (valuetype [runtime]System.Decimal V_0)
+IL_0000: ldc.i4.5
+IL_0001: ldc.i4.0
+IL_0002: ldc.i4.0
+IL_0003: ldc.i4.0
+IL_0004: ldc.i4.0
+IL_0005: newobj instance void [netstandard]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)
+IL_000a: stloc.0
+IL_000b: ldloc.0
+IL_000c: ldc.i4.5
+IL_000d: ldc.i4.0
+IL_000e: ldc.i4.0
+IL_000f: ldc.i4.0
+IL_0010: ldc.i4.0
+IL_0011: newobj instance void [netstandard]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)
+IL_0016: call bool [netstandard]System.Decimal::op_Equality(valuetype [netstandard]System.Decimal,
+ valuetype [netstandard]System.Decimal)
+ """
]
[]
@@ -264,6 +362,56 @@ let y = 42m
|> withLangVersion80
|> compile
|> shouldSucceed
+ |> verifyIL [
+ """
+.field public static initonly valuetype [runtime]System.Decimal x
+.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ uint8,
+ int32,
+ int32,
+ int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 29 00 00 00
+ 00 00 )
+"""
+ """
+.field public static initonly valuetype [runtime]System.Decimal y
+.custom instance void [runtime]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,
+ uint8,
+ int32,
+ int32,
+ int32) = ( 01 00 00 00 00 00 00 00 00 00 00 00 2A 00 00 00
+ 00 00 )
+"""
+ """
+.method assembly specialname static void staticInitialization@() cil managed
+{
+
+.maxstack 8
+IL_0000: ldc.i4.s 41
+IL_0002: ldc.i4.0
+IL_0003: ldc.i4.0
+IL_0004: ldc.i4.0
+IL_0005: ldc.i4.0
+IL_0006: newobj instance void [runtime]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)
+IL_000b: stsfld valuetype [runtime]System.Decimal DecimalLiterals::x
+IL_0010: ldc.i4.s 42
+IL_0012: ldc.i4.0
+IL_0013: ldc.i4.0
+IL_0014: ldc.i4.0
+IL_0015: ldc.i4.0
+IL_0016: newobj instance void [runtime]System.Decimal::.ctor(int32,
+ int32,
+ int32,
+ bool,
+ uint8)
+IL_001b: stsfld valuetype [runtime]System.Decimal DecimalLiterals::y
+IL_0020: ret
+}
+"""
+ ]
[]
let ``Compilation fails when using arithmetic with a non-literal in literal``() =
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs
index 9a43d34d429..1e5187167a7 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/TryCatch/TryCatch.fs
@@ -56,9 +56,9 @@ let ``Stackoverflow reproduction`` compilation =
| CompilationResult.Success ({OutputPath = Some dllFile} as s) ->
let fsharpCoreFile = typeof>.Assembly.Location
File.Copy(fsharpCoreFile, Path.Combine(Path.GetDirectoryName(dllFile), Path.GetFileName(fsharpCoreFile)), true)
- let exitCode, _stdout, _stderr = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true)
+ let _exitCode, _stdout, stderr, _exn = CompilerAssert.ExecuteAndReturnResult (dllFile, isFsx=false, deps = s.Dependencies, newProcess=true)
- Assert.NotEqual(0,exitCode)
+ Assert.True(stderr.Contains "stack overflow" || stderr.Contains "StackOverflow")
| _ -> failwith (sprintf "%A" compilationResult)
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 4b50b28aa12..4ddec1e3405 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -33,6 +33,7 @@
+
diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
index 9d276c13629..3555e97fd2d 100644
--- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs
@@ -644,4 +644,85 @@ let indexHandler (): Task =
'string'
but here has type
'Task' ")
+ ]
+
+ []
+ let ``use expressions may not be used in queries(SynExpr.Sequential)`` () =
+ Fsx """
+let x11 =
+ query { for c in [1..10] do
+ use x = { new System.IDisposable with __.Dispose() = () }
+ yield 1 }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3142, Line 4, Col 13, Line 4, Col 16, "'use' expressions may not be used in queries")
+ ]
+
+ []
+ let ``use, This control construct may only be used if the computation expression builder defines a 'Using' 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 _.YieldReturn(x: Result<'T,'U>) = x
+ member _.Return(x: 'T) = Ok x
+
+let result = ResultBuilder()
+
+let run r2 r3 =
+ result {
+ use b = r2
+ return Ok 0
+ }
+ """
+ |> ignoreWarnings
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 708, Line 20, Col 9, Line 20, Col 12, "This control construct may only be used if the computation expression builder defines a 'Using' method")
+ ]
+
+ []
+ let ``This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.`` () =
+ Fsx """
+let x18rec2 =
+ query {
+ for d in [1..10] do
+ let rec f x = x + 1 // error expected here - no recursive functions
+ and g x = f x + 2
+ select (f d)
+ }
+
+let x18inline =
+ query {
+ for d in [1..10] do
+ let inline f x = x + 1 // error expected here - no inline functions
+ select (f d)
+ }
+
+let x18mutable =
+ query {
+ for d in [1..10] do
+ let mutable v = 1 // error expected here - no mutable values
+ select (f d)
+ }
+
+ """
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3147, Line 5, Col 17, Line 5, Col 20, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.")
+ (Error 3147, Line 13, Col 20, Line 13, Col 23, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.")
+ (Error 3147, Line 20, Col 21, Line 20, Col 22, "This 'let' definition may not be used in a query. Only simple value definitions may be used in queries.")
]
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs
index 9cfbbb9df80..294db344223 100644
--- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/CompilationFromCmdlineArgsTests.fs
@@ -38,12 +38,12 @@ module CompilationFromCmdlineArgsTests =
yield! methodOptions method
|]
- let diagnostics, exitCode = checker.Compile(args) |> Async.RunSynchronously
+ let diagnostics, exn = checker.Compile(args) |> Async.RunSynchronously
for diag in diagnostics do
printfn "%A" diag
- Assert.Equal(exitCode, 0)
+ Assert.Equal(exn, None)
finally
Environment.CurrentDirectory <- oldWorkDir
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 42ec38ee366..15e1dd848e6 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
@@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
-FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
+FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked
@@ -10231,7 +10231,9 @@ FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.SyntaxTrivia
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InKeyword
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword()
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: System.String ToString()
-FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range LetOrUseKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range get_LetOrUseKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range MatchBangKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range WithKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range get_MatchBangKeyword()
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 42ec38ee366..15e1dd848e6 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
@@ -2166,7 +2166,7 @@ FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults,FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.CodeAnalysis.ProjectSnapshot+FSharpProjectSnapshot,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Diagnostics.FSharpDiagnostic]]] GetProjectSnapshotFromScript(System.String, FSharp.Compiler.Text.ISourceTextNew, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.DocumentSource], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String])
-FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
+FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Diagnostics.FSharpDiagnostic[],Microsoft.FSharp.Core.FSharpOption`1[System.Exception]]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.CodeAnalysis.FSharpParsingOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.Text.Range,FSharp.Compiler.Text.Range][]] MatchBraces(System.String, System.String, FSharp.Compiler.CodeAnalysis.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpChecker: Microsoft.FSharp.Control.IEvent`2[Microsoft.FSharp.Control.FSharpHandler`1[FSharp.Compiler.CodeAnalysis.FSharpProjectOptions],FSharp.Compiler.CodeAnalysis.FSharpProjectOptions] ProjectChecked
@@ -10231,7 +10231,9 @@ FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.SyntaxTrivia
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InKeyword
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword()
FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: System.String ToString()
-FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range LetOrUseKeyword
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: FSharp.Compiler.Text.Range get_LetOrUseKeyword()
+FSharp.Compiler.SyntaxTrivia.SynExprLetOrUseTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range MatchBangKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range WithKeyword
FSharp.Compiler.SyntaxTrivia.SynExprMatchBangTrivia: FSharp.Compiler.Text.Range get_MatchBangKeyword()
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index f535bc21c5a..5e5629b089f 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -170,10 +170,13 @@ module rec Compiler =
Message: string
SubCategory: string }
+ // This type is used either for the output of the compiler (typically in CompilationResult coming from 'compile')
+ // or for the output of the code generated by the compiler (in CompilationResult coming from 'run')
type ExecutionOutput =
- { ExitCode: int
+ { ExitCode: int option
StdOut: string
- StdErr: string }
+ StdErr: string
+ Exn: exn option }
type RunOutput =
| EvalOutput of Result
@@ -699,7 +702,7 @@ module rec Compiler =
let private compileFSharpCompilation compilation ignoreWarnings (cUnit: CompilationUnit) : CompilationResult =
use redirect = new RedirectConsole()
- let ((err: FSharpDiagnostic[], rc: int, outputFilePath: string), deps) =
+ let ((err: FSharpDiagnostic[], exn, outputFilePath: string), deps) =
CompilerAssert.CompileRaw(compilation, ignoreWarnings)
// Create and stash the console output
@@ -711,7 +714,7 @@ module rec Compiler =
Adjust = 0
PerFileErrors = diagnostics
Diagnostics = diagnostics |> List.map snd
- Output = Some (RunOutput.ExecutionOutput { ExitCode = rc; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput() })
+ Output = Some (RunOutput.ExecutionOutput { ExitCode = None; StdOut = redirect.Output(); StdErr = redirect.ErrorOutput(); Exn = exn })
Compilation = cUnit
}
@@ -978,14 +981,13 @@ module rec Compiler =
| SourceCodeFileKind.Fsx _ -> true
| _ -> false
| _ -> false
- let exitCode, output, errors = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
+ let exitCode, output, errors, exn = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
printfn "---------output-------\n%s\n-------" output
printfn "---------errors-------\n%s\n-------" errors
- let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) }
- if exitCode = 0 then
- CompilationResult.Success executionResult
- else
- CompilationResult.Failure executionResult
+ let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors; Exn = exn }) }
+ match exn with
+ | None -> CompilationResult.Success executionResult
+ | Some _ -> CompilationResult.Failure executionResult
let compileAndRun = compile >> run
@@ -1080,27 +1082,25 @@ module rec Compiler =
opts.ToArray()
let errors, stdOut = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
- let executionOutputwithStdOut: RunOutput option =
- ExecutionOutput { StdOut = stdOut; ExitCode = 0; StdErr = "" }
- |> Some
- let result =
+ let mkResult output =
{ OutputPath = None
Dependencies = []
Adjust = 0
Diagnostics = []
PerFileErrors= []
- Output = executionOutputwithStdOut
+ Output = Some output
Compilation = cUnit }
-
- if errors.Count > 0 then
- let output = ExecutionOutput {
- ExitCode = -1
- StdOut = String.Empty
- StdErr = ((errors |> String.concat "\n").Replace("\r\n","\n")) }
- CompilationResult.Failure { result with Output = Some output }
+
+ if errors.Count = 0 then
+ let output =
+ ExecutionOutput { ExitCode = None; StdOut = stdOut; StdErr = ""; Exn = None }
+ CompilationResult.Success (mkResult output)
else
- CompilationResult.Success result
-
+ let err = (errors |> String.concat "\n").Replace("\r\n","\n")
+ let output =
+ ExecutionOutput {ExitCode = None; StdOut = String.Empty; StdErr = err; Exn = None }
+ CompilationResult.Failure (mkResult output)
+
finally
disposals
|> Seq.iter (fun x -> x.Dispose())
@@ -1190,7 +1190,7 @@ Actual:
| Some p ->
match ILChecker.verifyILAndReturnActual [] p expected with
| true, _, _ -> result
- | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput { StdOut = errorMsg; ExitCode = 0; StdErr = "" })} )
+ | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput {ExitCode = None; StdOut = errorMsg; StdErr = ""; Exn = None })} )
| CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}"
@@ -1706,7 +1706,7 @@ Actual:
| None -> failwith "Execution output is missing, cannot check exit code."
| Some o ->
match o with
- | ExecutionOutput e -> Assert.Equal(expectedExitCode, e.ExitCode)
+ | ExecutionOutput {ExitCode = Some exitCode} -> Assert.Equal(expectedExitCode, exitCode)
| _ -> failwith "Cannot check exit code on this run result."
result
diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs
index fc2875d8955..37a8e25e164 100644
--- a/tests/FSharp.Test.Utilities/CompilerAssert.fs
+++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs
@@ -322,7 +322,7 @@ module rec CompilerAssertHelpers =
else
entryPoint
let args = mkDefaultArgs entryPoint
- captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args) |> ignore)
+ captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args))
#if NETCOREAPP
let executeBuiltApp assembly deps isFsx =
@@ -409,8 +409,8 @@ module rec CompilerAssertHelpers =
// Generate a response file, purely for diagnostic reasons.
File.WriteAllLines(Path.ChangeExtension(outputFilePath, ".rsp"), args)
- let errors, rc = checker.Compile args |> Async.RunImmediate
- errors, rc, outputFilePath
+ let errors, ex = checker.Compile args |> Async.RunImmediate
+ errors, ex, outputFilePath
let compileDisposable (outputDirectory:DirectoryInfo) isExe options targetFramework nameOpt (sources:SourceCodeFileKind list) =
let disposeFile path =
@@ -537,7 +537,7 @@ module rec CompilerAssertHelpers =
let tmp = Path.Combine(outputPath.FullName, Path.ChangeExtension(fileName, ".dll"))
disposals.Add({ new IDisposable with member _.Dispose() = File.Delete tmp })
cmpl.EmitAsFile tmp
- (([||], 0, tmp), []), false)
+ (([||], None, tmp), []), false)
let compilationRefs =
compiledRefs
@@ -559,7 +559,7 @@ module rec CompilerAssertHelpers =
compilationRefs, deps
- let compileCompilationAux outputDirectory (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * int * string) * string list =
+ let compileCompilationAux outputDirectory (disposals: ResizeArray) ignoreWarnings (cmpl: Compilation) : (FSharpDiagnostic[] * exn option * string) * string list =
let compilationRefs, deps = evaluateReferences outputDirectory disposals ignoreWarnings cmpl
let isExe, sources, options, targetFramework, name =
@@ -604,7 +604,7 @@ module rec CompilerAssertHelpers =
outputDirectory.Create()
compileCompilationAux outputDirectory (ResizeArray()) ignoreWarnings cmpl
- let captureConsoleOutputs (func: unit -> unit) =
+ let captureConsoleOutputs (func: unit -> obj) =
let out = Console.Out
let err = Console.Error
@@ -614,29 +614,30 @@ module rec CompilerAssertHelpers =
use outWriter = new StringWriter (stdout)
use errWriter = new StringWriter (stderr)
- let succeeded, exn =
+ let rc, exn =
try
try
Console.SetOut outWriter
Console.SetError errWriter
- func ()
- true, None
+ let rc = func()
+ match rc with
+ | :? int as rc -> Some rc, None
+ | _ -> None, None
with e ->
let errorMessage = if e.InnerException <> null then e.InnerException.ToString() else e.ToString()
stderr.Append errorMessage |> ignore
- false, Some e
+ None, Some e
finally
Console.SetOut out
Console.SetError err
outWriter.Close()
errWriter.Close()
- succeeded, stdout.ToString(), stderr.ToString(), exn
+ rc, stdout.ToString(), stderr.ToString(), exn
- let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int * string * string) =
- let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps isFsx
- let exitCode = if succeeded then 0 else -1
- exitCode, stdout, stderr
+ let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int option * string * string * exn option) =
+ let rc, stdout, stderr, exn = executeBuiltApp outputFilePath deps isFsx
+ rc, stdout, stderr, exn
let executeBuiltAppNewProcessAndReturnResult (outputFilePath: string) : (int * string * string) =
#if !NETCOREAPP
@@ -663,7 +664,7 @@ module rec CompilerAssertHelpers =
member _.Dispose() = try File.Delete runtimeconfigPath with | _ -> () }
#endif
let timeout = 30000
- let exitCode, output, errors = Commands.executeProcess (Some fileName) arguments (Path.GetDirectoryName(outputFilePath)) timeout
+ let exitCode, output, errors = Commands.executeProcess fileName arguments (Path.GetDirectoryName(outputFilePath)) timeout
(exitCode, output |> String.concat "\n", errors |> String.concat "\n")
open CompilerAssertHelpers
@@ -677,7 +678,7 @@ type CompilerAssert private () =
if errors.Length > 0 then
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors)
- executeBuiltApp outputExe [] false |> ignore
+ executeBuiltApp outputExe [] false |> ignore
)
static let compileLibraryAndVerifyILWithOptions options (source: SourceCodeFileKind) (f: ILVerifier -> unit) =
@@ -739,11 +740,13 @@ Updated automatically, please check diffs in your pull request, changes must be
returnCompilation cmpl (defaultArg ignoreWarnings false)
static member ExecuteAndReturnResult (outputFilePath: string, isFsx: bool, deps: string list, newProcess: bool) =
- // If we execute in-process (true by default), then the only way of getting STDOUT is to redirect it to SB, and STDERR is from catching an exception.
if not newProcess then
- executeBuiltAppAndReturnResult outputFilePath deps isFsx
+ let entryPointReturnCode, deps, isFsx, exn = executeBuiltAppAndReturnResult outputFilePath deps isFsx
+ entryPointReturnCode, deps, isFsx, exn
else
- executeBuiltAppNewProcessAndReturnResult outputFilePath
+ let processExitCode, deps, isFsx = executeBuiltAppNewProcessAndReturnResult outputFilePath
+ Some processExitCode, deps, isFsx, None
+
static member Execute(cmpl: Compilation, ?ignoreWarnings, ?beforeExecute, ?newProcess, ?onOutput) =
@@ -767,7 +770,7 @@ Updated automatically, please check diffs in your pull request, changes must be
Assert.Fail errors
onOutput output
else
- let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false
+ let _rc, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false
exn |> Option.iter raise)
static member ExecutionHasOutput(cmpl: Compilation, expectedOutput: string) =
diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs
index 4474ef01c10..de0fbd8050b 100644
--- a/tests/FSharp.Test.Utilities/ILChecker.fs
+++ b/tests/FSharp.Test.Utilities/ILChecker.fs
@@ -16,7 +16,7 @@ module ILChecker =
let private exec exe args =
let arguments = args |> String.concat " "
let timeout = 30000
- let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout
+ let exitCode, _output, errors = Commands.executeProcess exe arguments "" timeout
let errors = errors |> String.concat Environment.NewLine
errors, exitCode
diff --git a/tests/FSharp.Test.Utilities/Peverifier.fs b/tests/FSharp.Test.Utilities/Peverifier.fs
index 35db5b208fb..f3ccc7de2b1 100644
--- a/tests/FSharp.Test.Utilities/Peverifier.fs
+++ b/tests/FSharp.Test.Utilities/Peverifier.fs
@@ -25,7 +25,7 @@ module PEVerifier =
let private exec exe args =
let arguments = args |> String.concat " "
let timeout = 30000
- let exitCode, _output, errors = Commands.executeProcess (Some exe) arguments "" timeout
+ let exitCode, _output, errors = Commands.executeProcess exe arguments "" timeout
let errors = errors |> String.concat Environment.NewLine
errors, exitCode
diff --git a/tests/FSharp.Test.Utilities/ProjectGeneration.fs b/tests/FSharp.Test.Utilities/ProjectGeneration.fs
index 78feb049435..a75784240dd 100644
--- a/tests/FSharp.Test.Utilities/ProjectGeneration.fs
+++ b/tests/FSharp.Test.Utilities/ProjectGeneration.fs
@@ -1360,9 +1360,8 @@ type ProjectWorkflowBuilder
yield! projectOptions.OtherOptions
yield! projectOptions.SourceFiles
|]
- let! _diagnostics, exitCode = checker.Compile(arguments)
- if exitCode <> 0 then
- exn $"Compilation failed with exit code {exitCode}" |> raise
+ let! _diagnostics, ex = checker.Compile(arguments)
+ if ex.IsSome then raise ex.Value
return ctx
}
diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs
index 6e1611beb5c..dfde63f2352 100644
--- a/tests/FSharp.Test.Utilities/TestFramework.fs
+++ b/tests/FSharp.Test.Utilities/TestFramework.fs
@@ -63,69 +63,66 @@ module Commands =
// Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever
// returns exit code, stdio and stderr as string arrays
let executeProcess pathToExe arguments workingDir (timeout:int) =
- match pathToExe with
- | Some path ->
- let commandLine = ResizeArray()
- let errorsList = ResizeArray()
- let outputList = ResizeArray()
- let errorslock = obj()
- let outputlock = obj()
- let outputDataReceived (message: string) =
- if not (isNull message) then
- lock outputlock (fun () -> outputList.Add(message))
-
- let errorDataReceived (message: string) =
- if not (isNull message) then
- lock errorslock (fun () -> errorsList.Add(message))
-
- commandLine.Add $"cd {workingDir}"
- commandLine.Add $"{path} {arguments} /bl"
-
- let psi = ProcessStartInfo()
- psi.FileName <- path
- psi.WorkingDirectory <- workingDir
- psi.RedirectStandardOutput <- true
- psi.RedirectStandardError <- true
- psi.Arguments <- arguments
- psi.CreateNoWindow <- true
- // When running tests, we want to roll forward to minor versions (including previews).
- psi.EnvironmentVariables["DOTNET_ROLL_FORWARD"] <- "LatestMajor"
- psi.EnvironmentVariables["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1"
- psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things
- psi.UseShellExecute <- false
-
- use p = new Process()
- p.StartInfo <- psi
-
- p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data)
- p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data)
-
- if p.Start() then
- p.BeginOutputReadLine()
- p.BeginErrorReadLine()
- if not(p.WaitForExit(timeout)) then
- // Timed out resolving throw a diagnostic.
- raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments)))
- else
- p.WaitForExit()
- #if DEBUG
- let workingDir' =
- if workingDir = ""
- then
- // Assign working dir to prevent default to C:\Windows\System32
- let executionLocation = Assembly.GetExecutingAssembly().Location
- Path.GetDirectoryName executionLocation
- else
- workingDir
-
- lock gate (fun () ->
- File.WriteAllLines(Path.Combine(workingDir', "commandline.txt"), commandLine)
- File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList)
- File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList)
- )
- #endif
- p.ExitCode, outputList.ToArray(), errorsList.ToArray()
- | None -> -1, Array.empty, Array.empty
+ let commandLine = ResizeArray()
+ let errorsList = ResizeArray()
+ let outputList = ResizeArray()
+ let errorslock = obj()
+ let outputlock = obj()
+ let outputDataReceived (message: string) =
+ if not (isNull message) then
+ lock outputlock (fun () -> outputList.Add(message))
+
+ let errorDataReceived (message: string) =
+ if not (isNull message) then
+ lock errorslock (fun () -> errorsList.Add(message))
+
+ commandLine.Add $"cd {workingDir}"
+ commandLine.Add $"{pathToExe} {arguments} /bl"
+
+ let psi = ProcessStartInfo()
+ psi.FileName <- pathToExe
+ psi.WorkingDirectory <- workingDir
+ psi.RedirectStandardOutput <- true
+ psi.RedirectStandardError <- true
+ psi.Arguments <- arguments
+ psi.CreateNoWindow <- true
+ // When running tests, we want to roll forward to minor versions (including previews).
+ psi.EnvironmentVariables["DOTNET_ROLL_FORWARD"] <- "LatestMajor"
+ psi.EnvironmentVariables["DOTNET_ROLL_FORWARD_TO_PRERELEASE"] <- "1"
+ psi.EnvironmentVariables.Remove("MSBuildSDKsPath") // Host can sometimes add this, and it can break things
+ psi.UseShellExecute <- false
+
+ use p = new Process()
+ p.StartInfo <- psi
+
+ p.OutputDataReceived.Add(fun a -> outputDataReceived a.Data)
+ p.ErrorDataReceived.Add(fun a -> errorDataReceived a.Data)
+
+ if p.Start() then
+ p.BeginOutputReadLine()
+ p.BeginErrorReadLine()
+ if not(p.WaitForExit(timeout)) then
+ // Timed out resolving throw a diagnostic.
+ raise (new TimeoutException(sprintf "Timeout executing command '%s' '%s'" (psi.FileName) (psi.Arguments)))
+ else
+ p.WaitForExit()
+#if DEBUG
+ let workingDir' =
+ if workingDir = ""
+ then
+ // Assign working dir to prevent default to C:\Windows\System32
+ let executionLocation = Assembly.GetExecutingAssembly().Location
+ Path.GetDirectoryName executionLocation
+ else
+ workingDir
+
+ lock gate (fun () ->
+ File.WriteAllLines(Path.Combine(workingDir', "commandline.txt"), commandLine)
+ File.WriteAllLines(Path.Combine(workingDir', "StandardOutput.txt"), outputList)
+ File.WriteAllLines(Path.Combine(workingDir', "StandardError.txt"), errorsList)
+ )
+#endif
+ p.ExitCode, outputList.ToArray(), errorsList.ToArray()
let getfullpath workDir (path:string) =
let rooted =
diff --git a/tests/FSharp.Test.Utilities/Utilities.fs b/tests/FSharp.Test.Utilities/Utilities.fs
index 6ed885d4e44..1a6d0ff60f8 100644
--- a/tests/FSharp.Test.Utilities/Utilities.fs
+++ b/tests/FSharp.Test.Utilities/Utilities.fs
@@ -245,7 +245,7 @@ let main argv = 0"""
File.WriteAllText(directoryBuildTargetsFileName, directoryBuildTargets)
let timeout = 120000
- let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess (Some config.DotNetExe) "build" projectDirectory timeout
+ let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess config.DotNetExe "build" projectDirectory timeout
if exitCode <> 0 || errors.Length > 0 then
errors <- dotneterrors
diff --git a/tests/fsharp/typecheck/sigs/neg59.bsl b/tests/fsharp/typecheck/sigs/neg59.bsl
index a938f0d271c..77a9c8caf46 100644
--- a/tests/fsharp/typecheck/sigs/neg59.bsl
+++ b/tests/fsharp/typecheck/sigs/neg59.bsl
@@ -33,9 +33,9 @@ neg59.fs(89,15,89,18): typecheck error FS3141: 'try/finally' expressions may not
neg59.fs(95,15,95,18): typecheck error FS3141: 'try/finally' expressions may not be used in queries
-neg59.fs(102,15,102,64): typecheck error FS3142: 'use' expressions may not be used in queries
+neg59.fs(102,15,102,18): typecheck error FS3142: 'use' expressions may not be used in queries
-neg59.fs(108,15,108,64): typecheck error FS3142: 'use' expressions may not be used in queries
+neg59.fs(108,15,108,18): typecheck error FS3142: 'use' expressions may not be used in queries
neg59.fs(113,15,113,25): typecheck error FS3140: 'while' expressions may not be used in queries
diff --git a/tests/fsharp/typecheck/sigs/neg61.bsl b/tests/fsharp/typecheck/sigs/neg61.bsl
index b0e6b151a2c..d7011cef5ef 100644
--- a/tests/fsharp/typecheck/sigs/neg61.bsl
+++ b/tests/fsharp/typecheck/sigs/neg61.bsl
@@ -57,7 +57,7 @@ neg61.fs(79,13,79,16): typecheck error FS3146: 'try/with' expressions may not be
neg61.fs(86,13,86,16): typecheck error FS3141: 'try/finally' expressions may not be used in queries
-neg61.fs(92,13,92,70): typecheck error FS3142: 'use' expressions may not be used in queries
+neg61.fs(92,13,92,16): typecheck error FS3142: 'use' expressions may not be used in queries
neg61.fs(97,13,97,17): typecheck error FS3143: 'let!', 'use!' and 'do!' expressions may not be used in queries
diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs
index 90018a3a6a5..e83604cfdf9 100644
--- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.fs
+++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/ComputationExpressions/E_MissingUsing.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 'Using' method$
+//This control construct may only be used if the computation expression builder defines a 'Using' method$
type R = S of string
diff --git a/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl
index 5a7bf976186..596eb100812 100644
--- a/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/InlineKeywordInBinding.fs.bsl
@@ -44,11 +44,12 @@ ImplFile
{ LeadingKeyword = Let (3,4--3,7)
InlineKeyword = Some (3,8--3,14)
EqualsRange = Some (3,21--3,22) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,11--2,16), NoneAtLet, { LeadingKeyword = Let (2,0--2,3)
- InlineKeyword = Some (2,4--2,10)
- EqualsRange = Some (2,17--2,18) })],
- (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,11--2,16), NoneAtLet,
+ { LeadingKeyword = Let (2,0--2,3)
+ InlineKeyword = Some (2,4--2,10)
+ EqualsRange = Some (2,17--2,18) })], (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl
index 844946e66c3..e3156b5c3b5 100644
--- a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBinding.fs.bsl
@@ -20,8 +20,9 @@ ImplFile
Yes (3,4--3,13), { LeadingKeyword = Let (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,10--3,11) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl
index b0e567ed3bd..93dabea4c82 100644
--- a/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/RangeOfEqualSignShouldBePresentInLocalLetBindingTyped.fs.bsl
@@ -30,8 +30,9 @@ ImplFile
{ LeadingKeyword = Let (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,15--3,16) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl b/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl
index 31febede5b6..86775dec80c 100644
--- a/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl
+++ b/tests/service/data/SyntaxTree/Binding/RangeOfLetKeywordShouldBePresentInSynExprLetOrUseBinding.fs.bsl
@@ -34,11 +34,12 @@ ImplFile
NoneAtLet, { LeadingKeyword = Let (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,12--3,13) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,4--2,5), NoneAtLet, { LeadingKeyword = Let (2,0--2,3)
- InlineKeyword = None
- EqualsRange = Some (2,6--2,7) })],
- (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,4--2,5), NoneAtLet,
+ { LeadingKeyword = Let (2,0--2,3)
+ InlineKeyword = None
+ EqualsRange = Some (2,6--2,7) })], (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
index 132e7030303..791f6099b9e 100644
--- a/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/NestedSynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
@@ -55,8 +55,10 @@ ImplFile
[Some (OriginalNotation "+")]), None,
(5,6--5,7)), Ident x, (5,4--5,7)), Ident y,
(5,4--5,9)), (4,4--5,9),
- { InKeyword = Some (4,14--4,16) }), (3,4--5,9),
- { InKeyword = Some (3,14--3,16) }), (2,4--2,8), NoneAtLet,
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = Some (4,14--4,16) }), (3,4--5,9),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = Some (3,14--3,16) }), (2,4--2,8), NoneAtLet,
{ LeadingKeyword = Let (2,0--2,3)
InlineKeyword = None
EqualsRange = Some (2,9--2,10) })], (2,0--5,9))],
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
index f9ce333429a..5408f5d71d1 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseContainsTheRangeOfInKeyword.fs.bsl
@@ -19,7 +19,8 @@ ImplFile
InlineKeyword = None
EqualsRange = Some (2,6--2,7) })],
Const (Unit, (2,13--2,15)), (2,0--2,15),
- { InKeyword = Some (2,10--2,12) }), (2,0--2,15))],
+ { LetOrUseKeyword = (2,0--2,3)
+ InKeyword = Some (2,10--2,12) }), (2,0--2,15))],
PreXmlDocEmpty, [], None, (2,0--2,15), { LeadingKeyword = None })],
(true, true), { ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl
index 54c3f8180e4..bb9dcafe15f 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseDoesNotContainTheRangeOfInKeyword.fs.bsl
@@ -21,8 +21,9 @@ ImplFile
Yes (3,0--3,9), { LeadingKeyword = Let (3,0--3,3)
InlineKeyword = None
EqualsRange = Some (3,6--3,7) })],
- Const (Unit, (4,0--4,2)), (3,0--4,2), { InKeyword = None }),
- (2,0--4,2)), (2,0--4,2))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,0--4,2)), (3,0--4,2),
+ { LetOrUseKeyword = (3,0--3,3)
+ InKeyword = None }), (2,0--4,2)), (2,0--4,2))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl
index a5d102356f1..554f4eb21ef 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWhereBodyExprStartsWithTokenOfTwoCharactersDoesNotContainTheRangeOfInKeyword.fs.bsl
@@ -40,7 +40,8 @@ ImplFile
SynLongIdent
([e1; Value], [(4,10--4,11)], [None; None]), None,
(4,8--4,16))], [(4,6--4,7)], (4,0--4,16)),
- (3,0--4,16), { InKeyword = None }), (2,0--4,16)),
+ (3,0--4,16), { LetOrUseKeyword = (3,0--3,3)
+ InKeyword = None }), (2,0--4,16)),
(2,0--4,16))], PreXmlDocEmpty, [], None, (2,0--5,0),
{ LeadingKeyword = None })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl
index 72352706810..8b57f33b953 100644
--- a/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/SynExprLetOrUseWithRecursiveBindingContainsTheRangeOfInKeyword.fs.bsl
@@ -35,7 +35,8 @@ ImplFile
InlineKeyword = None
EqualsRange = Some (4,10--4,11) })],
Const (Unit, (5,4--5,6)), (3,4--5,6),
- { InKeyword = Some (4,15--4,17) }), (2,0--5,6)), (2,0--5,6))],
+ { LetOrUseKeyword = (3,4--3,11)
+ InKeyword = Some (4,15--4,17) }), (2,0--5,6)), (2,0--5,6))],
PreXmlDocEmpty, [], None, (2,0--6,0), { LeadingKeyword = None })],
(true, true), { ConditionalDirectives = []
CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl b/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl
index 94ee31ce8d1..74221e70a5f 100644
--- a/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl
+++ b/tests/service/data/SyntaxTree/Expression/Try with - Missing expr 04.fs.bsl
@@ -19,7 +19,8 @@ ImplFile
InlineKeyword = None
EqualsRange = Some (5,6--5,7) })],
ArbitraryAfterError ("seqExpr", (5,10--5,10)), (5,0--5,10),
- { InKeyword = None }), [], (3,0--5,10), Yes (3,0--3,3),
+ { LetOrUseKeyword = (5,0--5,3)
+ InKeyword = None }), [], (3,0--5,10), Yes (3,0--3,3),
Yes (5,10--5,10), { TryKeyword = (3,0--3,3)
TryToWithRange = (3,0--5,10)
WithKeyword = (5,10--5,10)
diff --git a/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl b/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl
index b2b3420c806..4571189344f 100644
--- a/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/LeadingKeyword/UseKeyword.fs.bsl
@@ -22,8 +22,9 @@ ImplFile
{ LeadingKeyword = Use (3,4--3,7)
InlineKeyword = None
EqualsRange = Some (3,10--3,11) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl b/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl
index 7dbbc35edd7..ac1d1ce9819 100644
--- a/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl
+++ b/tests/service/data/SyntaxTree/LeadingKeyword/UseRecKeyword.fs.bsl
@@ -22,8 +22,9 @@ ImplFile
{ LeadingKeyword = UseRec ((3,4--3,7), (3,8--3,11))
InlineKeyword = None
EqualsRange = Some (3,14--3,15) })],
- Const (Unit, (4,4--4,6)), (3,4--4,6), { InKeyword = None }),
- (2,0--4,6)), (2,0--4,6))], PreXmlDocEmpty, [], None, (2,0--5,0),
- { LeadingKeyword = None })], (true, true),
- { ConditionalDirectives = []
- CodeComments = [] }, set []))
+ Const (Unit, (4,4--4,6)), (3,4--4,6),
+ { LetOrUseKeyword = (3,4--3,11)
+ InKeyword = None }), (2,0--4,6)), (2,0--4,6))],
+ PreXmlDocEmpty, [], None, (2,0--5,0), { LeadingKeyword = None })],
+ (true, true), { ConditionalDirectives = []
+ CodeComments = [] }, set []))
diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl
index 84ce5019498..f4b3b9f7a39 100644
--- a/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl
+++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfMultipleSynMatchClause.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
EqualsRange = Some (3,16--3,17) })],
App
(NonAtomic, false, Ident Some, Ident content, (4,4--4,16)),
- (3,4--4,16), { InKeyword = None }),
+ (3,4--4,16), { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }),
[SynMatchClause
(Named (SynIdent (ex, None), false, None, (6,2--6,4)), None,
Sequential
diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl
index dfa2ad58587..324463e7b2e 100644
--- a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl
+++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClause.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
EqualsRange = Some (3,16--3,17) })],
App
(NonAtomic, false, Ident Some, Ident content, (4,4--4,16)),
- (3,4--4,16), { InKeyword = None }),
+ (3,4--4,16), { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }),
[SynMatchClause
(Named (SynIdent (ex, None), false, None, (5,5--5,7)), None,
Sequential
diff --git a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl
index ea10cf70558..132cbd01cc0 100644
--- a/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl
+++ b/tests/service/data/SyntaxTree/MatchClause/RangeOfSingleSynMatchClauseFollowedByBar.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
EqualsRange = Some (3,16--3,17) })],
App
(NonAtomic, false, Ident Some, Ident content, (4,4--4,16)),
- (3,4--4,16), { InKeyword = None }),
+ (3,4--4,16), { LetOrUseKeyword = (3,4--3,7)
+ InKeyword = None }),
[SynMatchClause
(Named (SynIdent (ex, None), false, None, (6,2--6,4)), None,
Const (Unit, (7,4--7,6)), (6,2--7,6), Yes,
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl
index 54749497087..7bd27b958c6 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 05.fs.bsl
@@ -30,7 +30,8 @@ ImplFile
InlineKeyword = None
EqualsRange = None })],
ArbitraryAfterError ("seqExpr", (4,10--4,10)),
- (4,4--4,10), { InKeyword = None }), (4,4--4,10)),
+ (4,4--4,10), { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (4,4--4,10)),
(3,0--4,10)), (3,0--4,10))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--4,10), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl
index 55a07b60288..6120ff4f5fd 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 06.fs.bsl
@@ -26,8 +26,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,11--4,12) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl
index 89a4af5ce5c..0f2e4604d2b 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 09.fs.bsl
@@ -25,7 +25,8 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = None })], Const (Unit, (6,4--6,6)),
- (4,4--6,6), { InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
+ (4,4--6,6), { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl
index f3fa83db96a..5e8ab0f26fd 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 10.fs.bsl
@@ -24,8 +24,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,13--4,14) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl
index e89431a48e0..dbf43bcf3b1 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 11.fs.bsl
@@ -30,8 +30,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,15--4,16) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl
index 97ad7191e25..416dc67c859 100644
--- a/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl
+++ b/tests/service/data/SyntaxTree/Pattern/Typed - Missing type 12.fs.bsl
@@ -38,8 +38,9 @@ ImplFile
{ LeadingKeyword = Let (4,4--4,7)
InlineKeyword = None
EqualsRange = Some (4,18--4,19) })],
- Const (Unit, (6,4--6,6)), (4,4--6,6), { InKeyword = None }),
- (3,0--6,6)), (3,0--6,6))],
+ Const (Unit, (6,4--6,6)), (4,4--6,6),
+ { LetOrUseKeyword = (4,4--4,7)
+ InKeyword = None }), (3,0--6,6)), (3,0--6,6))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
diff --git a/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl b/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl
index d91bffd331d..1dfe5586b56 100644
--- a/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl
+++ b/tests/service/data/SyntaxTree/String/InterpolatedStringOffsideInNestedLet.fs.bsl
@@ -31,7 +31,8 @@ ImplFile
{ LeadingKeyword = Let (2,4--2,7)
InlineKeyword = None
EqualsRange = Some (2,10--2,11) })], Ident b,
- (2,4--5,5), { InKeyword = None }), (1,4--1,5), NoneAtLet,
+ (2,4--5,5), { LetOrUseKeyword = (2,4--2,7)
+ InKeyword = None }), (1,4--1,5), NoneAtLet,
{ LeadingKeyword = Let (1,0--1,3)
InlineKeyword = None
EqualsRange = Some (1,6--1,7) })], (1,0--5,5))],