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 d055d7c988b..2aba384bfa0 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -13,6 +13,7 @@ * `[]` 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)) +* Return diagnostics that got suppressed by errors in previous files. ([PR #16719](https://github.com/dotnet/fsharp/pull/16719)) * Fix release inline optimization, which leads to MethodAccessException if used with `assembly:InternalsVisibleTo`` attribute. ([Issue #16105](https://github.com/dotnet/fsharp/issues/16105), ([PR #16737](https://github.com/dotnet/fsharp/pull/16737)) * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index dda21fffd39..46ea4bce4f5 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -2909,11 +2909,6 @@ module internal ParseAndCheckFile = // update the error handler with the modified tcConfig errHandler.DiagnosticOptions <- tcConfig.diagnosticsOptions - // Play background errors and warnings for this file. - do - for err, severity in backgroundDiagnostics do - diagnosticSink (err, severity) - // If additional references were brought in by the preprocessor then we need to process them ApplyLoadClosure(tcConfig, parsedMainInput, mainInputFileName, loadClosure, tcImports, backgroundDiagnostics) @@ -2957,6 +2952,11 @@ module internal ParseAndCheckFile = return ((tcState.TcEnvFromSignatures, EmptyTopAttrs, [], [ mty ]), tcState) } + // Play background errors and warnings for this file. + do + for err, severity in backgroundDiagnostics do + diagnosticSink (err, severity) + let (tcEnvAtEnd, _, implFiles, ccuSigsForFiles), tcState = resOpt let symbolEnv = SymbolEnv(tcGlobals, tcState.Ccu, Some tcState.CcuSig, tcImports) diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs index bcdc3517394..6912abca332 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs @@ -166,3 +166,31 @@ let GetAllUsesOfAllSymbols() = traceProvider.Dispose() if result.Length <> 79 then failwith $"Expected 79 symbolUses, got {result.Length}:\n%A{result}" + +[] +let ``We don't lose subsequent diagnostics when there's error in one file`` () = + let project = + { SyntheticProject.Create( + { sourceFile "First" [] with + Source = """module AbstractBaseClass.File1 + + let foo x = () + + a""" }, + { sourceFile "Second" [] with + Source = """module AbstractBaseClass.File2 + + open AbstractBaseClass.File1 + + let goo = foo 1 + + type AbstractBaseClass() = + + abstract P: int""" }) with + AutoAddModules = false + SkipInitialCheck = true } + + project.Workflow { + checkFile "First" (expectErrorCodes ["FS0039"]) + checkFile "Second" (expectErrorCodes ["FS0054"; "FS0365"]) + } diff --git a/tests/FSharp.Test.Utilities/ProjectGeneration.fs b/tests/FSharp.Test.Utilities/ProjectGeneration.fs index ad3660747fe..892d7c16701 100644 --- a/tests/FSharp.Test.Utilities/ProjectGeneration.fs +++ b/tests/FSharp.Test.Utilities/ProjectGeneration.fs @@ -725,6 +725,19 @@ module ProjectOperations = then failwith "Expected errors, but there were none" + let expectErrorCodes codes parseAndCheckResults _ = + let (parseResult: FSharpParseFileResults), _checkResult = parseAndCheckResults + + if not parseResult.ParseHadErrors then + let checkResult = getTypeCheckResult parseAndCheckResults + let actualCodes = checkResult.Diagnostics |> Seq.map (fun d -> d.ErrorNumberText) |> Set + let codes = Set.ofSeq codes + if actualCodes <> codes then + failwith $"Expected error codes {codes} but got {actualCodes}. \n%A{checkResult.Diagnostics}" + + else + failwith $"There were parse errors: %A{parseResult.Diagnostics}" + let expectSignatureChanged result (oldSignature: string, newSignature: string) = expectOk result () Assert.NotEqual(oldSignature, newSignature)