From 611e4f350e119a4173a2b235eac65539ac2b61b6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:16:14 +0100 Subject: [PATCH 1/4] [main] Update dependencies from dotnet/source-build-reference-packages (#16683) * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240208.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 9.0.0-alpha.1.24107.1 -> To Version 9.0.0-alpha.1.24108.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240209.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 9.0.0-alpha.1.24107.1 -> To Version 9.0.0-alpha.1.24109.1 * Update dependencies from https://github.com/dotnet/source-build-reference-packages build 20240209.1 Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 9.0.0-alpha.1.24107.1 -> To Version 9.0.0-alpha.1.24109.1 --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Kevin Ransom (msft) --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6bff45a6228..8677a94b146 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,9 +1,9 @@ - + https://github.com/dotnet/source-build-reference-packages - a739c05eb1a5200d7fa2f1e3977b4dc54fdec36a + 8ee50f75f960fbfb20fce0fefc5a3b05d15b1d21 From f6f49b6b8be7f36528b2600522671a5ffbafd45e Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 12 Feb 2024 07:24:22 -0800 Subject: [PATCH 2/4] Fix16572 - Enabling preview features causes an issue with main somehow. (#16657) * temp * Fix16572 * readme * Update 8.0.300.md --------- Co-authored-by: Petr --- .../.FSharp.Compiler.Service/8.0.300.md | 3 +- src/Compiler/Checking/CheckDeclarations.fs | 34 ++++++----- .../Types/UnionTypes/UnionTypes.fs | 60 +++++++++++++++++++ .../Language/DiscriminatedUnionTests.fs | 55 ++++++++++++----- 4 files changed, 119 insertions(+), 33 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 6a4d44d2aec..88b09242421 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -6,7 +6,8 @@ * Graph Based Checking doesn't throw on invalid parsed input so it can be used for IDE scenarios ([PR #16575](https://github.com/dotnet/fsharp/pull/16575), [PR #16588](https://github.com/dotnet/fsharp/pull/16588), [PR #16643](https://github.com/dotnet/fsharp/pull/16643)) * Various parenthesization API fixes. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578), [PR #16666](https://github.com/dotnet/fsharp/pull/16666)) * Keep parens for problematic exprs (`if`, `match`, etc.) in `$"{(…):N0}"`, `$"{(…),-3}"`, etc. ([PR #16578](https://github.com/dotnet/fsharp/pull/16578)) -* Fix crash in DOTNET_SYSTEM_GLOBALIZATION_INVARIANT mode ([PR #16471](https://github.com/dotnet/fsharp/pull/16471)) +* Fix crash in DOTNET_SYSTEM_GLOBALIZATION_INVARIANT mode [#PR 16471](https://github.com/dotnet/fsharp/pull/16471)) +* Fix16572 - Fixed the preview feature enabling Is properties for union case did not work correctly with let .rec and .fsi files ([PR #16657](https://github.com/dotnet/fsharp/pull/16657)) * `[]` member should not produce property symbol. ([Issue #16640](https://github.com/dotnet/fsharp/issues/16640), [PR #16658](https://github.com/dotnet/fsharp/pull/16658)) * Fix discriminated union initialization. ([#PR 16661](https://github.com/dotnet/fsharp/pull/16661)) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index ef59411179e..fc2e5e9d19b 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -4727,7 +4727,6 @@ module TcDeclarations = let env = List.foldBack (AddLocalVal g cenv.tcSink scopem) idvs envForDecls env) - /// Bind a collection of mutually recursive declarations in a signature file let TcMutRecSignatureDecls (cenv: cenv) envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecSigs: MutRecSigsInitialData) = let mutRecSigsAfterSplit = mutRecSigs |> MutRecShapes.mapTycons SplitTyconSignature @@ -4739,6 +4738,18 @@ module TcDeclarations = // Updates the types of the modules to contain the contents so far, which now includes values and members MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterCore + // Generate the union augmentation values for all tycons. + let mutable vals = List.empty + (envMutRec, mutRecDefnsAfterCore) + ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls ((tyconCore, _, _), tyconOpt, _, _, _) -> + let (MutRecDefnsPhase1DataForTycon (isAtOriginalTyconDefn=isAtOriginalTyconDefn)) = tyconCore + match tyconOpt with + | Some tycon when isAtOriginalTyconDefn -> + if tycon.IsUnionTycon && AddAugmentationDeclarations.ShouldAugmentUnion cenv.g tycon then + let vspecs = AddAugmentationDeclarations.AddUnionAugmentationValues cenv envForDecls tycon + vals <- vspecs @ vals + | _ -> ()) + // By now we've established the full contents of type definitions apart from their // members and any fields determined by implicit construction. We know the kinds and // representations of types and have established them as valid. @@ -4747,28 +4758,19 @@ module TcDeclarations = // // Note: This environment reconstruction doesn't seem necessary. We're about to create Val's for all members, // which does require type checking, but no more information than is already available. - let envMutRecPrelimWithReprs, withEnvs = + + let envMutRecPrelimWithReprs, withEnvs = (envInitial, MutRecShapes.dropEnvs mutRecDefnsAfterCore) - ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs - (fun (_, tyconOpt, _, _, _) -> tyconOpt) - (fun _binds -> [ (* no values are available yet *) ]) - cenv true scopem m + ||> MutRecBindingChecking.TcMutRecDefns_ComputeEnvs + (fun (_, tyconOpt, _, _, _) -> tyconOpt) + (fun _binds -> vals) + cenv true scopem m let mutRecDefnsAfterVals = TcMutRecSignatureDecls_Phase2 cenv scopem envMutRecPrelimWithReprs withEnvs // Updates the types of the modules to contain the contents so far, which now includes values and members MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterVals - // Generate the union augmentation values for all tycons. - (envMutRec, mutRecDefnsAfterCore) ||> MutRecShapes.iterTyconsWithEnv (fun envForDecls ((tyconCore, _, _), tyconOpt, _, _, _) -> - let (MutRecDefnsPhase1DataForTycon (isAtOriginalTyconDefn=isAtOriginalTyconDefn)) = tyconCore - match tyconOpt with - | Some tycon when isAtOriginalTyconDefn -> - if tycon.IsUnionTycon && AddAugmentationDeclarations.ShouldAugmentUnion cenv.g tycon then - let vspecs = AddAugmentationDeclarations.AddUnionAugmentationValues cenv envForDecls tycon - ignore vspecs - | _ -> ()) - envMutRec //------------------------------------------------------------------------- diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionTypes.fs index e30a31edacf..948ae405822 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionTypes.fs @@ -610,6 +610,66 @@ module UnionTypes = (Warning 42, Line 11, Col 12, Line 11, Col 24, "This construct is deprecated: it is only for use in the F# library") ] + [] + [] + [] + let ``UnionCaseIsTester inlined and SignatureData`` userec = + + let kwrec = if userec then "rec" else "" + let myLibraryFsi = + SourceCodeFileKind.Create( + "myLibrary.fsi", + $""" +module {kwrec} MyLibrary + + [] + type PrimaryAssembly = + | Mscorlib + | System_Runtime + | NetStandard""") + + let myLibraryFs = + SourceCodeFileKind.Create( + "myLibrary.fs", + $""" +module {kwrec} MyLibrary + + [] + type PrimaryAssembly = + | Mscorlib + | System_Runtime + | NetStandard + """) + + let myFileFs = + SourceCodeFileKind.Create( + "myFile.fs", + $""" +module {kwrec} FileName + + open MyLibrary + let inline getAssemblyType () = PrimaryAssembly.NetStandard + let inline isNetStandard () = (PrimaryAssembly.NetStandard).IsNetStandard + """) + + let myLibrary = + (fsFromString myLibraryFsi) |> FS + |> withAdditionalSourceFiles [myLibraryFs; myFileFs] + |> asLibrary + |> withLangVersionPreview + |> withName "MyLibrary" + + Fs """ +let x = FileName.getAssemblyType().IsNetStandard +let y = FileName.getAssemblyType() +let z = FileName.isNetStandard() +printfn "%b %A %b" x y z + """ + |> asExe + |> withReferences [myLibrary] + |> withLangVersionPreview + |> compileAndRun + |> shouldSucceed //SOURCE=W_UnionCaseProduction01.fsx SCFLAGS="-a --test:ErrorRanges" # W_UnionCaseProduction01.fsx [] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs index d7de4c35cd2..6d2d0d24c28 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs @@ -2,10 +2,12 @@ namespace Language +open Xunit open FSharp.Test.Compiler module DiscriminatedUnionTests = - [] + + [] let ``Simple Is* discriminated union properties are visible, proper values are returned`` () = Fsx """ type Foo = | Foo of string | Bar @@ -17,7 +19,7 @@ if foo.IsBar then failwith "Should not be Bar" |> compileExeAndRun |> shouldSucceed - [] + [] let ``Simple Is* discriminated union properties are not visible for a single case union`` () = Fsx """ type Foo = Bar of string @@ -31,7 +33,7 @@ if not foo.IsBar then failwith "Should be Bar" |> withDiagnostics [Error 39, Line 4, Col 12, Line 4, Col 17, "The type 'Foo' does not define the field, constructor or member 'IsBar'. Maybe you want one of the following: Bar"] - [] + [] let ``Simple Is* discriminated union property satisfies SRTP constraint`` () = Fsx """ type X = @@ -47,7 +49,7 @@ X.A "a" |> test |> compileExeAndRun |> shouldSucceed - [] + [] let ``Lowercase Is* discriminated union properties are visible, proper values are returned`` () = Fsx """ [] @@ -63,7 +65,7 @@ if foo.IsA then failwith "Should not be A" |> compileExeAndRun |> shouldSucceed - [] + [] let ``Is* discriminated union properties with backticks are visible, proper values are returned`` () = Fsx """ type Foo = | Foo of string | ``Mars Bar`` @@ -79,7 +81,7 @@ if not marsbar.``IsMars Bar`` then failwith "Should be ``Mars Bar``" |> compileExeAndRun |> shouldSucceed - [] + [] let ``Is* discriminated union properties are visible, proper values are returned in recursive namespace, before the definition`` () = FSharp """ namespace rec Hello @@ -102,7 +104,7 @@ type Foo = |> shouldSucceed - [] + [] let ``Is* discriminated union properties are visible, proper values are returned in recursive namespace, in SRTP`` () = FSharp """ namespace Hello @@ -130,7 +132,7 @@ module Main = |> compileExeAndRun |> shouldSucceed - [] + [] let ``Is* discriminated union properties are unavailable with DefaultAugmentation(false)`` () = Fsx """ [] @@ -144,19 +146,40 @@ let isFoo = foo.IsFoo |> withErrorMessage "The type 'Foo' does not define the field, constructor or member 'IsFoo'. Maybe you want one of the following: Foo" - [] - let ``Is* discriminated union properties are unavailable on voption`` () = + [] + let ``Is* discriminated union properties are unavailable on union case with lang version 8`` () = Fsx """ -let x = (ValueSome 1).IsSome -let y = ValueOption.None.IsValueNone +[] +type PrimaryAssembly = +| Mscorlib +| System_Runtime +| NetStandard + +let x = (PrimaryAssembly.Mscorlib).IsMscorlib """ - |> withLangVersionPreview + |> withLangVersion80 |> typecheck |> shouldFail - |> withErrorMessage "The type 'ValueOption<_>' does not define the field, constructor or member 'IsValueNone'. Maybe you want one of the following: - ValueNone" + |> withErrorMessage "The type 'PrimaryAssembly' does not define the field, constructor or member 'IsMscorlib'. Maybe you want one of the following: + Mscorlib" + + + [] + let ``Is* discriminated union properties are available on union case after lang version 8`` () = + Fsx """ +[] +type PrimaryAssembly = +| Mscorlib +| System_Runtime +| NetStandard + +let x = (PrimaryAssembly.Mscorlib).IsMscorlib + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed - [] + [] let ``Is* discriminated union properties work with UseNullAsTrueValue`` () = Fsx """ [] From 921ec7ce9d60e39c8db2db9872f586d1a343e230 Mon Sep 17 00:00:00 2001 From: ijklam <43789618+Tangent-90@users.noreply.github.com> Date: Tue, 13 Feb 2024 02:05:52 +0800 Subject: [PATCH 3/4] Allow calling method with both Optional and ParamArray (#16688) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Allow calling method with both Optional and ParamArray * release note * 更新 MethodCalls.fs --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + src/Compiler/Checking/MethodCalls.fs | 6 ++++ .../BasicGrammarElements/MethodResolution.fs | 31 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 88b09242421..672209d2ed1 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -10,6 +10,7 @@ * Fix16572 - Fixed the preview feature enabling Is properties for union case did not work correctly with let .rec and .fsi files ([PR #16657](https://github.com/dotnet/fsharp/pull/16657)) * `[]` member should not produce property symbol. ([Issue #16640](https://github.com/dotnet/fsharp/issues/16640), [PR #16658](https://github.com/dotnet/fsharp/pull/16658)) * Fix discriminated union initialization. ([#PR 16661](https://github.com/dotnet/fsharp/pull/16661)) +* Allow calling method with both Optional and ParamArray. ([#PR 16688](https://github.com/dotnet/fsharp/pull/16688), [suggestions #1120](https://github.com/fsharp/fslang-suggestions/issues/1120)) ### Added diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 5aed55cba08..5f60bfce120 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -556,6 +556,12 @@ type CalledMeth<'T> let nUnnamedCalledArgs = unnamedCalledArgs.Length if allowOutAndOptArgs && nUnnamedCallerArgs < nUnnamedCalledArgs then let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs = List.splitAt nUnnamedCallerArgs unnamedCalledArgs + + // take the last ParamArray arg out, make it not break the optional/out params check + let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs = + match List.rev unnamedCalledOptOrOutArgs with + | h :: t when h.IsParamArray -> unnamedCalledArgsTrimmed @ [h], List.rev t + | _ -> unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs let isOpt x = x.OptArgInfo.IsOptional let isOut x = x.IsOutArg && isByrefTy g x.CalledArgumentType diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs index 613001af658..3ac3d49ce4b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs @@ -262,3 +262,34 @@ let _, _ = Thing.Do() (Error 501, Line 6, Col 12, Line 6, Col 22, "The member or object constructor 'Do' takes 1 argument(s) but is here given 0. The required signature is 'static member Thing.Do: [] i: outref -> bool'.") ] + [] + let ``optional and ParamArray parameter resolves correctly `` () = + Fsx """ +open System.Runtime.InteropServices + +type Thing = + static member Do( + [] something: string, + [] args: obj[]) = something, args + static member Do2( + [] something: string, + outvar: outref, + [] args: obj[]) = + + outvar <- 1 + something, args +let _, _ = Thing.Do() +let _, _ = Thing.Do("123") +let _, _ = Thing.Do("123", 1, 2, 3, 4) + +let _, _ = Thing.Do2() +let _, _ = Thing.Do2("123") +let _ = + let mutable x = 0 + Thing.Do2("123", &x) +let _ = + let mutable x = 0 + Thing.Do2("123", &x, 1, 2, 3, 4) + """ + |> typecheck + |> shouldSucceed From 9636fba93efef872e6e19448bcac7edeae342de6 Mon Sep 17 00:00:00 2001 From: dawe Date: Mon, 12 Feb 2024 19:14:32 +0100 Subject: [PATCH 4/4] Let TransparentCompiler respect hash directives like #nowarn (#16667) --- src/Compiler/Service/TransparentCompiler.fs | 19 +++------------ .../ConstraintSolver/ObjInference.fs | 11 +++++---- tests/service/ExprTests.fs | 24 +++++++++++++++++++ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index 124be183fd9..1d3ccf36906 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -1198,29 +1198,16 @@ type internal TransparentCompiler tcConfig.flatErrors ) - use _ = - new CompilationGlobalsScope(errHandler.DiagnosticsLogger, BuildPhase.TypeCheck) - // Apply nowarns to tcConfig (may generate errors, so ensure diagnosticsLogger is installed) let tcConfig = ApplyNoWarnsToTcConfig(tcConfig, parsedMainInput, Path.GetDirectoryName mainInputFileName) - // update the error handler with the modified tcConfig - errHandler.DiagnosticOptions <- tcConfig.diagnosticsOptions - let diagnosticsLogger = errHandler.DiagnosticsLogger - //let capturingDiagnosticsLogger = CapturingDiagnosticsLogger("TypeCheck") - - //let diagnosticsLogger = - // GetDiagnosticsLoggerFilteringByScopedPragmas( - // false, - // input.ScopedPragmas, - // tcConfig.diagnosticsOptions, - // capturingDiagnosticsLogger - // ) + let diagnosticsLogger = + GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, diagnosticsLogger) - //use _ = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.TypeCheck) + use _ = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.TypeCheck) //beforeFileChecked.Trigger fileName diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/ObjInference.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/ObjInference.fs index 32950d8ba4c..d12a462f384 100644 --- a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/ObjInference.fs +++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/ObjInference.fs @@ -34,13 +34,14 @@ let x = deserialize "" |> f""", 3, 9, 3, 28 [] [] let ``Warning is emitted when type Obj is inferred``(code: string, line1: int, col1: int, line2: int, col2: int) = + let code = $"module M\n{code}" FSharp code |> withErrorRanges |> withWarnOn 3559 |> withLangVersion80 - |> typecheck + |> compile |> shouldFail - |> withSingleDiagnostic (Information 3559, Line line1, Col col1, Line line2, Col col2, message) + |> withSingleDiagnostic (Warning 3559, Line (line1 + 1), Col col1, Line (line2 + 1), Col col2, message) let quotableNoWarningCases = [ @@ -110,13 +111,13 @@ let f () = x = x |> ignore""" // measure is inferred as 1, but that's not covere [] [] let ``Warn also inside quotations of acceptable code``(expr: string, line1: int, col1: int, line2: int, col2: int) = - sprintf "<@ %s @> |> ignore" expr + sprintf "module M\n<@ %s @> |> ignore" expr |> FSharp |> withWarnOn 3559 |> withLangVersion80 - |> typecheck + |> compile |> shouldFail - |> withSingleDiagnostic (Information 3559, Line line1, Col (col1 + 3), Line line2, Col (col2 + 3), message) + |> withSingleDiagnostic (Warning 3559, Line (line1 + 1), Col (col1 + 3), Line (line2 + 1), Col (col2 + 3), message) [] [] diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 7b35568e38d..1371c24f231 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -3605,3 +3605,27 @@ let ``Test ProjectForWitnesses4 GetWitnessPassingInfo`` useTransparentCompiler = printfn "actual:\n\n%A" actual actual |> shouldPairwiseEqual expected + +module internal ProjectForNoWarnHashDirective = + + let fileSource1 = """ +module N.M +#nowarn "40" +let rec f = new System.EventHandler(fun _ _ -> f.Invoke(null,null)) +""" + + let createOptions() = createOptionsAux [fileSource1] [] + +[] +[] +[] +let ``Test NoWarn HashDirective`` useTransparentCompiler = + let cleanup, options = ProjectForNoWarnHashDirective.createOptions() + use _holder = cleanup + let exprChecker = FSharpChecker.Create(keepAssemblyContents=true, useTransparentCompiler=useTransparentCompiler) + let wholeProjectResults = exprChecker.ParseAndCheckProject(options) |> Async.RunImmediate + + for e in wholeProjectResults.Diagnostics do + printfn "ProjectForNoWarnHashDirective error: <<<%s>>>" e.Message + + wholeProjectResults.Diagnostics.Length |> shouldEqual 0