Skip to content

Commit db079bb

Browse files
authored
Merge pull request #17466 from dotnet/merges/main-to-release/dev17.12
2 parents 1b491f6 + b475ab7 commit db079bb

File tree

3 files changed

+37
-22
lines changed

3 files changed

+37
-22
lines changed

src/Compiler/Checking/ConstraintSolver.fs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,9 +2644,13 @@ and SolveNullnessSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 (trace: Opti
26442644
| NullnessInfo.AmbivalentToNull -> ()
26452645
| NullnessInfo.WithNull -> ()
26462646
| NullnessInfo.WithoutNull ->
2647-
if g.checkNullness then
2648-
// TODO nullness: Shouldn't this be an error? We have a 'must support null' situation which is not being met.
2649-
return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2))
2647+
if g.checkNullness then
2648+
// If a type would allow null in older rules of F#, we can just emit a warning.
2649+
// In the opposite case, we keep this as an an error to avoid generating incorrect code (e.g. assigning null to an int)
2650+
if (TypeNullIsExtraValue g m ty) then
2651+
return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2))
2652+
else
2653+
return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2))
26502654
}
26512655

26522656
and SolveTypeUseNotSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty =

tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ let maybeAnon2 : {|Hello:string|} | null = null
458458
|> shouldFail
459459
|> withDiagnostics
460460
[ Error 3260, Line 4, Col 18, Line 4, Col 41, "The type '{| Hello: string |}' does not support a nullness qualitification."
461-
Error 3261, Line 4, Col 44, Line 4, Col 48, "Nullness warning: The type '{| Hello: string |}' does not support 'null'."]
461+
Error 43, Line 4, Col 44, Line 4, Col 48, "The type '{| Hello: string |}' does not have 'null' as a proper value"]
462462

463463

464464
[<Fact>]
@@ -567,8 +567,8 @@ myGenericFunction myValOfX
567567
|> shouldFail
568568
|> withDiagnostics
569569
[Error 3261, Line 13, Col 19, Line 13, Col 28, "Nullness warning: The type 'string' does not support 'null'."
570-
Error 3261, Line 15, Col 20, Line 15, Col 39, "Nullness warning: The type 'System.DateTime' does not support 'null'."
571-
Error 3261, Line 16, Col 19, Line 16, Col 22, "Nullness warning: The type 'int' does not support 'null'."]
570+
Error 193, Line 15, Col 20, Line 15, Col 39, "The type 'System.DateTime' does not have 'null' as a proper value"
571+
Error 1, Line 16, Col 19, Line 16, Col 22, "The type 'int' does not have 'null' as a proper value"]
572572

573573
[<Fact>]
574574
let ``Null assignment in generic code`` () =
@@ -602,10 +602,28 @@ myNullReturningFunction myValOfY |> ignore
602602
|> shouldFail
603603
|> withDiagnostics
604604
[Error 3261, Line 17, Col 25, Line 17, Col 34, "Nullness warning: The type 'string' does not support 'null'."
605-
Error 3261, Line 19, Col 26, Line 19, Col 45, "Nullness warning: The type 'System.DateTime' does not support 'null'."
606-
Error 3261, Line 20, Col 25, Line 20, Col 36, "Nullness warning: The type '{| Anon: 'a |}' does not support 'null'."
607-
Error 3261, Line 21, Col 26, Line 21, Col 31, "Nullness warning: The type '('a * 'b * 'c)' does not support 'null'."
608-
Error 3261, Line 23, Col 25, Line 23, Col 33, "Nullness warning: The type 'Y' does not support 'null'."]
605+
Error 193, Line 19, Col 26, Line 19, Col 45, "The type 'System.DateTime' does not have 'null' as a proper value"
606+
Error 1, Line 20, Col 25, Line 20, Col 36, "The type '{| Anon: 'a |}' does not have 'null' as a proper value"
607+
Error 1, Line 21, Col 26, Line 21, Col 31, "The type '('a * 'b * 'c)' does not have 'null' as a proper value"
608+
Error 1, Line 23, Col 25, Line 23, Col 33, "The type 'Y' does not have 'null' as a proper value"]
609+
610+
611+
[<Fact>]
612+
let ``Match null with int`` () =
613+
FSharp """module MyLibrary
614+
let test =
615+
match null with
616+
| null -> true
617+
| 42 -> false
618+
619+
"""
620+
|> asLibrary
621+
|> typeCheckWithStrictNullness
622+
|> shouldFail
623+
|> withDiagnostics
624+
[Error 1, Line 5, Col 7, Line 5, Col 9, "The type 'int' does not have 'null' as a proper value. See also test.fs(3,10)-(3,14)."
625+
Error 25, Line 3, Col 11, Line 3, Col 15, "Incomplete pattern matches on this expression."]
626+
609627

610628
[<Fact>]
611629
let ``Nullnesss support for F# types`` () =
@@ -658,10 +676,10 @@ looseFunc(maybeTuple2) |> ignore
658676
|> withDiagnostics
659677
[ Error 43, Line 21, Col 12, Line 21, Col 16, "The constraints 'null' and 'not null' are inconsistent"
660678
Error 3260, Line 27, Col 18, Line 27, Col 34, "The type '(int * int)' does not support a nullness qualitification."
661-
Error 3261, Line 27, Col 37, Line 27, Col 41, "Nullness warning: The type '(int * int)' does not support 'null'."
679+
Error 43, Line 27, Col 37, Line 27, Col 41, "The type '(int * int)' does not have 'null' as a proper value"
662680
Error 3261, Line 29, Col 12, Line 29, Col 19, "Nullness warning: The type 'MyDu | null' supports 'null' but a non-null type is expected."
663681
Error 3261, Line 30, Col 12, Line 30, Col 21, "Nullness warning: The type 'MyRecord | null' supports 'null' but a non-null type is expected."
664-
Error 3261, Line 40, Col 36, Line 40, Col 40, "Nullness warning: The type 'Maybe<int * int>' does not support 'null'."]
682+
Error 43, Line 40, Col 36, Line 40, Col 40, "The type 'Maybe<int * int>' does not have 'null' as a proper value"]
665683

666684
[<Fact>]
667685
let ``Static member on Record with null arg`` () =
Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
existing-negative.fs (10,17)-(10,33) typecheck error Nullness warning: The type '(int * int)' does not support 'null'.
2-
existing-negative.fs (12,17)-(12,28) typecheck error Nullness warning: The type 'int list' does not support 'null'.
3-
existing-negative.fs (14,17)-(14,30) typecheck error Nullness warning: The type '(int -> int)' does not support 'null'.
4-
existing-negative.fs (22,25)-(22,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
5-
existing-negative.fs (27,25)-(27,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
6-
existing-negative.fs (32,25)-(32,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
7-
existing-negative.fs (37,25)-(37,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
8-
existing-negative.fs (43,25)-(43,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
9-
existing-negative.fs (47,25)-(47,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
10-
existing-negative.fs (51,25)-(51,31) typecheck error The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check
1+
existing-negative.fs (10,17)-(10,33) typecheck error The type '(int * int)' does not have 'null' as a proper value
2+
existing-negative.fs (12,17)-(12,28) typecheck error The type 'int list' does not have 'null' as a proper value
3+
existing-negative.fs (14,17)-(14,30) typecheck error The type '(int -> int)' does not have 'null' as a proper value

0 commit comments

Comments
 (0)