Skip to content

Commit be2cd93

Browse files
authored
Type checker: don't suppress errors while checking expressions (dotnet#18311)
1 parent 54c4b66 commit be2cd93

File tree

18 files changed

+231
-99
lines changed

18 files changed

+231
-99
lines changed

docs/release-notes/.FSharp.Compiler.Service/9.0.300.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* Add support for C# `Experimental` attribute. ([PR #18253](https://github.com/dotnet/fsharp/pull/18253))
3333
* Nullness warnings are issued for signature<>implementation conformance ([PR #18186](https://github.com/dotnet/fsharp/pull/18186))
3434
* Symbols: Add FSharpAssembly.IsFSharp ([PR #18290](https://github.com/dotnet/fsharp/pull/18290))
35+
* Type checker: don't suppress errors while checking expressions ([PR #18311](https://github.com/dotnet/fsharp/pull/18311))
3536
* Type parameter constraint `null` in generic code will now automatically imply `not struct` ([Issue #18320](https://github.com/dotnet/fsharp/issues/18320), [PR #18323](https://github.com/dotnet/fsharp/pull/18323))
3637
* Add a switch to determine whether to generate a default implementation body for overridden method when completing. [PR #18341](https://github.com/dotnet/fsharp/pull/18341)
3738
* Use a more accurate range for CE Combine methods. [PR #18394](https://github.com/dotnet/fsharp/pull/18394)

src/Compiler/Checking/Expressions/CheckExpressions.fs

+27-35
Original file line numberDiff line numberDiff line change
@@ -5960,7 +5960,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
59605960

59615961
| SynExpr.FromParseError (expr1, m) ->
59625962
//SolveTypeAsError cenv env.DisplayEnv m overallTy
5963-
let _, tpenv = suppressErrorReporting (fun () -> TcExpr cenv overallTy env tpenv expr1)
5963+
let _, tpenv = TcExpr cenv overallTy env tpenv expr1
59645964
mkDefault(m, overallTy.Commit), tpenv
59655965

59665966
| SynExpr.Sequential (sp, dir, synExpr1, synExpr2, m, _) ->
@@ -6489,9 +6489,7 @@ and TcIteratedLambdas (cenv: cenv) isFirst (env: TcEnv) overallTy takenNames tpe
64896489

64906490
| e ->
64916491
let env = { env with eIsControlFlow = true }
6492-
// Dive into the expression to check for syntax errors and suppress them if they show.
6493-
conditionallySuppressErrorReporting (not isFirst && synExprContainsError e) (fun () ->
6494-
TcExpr cenv overallTy env tpenv e)
6492+
TcExpr cenv overallTy env tpenv e
64956493

64966494
and TcTyparExprThen (cenv: cenv) overallTy env tpenv synTypar m delayed =
64976495
match delayed with
@@ -11103,39 +11101,33 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
1110311101
// At each module binding, dive into the expression to check for syntax errors and suppress them if they show.
1110411102
// Don't do this for lambdas, because we always check for suppression for all lambda bodies in TcIteratedLambdas
1110511103
let rhsExprChecked, tpenv =
11106-
let atTopNonLambdaDefn =
11107-
declKind.IsModuleOrMemberOrExtensionBinding &&
11108-
(match rhsExpr with SynExpr.Lambda _ -> false | _ -> true) &&
11109-
synExprContainsError rhsExpr
11110-
11111-
conditionallySuppressErrorReporting atTopNonLambdaDefn (fun () ->
11112-
11113-
// Save the arginfos away to match them up in the lambda
11114-
let (PrelimValReprInfo(argInfos, _)) = prelimValReprInfo
11115-
11116-
// The right-hand-side is control flow (has an implicit debug point) in any situation where we
11117-
// haven't extended the debug point to include the 'let', that is, there is a debug point noted
11118-
// at the binding.
11119-
//
11120-
// This includes
11121-
// let _ = expr
11122-
// let () = expr
11123-
// which are transformed to sequential expressions in TcLetBinding
11124-
//
11125-
let rhsIsControlFlow =
11126-
match pat with
11127-
| SynPat.Wild _
11128-
| SynPat.Const (SynConst.Unit, _)
11129-
| SynPat.Paren (SynPat.Const (SynConst.Unit, _), _) -> true
11130-
| _ ->
11131-
match debugPoint with
11132-
| DebugPointAtBinding.Yes _ -> false
11133-
| _ -> true
11104+
// Save the arginfos away to match them up in the lambda
11105+
let (PrelimValReprInfo(argInfos, _)) = prelimValReprInfo
11106+
11107+
// The right-hand-side is control flow (has an implicit debug point) in any situation where we
11108+
// haven't extended the debug point to include the 'let', that is, there is a debug point noted
11109+
// at the binding.
11110+
//
11111+
// This includes
11112+
// let _ = expr
11113+
// let () = expr
11114+
// which are transformed to sequential expressions in TcLetBinding
11115+
//
11116+
let rhsIsControlFlow =
11117+
match pat with
11118+
| SynPat.Wild _
11119+
| SynPat.Const (SynConst.Unit, _)
11120+
| SynPat.Paren (SynPat.Const (SynConst.Unit, _), _) -> true
11121+
| _ ->
11122+
11123+
match debugPoint with
11124+
| DebugPointAtBinding.Yes _ -> false
11125+
| _ -> true
1113411126

11135-
let envinner = { envinner with eLambdaArgInfos = argInfos; eIsControlFlow = rhsIsControlFlow }
11127+
let envinner = { envinner with eLambdaArgInfos = argInfos; eIsControlFlow = rhsIsControlFlow }
1113611128

11137-
if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr
11138-
else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr)
11129+
if isCtor then TcExprThatIsCtorBody (safeThisValOpt, safeInitInfo) cenv (MustEqual overallExprTy) envinner tpenv rhsExpr
11130+
else TcExprThatCantBeCtorBody cenv (MustConvertTo (false, overallExprTy)) envinner tpenv rhsExpr
1113911131

1114011132
if kind = SynBindingKind.StandaloneExpression && not cenv.isScript then
1114111133
UnifyUnitType cenv env mBinding overallPatTy rhsExprChecked |> ignore<bool>

tests/FSharp.Compiler.Service.Tests/Common.fs

+7-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ let mkProjectCommandLineArgsForScript (dllName, fileNames) =
119119
yield "--doc:test.xml"
120120
yield "--warn:3"
121121
yield "--fullpaths"
122-
yield "--flaterrors"
123122
yield "--target:library"
124123
for x in fileNames do
125124
yield x
@@ -370,11 +369,17 @@ let inline dumpDiagnostics (results: FSharpCheckFileResults) =
370369
|> Array.map (fun e ->
371370
let message =
372371
e.Message.Split('\n')
373-
|> Array.map (fun s -> s.Trim())
372+
|> Array.map _.Trim()
373+
|> Array.filter (fun s -> s.Length > 0)
374374
|> String.concat " "
375375
sprintf "%s: %s" (e.Range.ToString()) message)
376376
|> List.ofArray
377377

378+
let inline dumpDiagnosticNumbers (results: FSharpCheckFileResults) =
379+
results.Diagnostics
380+
|> Array.map (fun e -> e.Range.ToString(), e.ErrorNumber)
381+
|> List.ofArray
382+
378383
let getSymbolUses (results: FSharpCheckFileResults) =
379384
results.GetAllUsesOfAllSymbolsInFile()
380385

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<Link>XunitSetup.fs</Link>
2727
</Compile>
2828
<Compile Include="Common.fs" />
29+
<Compile Include="TypeChecker\TypeCheckerRecoveryTests.fs" />
2930
<Compile Include="GeneratedCodeSymbolsTests.fs" />
3031
<Compile Include="AssemblyReaderShim.fs" />
3132
<Compile Include="ModuleReaderCancellationTests.fs" />

0 commit comments

Comments
 (0)