diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index aea6037fc6..88cabb5af7 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -18,9 +18,9 @@ * Fix active pattern typechecking regression. ([Issue #18638](https://github.com/dotnet/fsharp/issues/18638), [PR #18642](https://github.com/dotnet/fsharp/pull/18642)) * Fix nullness warnings when casting non-nullable values to `IEquatable` to match C# behavior. ([Issue #18759](https://github.com/dotnet/fsharp/issues/18759)) * Fix IsByRefLikeAttribute types being incorrectly suppressed in completion lists. Types like `Span` and `ReadOnlySpan` now appear correctly in IntelliSense. - * Fix SRTP nullness constraint resolution for types imported from older assemblies. AmbivalentToNull types now use legacy F# nullness rules instead of always satisfying `'T : null` constraints. ([Issue #18390](https://github.com/dotnet/fsharp/issues/18390), [Issue #18344](https://github.com/dotnet/fsharp/issues/18344)) * Fix Show XML doc for enum fields in external metadata ([Issue #17939](https://github.com/dotnet/fsharp/issues/17939#issuecomment-3137410105), [PR #18800](https://github.com/dotnet/fsharp/pull/18800)) +* Fix nullable types formatting in `FSharpType.Format` and tooltips to include parentheses. ([PR #18842](https://github.com/dotnet/fsharp/pull/18842)) * TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851)) ### Changed diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 66b26e43a9..00b6f4c0b5 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -145,6 +145,9 @@ module internal PrintUtilities = | [x] -> [resultFunction x (layoutFunction x)] | x :: rest -> [ resultFunction x (layoutFunction x -- leftL (tagText (match rest.Length with 1 -> FSComp.SR.nicePrintOtherOverloads1() | n -> FSComp.SR.nicePrintOtherOverloadsN(n)))) ] | _ -> [] + + let showNullness (denv: DisplayEnv) (nullness: Nullness) = + denv.showNullnessAnnotations <> Some false && nullness.Evaluate() = NullnessInfo.WithNull let tagEntityRefName(denv: DisplayEnv) (xref: EntityRef) name = if xref.IsNamespace then tagNamespace name @@ -942,15 +945,12 @@ module PrintTypes = | [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ tcL | args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithInfoAndPrec denv env 2 SepL.comma args) --- tcL) - and layoutNullness (denv: DisplayEnv) part2 (nullness: Nullness) = + and layoutNullness (denv: DisplayEnv) part2 (nullness: Nullness) prec = // Show nullness annotations unless explicitly turned off - if denv.showNullnessAnnotations <> Some false then - match nullness.Evaluate() with - | NullnessInfo.WithNull -> part2 ^^ wordL (tagPunctuation "|") ^^ wordL (tagKeyword "null") - | NullnessInfo.WithoutNull -> part2 - | NullnessInfo.AmbivalentToNull -> part2 //^^ wordL (tagText "__maybenull") + if showNullness denv nullness then + part2 ^^ wordL (tagPunctuation "|") ^^ wordL (tagKeyword "null") |> bracketIfL (prec <= 3) else - part2 + part2 // if NullnessInfo.AmbivalentToNull -> part2 ^^ wordL (tagText "__maybenull") /// Layout a type, taking precedence into account to insert brackets where needed and layoutTypeWithInfoAndPrec denv env prec ty = @@ -1014,7 +1014,7 @@ module PrintTypes = prefix args - let part2 = layoutNullness denv part1 nullness + let part2 = layoutNullness denv part1 nullness prec part2 // Layout a tuple type @@ -1046,14 +1046,15 @@ module PrintTypes = let retTyL = layoutTypeWithInfoAndPrec denv env 5 retTy let argTysL = argTys |> List.map (layoutTypeWithInfoAndPrec denv env 4) let funcTyL = curriedLayoutsL arrow argTysL retTyL - let part1 = bracketIfL (prec <= 4) funcTyL - let part2 = layoutNullness denv part1 nullness + let showNull = showNullness denv nullness + let part1 = bracketIfL (prec <= 4 || showNull) funcTyL + let part2 = layoutNullness denv part1 nullness prec part2 // Layout a type variable . | TType_var (r, nullness) -> let part1 = layoutTyparRefWithInfo denv env r - let part2 = layoutNullness denv part1 nullness + let part2 = layoutNullness denv part1 nullness prec part2 | TType_measure unt -> layoutMeasure denv unt @@ -1104,8 +1105,13 @@ module PrintTypes = // Layout an unnamed argument // Cannot have any attributes - | None, _, _ -> - layoutTypeWithInfoAndPrec denv env 2 ty + | None, _, _ -> + let prec = + match ty with + | TType_tuple _ -> 2 + | _ -> 4 + + layoutTypeWithInfoAndPrec denv env prec ty // Layout a named argument | Some id, _, _ -> @@ -2945,7 +2951,7 @@ let minimalStringOfType denv ty = let ty, _cxs = PrettyTypes.PrettifyType denv.g ty let denv = suppressNullnessAnnotations denv let denvMin = { denv with showInferenceTyparAnnotations=false; showStaticallyResolvedTyparAnnotations=false } - showL (PrintTypes.layoutTypeWithInfoAndPrec denvMin SimplifyTypes.typeSimplificationInfo0 2 ty) + showL (PrintTypes.layoutTypeWithInfoAndPrec denvMin SimplifyTypes.typeSimplificationInfo0 5 ty) let minimalStringOfTypeWithNullness denv ty = minimalStringOfType {denv with showNullnessAnnotations = Some true} ty diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs index 533369961e..d3fad55a53 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/InferenceProcedures/ByrefSafetyAnalysis/ByrefSafetyAnalysis.fs @@ -69,29 +69,29 @@ module ByrefSafetyAnalysis = (Error 438, Line 113, Col 23, Line 113, Col 33, "Duplicate method. The method 'TestMethod' has the same name and signature as another method in type 'NegativeTests.TestNegativeOverloading'.") (Error 412, Line 121, Col 18, Line 121, Col 22, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 123, Col 18, Line 123, Col 23, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") - (Error 3301, Line 125, Col 9, Line 125, Col 14, "The function or method has an invalid return type '(byref * int)'. This is not permitted by the rules of Common IL.") + (Error 3301, Line 125, Col 9, Line 125, Col 14, "The function or method has an invalid return type 'byref * int'. This is not permitted by the rules of Common IL.") (Error 412, Line 125, Col 34, Line 125, Col 39, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 418, Line 125, Col 35, Line 125, Col 36, "The byref typed value 'x' cannot be used at this point") - (Error 3301, Line 127, Col 9, Line 127, Col 14, "The function or method has an invalid return type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 3301, Line 127, Col 9, Line 127, Col 14, "The function or method has an invalid return type 'byref -> unit'. This is not permitted by the rules of Common IL.") (Error 412, Line 129, Col 14, Line 129, Col 15, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") - (Error 3300, Line 131, Col 17, Line 131, Col 18, "The parameter 'x' has an invalid type '((byref -> unit) * int)'. This is not permitted by the rules of Common IL.") - (Error 3300, Line 133, Col 17, Line 133, Col 18, "The parameter 'x' has an invalid type '(byref -> unit)'. This is not permitted by the rules of Common IL.") - (Error 3300, Line 133, Col 41, Line 133, Col 42, "The parameter 'y' has an invalid type '(byref * int)'. This is not permitted by the rules of Common IL.") - (Error 3300, Line 139, Col 36, Line 139, Col 39, "The parameter 'tup' has an invalid type '(inref * int)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 131, Col 17, Line 131, Col 18, "The parameter 'x' has an invalid type '(byref -> unit) * int'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 133, Col 17, Line 133, Col 18, "The parameter 'x' has an invalid type 'byref -> unit'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 133, Col 41, Line 133, Col 42, "The parameter 'y' has an invalid type 'byref * int'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 139, Col 36, Line 139, Col 39, "The parameter 'tup' has an invalid type 'inref * int'. This is not permitted by the rules of Common IL.") (Error 412, Line 140, Col 13, Line 140, Col 33, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") - (Error 3300, Line 142, Col 37, Line 142, Col 38, "The parameter 'x' has an invalid type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 142, Col 37, Line 142, Col 38, "The parameter 'x' has an invalid type 'byref -> unit'. This is not permitted by the rules of Common IL.") (Error 3300, Line 144, Col 37, Line 144, Col 38, "The parameter 'x' has an invalid type 'byref option'. This is not permitted by the rules of Common IL.") (Error 3300, Line 146, Col 17, Line 146, Col 18, "The parameter 'x' has an invalid type 'byref option'. This is not permitted by the rules of Common IL.") (Error 412, Line 151, Col 13, Line 151, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 151, Col 17, Line 151, Col 30, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") - (Error 3301, Line 154, Col 9, Line 154, Col 15, "The function or method has an invalid return type '(byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 3301, Line 154, Col 9, Line 154, Col 15, "The function or method has an invalid return type 'byref -> unit'. This is not permitted by the rules of Common IL.") (Error 412, Line 155, Col 9, Line 155, Col 22, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 158, Col 13, Line 158, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 160, Col 13, Line 160, Col 26, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 165, Col 9, Line 165, Col 22, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 169, Col 13, Line 169, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 169, Col 17, Line 169, Col 28, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") - (Error 3301, Line 172, Col 9, Line 172, Col 15, "The function or method has an invalid return type '(int -> byref -> unit)'. This is not permitted by the rules of Common IL.") + (Error 3301, Line 172, Col 9, Line 172, Col 15, "The function or method has an invalid return type 'int -> byref -> unit'. This is not permitted by the rules of Common IL.") (Error 412, Line 173, Col 9, Line 173, Col 20, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 176, Col 13, Line 176, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 178, Col 13, Line 178, Col 24, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") @@ -102,7 +102,7 @@ module ByrefSafetyAnalysis = (Error 412, Line 191, Col 13, Line 191, Col 14, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 193, Col 13, Line 193, Col 28, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 198, Col 9, Line 198, Col 24, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") - (Error 3301, Line 201, Col 9, Line 201, Col 15, "The function or method has an invalid return type '(byref * int)'. This is not permitted by the rules of Common IL.") + (Error 3301, Line 201, Col 9, Line 201, Col 15, "The function or method has an invalid return type 'byref * int'. This is not permitted by the rules of Common IL.") (Error 412, Line 203, Col 10, Line 203, Col 15, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 421, Line 203, Col 11, Line 203, Col 12, "The address of the variable 'x' cannot be used at this point") (Error 412, Line 206, Col 9, Line 206, Col 18, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") @@ -807,7 +807,7 @@ type outref<'T> with |> compile |> shouldFail |> withDiagnostics [ - (Error 3300, Line 5, Col 18, Line 5, Col 19, "The parameter 'f' has an invalid type '(byref -> 'a)'. This is not permitted by the rules of Common IL.") + (Error 3300, Line 5, Col 18, Line 5, Col 19, "The parameter 'f' has an invalid type 'byref -> 'a'. This is not permitted by the rules of Common IL.") (Error 424, Line 7, Col 6, Line 7, Col 13, "The address of an array element cannot be used at this point") (Error 412, Line 9, Col 19, Line 9, Col 20, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") (Error 412, Line 11, Col 19, Line 11, Col 20, "A type instantiation involves a byref type. This is not permitted by the rules of Common IL.") diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs index 6cffe31c23..5cc6dbde27 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnionCasePatternMatchingErrors.fs @@ -24,7 +24,7 @@ let myVal = \tf1: int list \t{| X: string |} \tf3: U -\tf4: (int * System.String)") +\tf4: int * System.String") [] let ``Union matching error - Named args - Name used twice`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs index 4d0710ba89..de591b580a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs @@ -103,7 +103,7 @@ let main _args = |> withDiagnostics [ Error 3265, Line 13, Col 13, Line 13, Col 60, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for '{| x: int |}'. Nullness warnings won't be reported correctly for such types." Error 3265, Line 14, Col 13, Line 14, Col 51, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for 'System.Int32'. Nullness warnings won't be reported correctly for such types." - Error 3265, Line 15, Col 13, Line 15, Col 59, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for '(int * float)'. Nullness warnings won't be reported correctly for such types." + Error 3265, Line 15, Col 13, Line 15, Col 59, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for 'int * float'. Nullness warnings won't be reported correctly for such types." Error 3265, Line 16, Col 13, Line 16, Col 67, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for 'struct (int * float)'. Nullness warnings won't be reported correctly for such types." Error 3265, Line 17, Col 13, Line 17, Col 57, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for 'int'. Nullness warnings won't be reported correctly for such types." Error 3265, Line 18, Col 13, Line 18, Col 57, "Application of method 'Deserialize' attempted to create a nullable type ('T | null) for 'int'. Nullness warnings won't be reported correctly for such types."] @@ -152,7 +152,7 @@ let doNotWarnOnDowncastRepeatedNestedNullable(o:objnull) = o :? list<((AB | null [ Error 3264, Line 4, Col 39, Line 4, Col 47, "Nullness warning: Downcasting from 'objnull' into 'AB' can introduce unexpected null values. Cast to 'AB|null' instead or handle the null before downcasting." Error 3060, Line 5, Col 42, Line 5, Col 59, "This type test or downcast will erase the provided type 'AB | null' to the type 'AB'" Error 3060, Line 6, Col 41, Line 6, Col 55, "This type test or downcast will erase the provided type 'AB | null' to the type 'AB'" - Error 3060, Line 7, Col 51, Line 7, Col 97, "This type test or downcast will erase the provided type 'List | null' to the type 'List'"] + Error 3060, Line 7, Col 51, Line 7, Col 97, "This type test or downcast will erase the provided type 'List<(AB | null) array | null> | null' to the type 'List'"] [] @@ -611,7 +611,7 @@ let f6(x: 'a | null when 'a:null) = () [ Error 3261, Line 3, Col 11, Line 3, Col 32, "Nullness warning: The type 'string option' uses 'null' as a representation value but a non-null type is expected." Error 3260, Line 4, Col 11, Line 4, Col 21, "The type 'int' does not support a nullness qualification." Error 43, Line 4, Col 11, Line 4, Col 21, "A generic construct requires that the type 'int' have reference semantics, but it does not, i.e. it is a struct" - Error 3260, Line 5, Col 11, Line 5, Col 25, "The type '('a * 'b)' does not support a nullness qualification." + Error 3260, Line 5, Col 11, Line 5, Col 25, "The type ''a * 'b' does not support a nullness qualification." Error 3261, Line 6, Col 11, Line 6, Col 28, "Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected." Error 43, Line 7, Col 28, Line 7, Col 37, "The constraints 'struct' and 'not struct' are inconsistent" Error 43, Line 8, Col 26, Line 8, Col 33, "The constraints 'null' and 'not null' are inconsistent"] @@ -1013,7 +1013,7 @@ myNullReturningFunction myValOfY |> ignore [Error 3261, Line 17, Col 25, Line 17, Col 34, "Nullness warning: The type 'string' does not support 'null'." Error 193, Line 19, Col 26, Line 19, Col 45, "The type 'System.DateTime' does not have 'null' as a proper value" Error 1, Line 20, Col 25, Line 20, Col 36, "The type '{| Anon: 'a |}' does not have 'null' as a proper value" - Error 1, Line 21, Col 26, Line 21, Col 31, "The type '('a * 'b * 'c)' does not have 'null' as a proper value" + Error 1, Line 21, Col 26, Line 21, Col 31, "The type ''a * 'b * 'c' does not have 'null' as a proper value" Error 1, Line 23, Col 25, Line 23, Col 33, "The type 'Y' does not have 'null' as a proper value"] @@ -1084,8 +1084,8 @@ looseFunc(maybeTuple2) |> ignore |> shouldFail |> withDiagnostics [ Error 43, Line 21, Col 12, Line 21, Col 16, "The constraints 'null' and 'not null' are inconsistent" - Error 3260, Line 27, Col 18, Line 27, Col 34, "The type '(int * int)' does not support a nullness qualification." - Error 43, Line 27, Col 37, Line 27, Col 41, "The type '(int * int)' does not have 'null' as a proper value" + Error 3260, Line 27, Col 18, Line 27, Col 34, "The type 'int * int' does not support a nullness qualification." + Error 43, Line 27, Col 37, Line 27, Col 41, "The type 'int * int' does not have 'null' as a proper value" 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." 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." Error 43, Line 40, Col 36, Line 40, Col 40, "The type 'Maybe' does not have 'null' as a proper value"] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs index 7698f34fbb..bd3d90a807 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs @@ -44,7 +44,7 @@ let ``Signature conformance`` langVersion checknulls = |> withDiagnostics [Warning 3262, Line 18, Col 48, Line 18, Col 60, "Value known to be without null passed to a function meant for nullables: You can create 'Some value' directly instead of 'ofObj', or consider not using an option for this value." (Warning 3261, Line 4, Col 5, Line 4, Col 10, "Nullness warning: Module 'M' contains - val test2: x: string | null -> unit + val test2: x: (string | null) -> unit but its signature specifies val test2: string -> unit The types differ in their nullness annotations"); @@ -54,7 +54,7 @@ let ``Signature conformance`` langVersion checknulls = val test1: string | null -> unit The types differ in their nullness annotations"); (Warning 3261, Line 6, Col 5, Line 6, Col 17, "Nullness warning: Module 'M' contains - val iRejectNulls: x: string | null -> string + val iRejectNulls: x: (string | null) -> string but its signature specifies val iRejectNulls: string -> string The types differ in their nullness annotations"); diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl index eaffe804e9..698d7e1842 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl @@ -1,3 +1,3 @@ -existing-negative.fs (10,17)-(10,33) typecheck error The type '(int * int)' does not have 'null' as a proper value +existing-negative.fs (10,17)-(10,33) typecheck error The type 'int * int' does not have 'null' as a proper value existing-negative.fs (12,17)-(12,28) typecheck error The type 'int list' does not have 'null' as a proper value -existing-negative.fs (14,17)-(14,30) typecheck error The type '(int -> int)' does not have 'null' as a proper value \ No newline at end of file +existing-negative.fs (14,17)-(14,30) typecheck error The type 'int -> int' does not have 'null' as a proper value \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl index eaffe804e9..698d7e1842 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl @@ -1,3 +1,3 @@ -existing-negative.fs (10,17)-(10,33) typecheck error The type '(int * int)' does not have 'null' as a proper value +existing-negative.fs (10,17)-(10,33) typecheck error The type 'int * int' does not have 'null' as a proper value existing-negative.fs (12,17)-(12,28) typecheck error The type 'int list' does not have 'null' as a proper value -existing-negative.fs (14,17)-(14,30) typecheck error The type '(int -> int)' does not have 'null' as a proper value \ No newline at end of file +existing-negative.fs (14,17)-(14,30) typecheck error The type 'int -> int' does not have 'null' as a proper value \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs b/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs index cf87069807..f4da930e4d 100644 --- a/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/PatternMatchCompilationTests.fs @@ -65,7 +65,7 @@ match 1, 2 with """ assertHasSymbolUsages ["y"] checkResults dumpDiagnostics checkResults |> shouldEqual [ - "(3,2--3,6): The type '(int * int)' does not have 'null' as a proper value" + "(3,2--3,6): The type 'int * int' does not have 'null' as a proper value" "(2,6--2,10): Incomplete pattern matches on this expression. For example, the value '``some-non-null-value``' may indicate a case not covered by the pattern(s)." ] diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs index 44dc501458..b5126bf1ca 100644 --- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs +++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs @@ -503,6 +503,31 @@ let f2 b1 b2 b3 b4 b5 = | _ -> () | _ -> () + [] + [] + [] + [] + [] + [] + [ int) | null", "(int -> int) | null")>] + [ int) | null) list", "((int -> int) | null) list")>] + [ int) | null -> int) | null", "((int -> int) | null -> int) | null")>] + [ string | null", "int -> string | null")>] + [ int", "string | null -> int")>] + [ int * string | null", "int -> int * (string | null)")>] + [ string | null -> int", "int -> string | null -> int")>] + [] + [] + let ``Nullable types`` declaredType formattedType = + let _, checkResults = getParseAndCheckResults $""" +let f (x: {declaredType}) = () +""" + let symbolUse = findSymbolUseByName "x" checkResults + let symbol = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue + let typeArg = symbol.FullType + typeArg.Format(symbolUse.DisplayContext) |> shouldEqual formattedType + + module FSharpMemberOrFunctionOrValue = let private chooseMemberOrFunctionOrValue (su: FSharpSymbolUse) = match su.Symbol with :? FSharpMemberOrFunctionOrValue as mfv -> Some mfv | _ -> None diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs index 9fd5f364b0..92d30a3e4c 100644 --- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs @@ -403,6 +403,19 @@ type Bar() = |> assertAndGetSingleToolTipText |> Assert.shouldBeEquivalentTo "property Bar.Foo: string with get, set" +[] +[] +[ int) | null", "val x: (int -> int) | null")>] +[] +let ``Should display correct nullable types`` declaredType tooltip = + Checker.getTooltip $""" +module Foo + +let f (x{{caret}}: {declaredType}) = () +""" + |> assertAndGetSingleToolTipText + |> Assert.shouldBeEquivalentTo tooltip + [] let ``Should display nullable Csharp code analysis annotations on method argument`` () = Checker.getTooltipWithOptions [|"--checknulls+";"--langversion:preview"|] """ @@ -444,7 +457,7 @@ let exists() = myFu{caret}nc(null) | FSharpXmlDoc.FromXmlText t -> t.UnprocessedLines |> Assert.shouldBeEquivalentTo [|" This is a xml doc above myFunc"|] | _ -> failwith $"xml was %A{xml}" - text |> Assert.shouldBeEquivalentTo "val myFunc: x: string | null -> string | null" + text |> Assert.shouldBeEquivalentTo "val myFunc: x: (string | null) -> string | null" remarks |> Assert.shouldBeEquivalentTo (Some "Full name: Foo.myFunc") diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index e54acb26cc..fa6efcd415 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -60,7 +60,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x00000015][found Boolean] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2072-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2078-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000033][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000063][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000AD][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index 93f96640c2..2d4f609d6d 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -65,7 +65,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000012][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1875'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,T0>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000040][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x0000000B][found Boolean] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2072-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2078-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000034][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000074][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000A8][found Char] Unexpected type on the stack. diff --git a/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs b/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs index b6597769b4..d4d0929242 100644 --- a/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs +++ b/tests/fsharp/Compiler/Libraries/Core/Operators/HashTests.fs @@ -23,7 +23,7 @@ hash id |> ignore FSharpDiagnosticSeverity.Error 1 (2, 6, 2, 8) - "The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type" + "The type ''a -> 'a' does not support the 'equality' constraint because it is a function type" [] let ``Unchecked hash of function values``() = diff --git a/tests/fsharp/typecheck/sigs/neg10.bsl b/tests/fsharp/typecheck/sigs/neg10.bsl index 64fcc4eefb..02bc048499 100644 --- a/tests/fsharp/typecheck/sigs/neg10.bsl +++ b/tests/fsharp/typecheck/sigs/neg10.bsl @@ -122,11 +122,11 @@ neg10.fs(245,50,245,51): typecheck error FS0193: A type parameter is missing a c neg10.fs(245,17,245,20): typecheck error FS0043: A type parameter is missing a constraint 'when 'b :> C' -neg10.fs(251,49,251,61): typecheck error FS0001: The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type +neg10.fs(251,49,251,61): typecheck error FS0001: The type ''a -> 'a' does not support the 'equality' constraint because it is a function type -neg10.fs(252,45,252,57): typecheck error FS0001: The type '('a -> 'a)' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface +neg10.fs(252,45,252,57): typecheck error FS0001: The type ''a -> 'a' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface -neg10.fs(253,36,253,48): typecheck error FS0001: The type '('a -> 'a)' does not support the 'equality' constraint because it is a function type +neg10.fs(253,36,253,48): typecheck error FS0001: The type ''a -> 'a' does not support the 'equality' constraint because it is a function type neg10.fs(297,17,297,24): typecheck error FS1187: An indexer property must be given at least one argument diff --git a/tests/fsharp/typecheck/sigs/neg107.bsl b/tests/fsharp/typecheck/sigs/neg107.bsl index 580233b477..19de477f8a 100644 --- a/tests/fsharp/typecheck/sigs/neg107.bsl +++ b/tests/fsharp/typecheck/sigs/neg107.bsl @@ -3,7 +3,7 @@ neg107.fsx(25,48,25,59): typecheck error FS0406: The byref-typed variable 'a' is neg107.fsx(26,69,26,80): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(27,13,27,25): typecheck error FS3301: The function or method has an invalid return type '(unit -> Span)'. This is not permitted by the rules of Common IL. +neg107.fsx(27,13,27,25): typecheck error FS3301: The function or method has an invalid return type 'unit -> Span'. This is not permitted by the rules of Common IL. neg107.fsx(27,43,27,59): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. @@ -17,7 +17,7 @@ neg107.fsx(27,57,27,58): typecheck error FS0418: The byref typed value 'a' canno neg107.fsx(27,47,27,58): typecheck error FS0425: The type of a first-class function cannot contain byrefs -neg107.fsx(28,13,28,25): typecheck error FS3301: The function or method has an invalid return type '(unit -> ReadOnlySpan)'. This is not permitted by the rules of Common IL. +neg107.fsx(28,13,28,25): typecheck error FS3301: The function or method has an invalid return type 'unit -> ReadOnlySpan'. This is not permitted by the rules of Common IL. neg107.fsx(28,51,28,67): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharp/typecheck/sigs/neg107.vsbsl b/tests/fsharp/typecheck/sigs/neg107.vsbsl index 580233b477..19de477f8a 100644 --- a/tests/fsharp/typecheck/sigs/neg107.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg107.vsbsl @@ -3,7 +3,7 @@ neg107.fsx(25,48,25,59): typecheck error FS0406: The byref-typed variable 'a' is neg107.fsx(26,69,26,80): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. -neg107.fsx(27,13,27,25): typecheck error FS3301: The function or method has an invalid return type '(unit -> Span)'. This is not permitted by the rules of Common IL. +neg107.fsx(27,13,27,25): typecheck error FS3301: The function or method has an invalid return type 'unit -> Span'. This is not permitted by the rules of Common IL. neg107.fsx(27,43,27,59): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. @@ -17,7 +17,7 @@ neg107.fsx(27,57,27,58): typecheck error FS0418: The byref typed value 'a' canno neg107.fsx(27,47,27,58): typecheck error FS0425: The type of a first-class function cannot contain byrefs -neg107.fsx(28,13,28,25): typecheck error FS3301: The function or method has an invalid return type '(unit -> ReadOnlySpan)'. This is not permitted by the rules of Common IL. +neg107.fsx(28,13,28,25): typecheck error FS3301: The function or method has an invalid return type 'unit -> ReadOnlySpan'. This is not permitted by the rules of Common IL. neg107.fsx(28,51,28,67): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fs b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fs index ff1a53ea7a..b609d716ee 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fs +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fs @@ -1,6 +1,6 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//Type '\(string -> byref> -> bool\)' is illegal because in byref, T cannot contain byref types\.$ +//Type 'string -> byref> -> bool' is illegal because in byref, T cannot contain byref types\.$ //Type 'byref>' is illegal because in byref, T cannot contain byref types\.$ module M // SHould give an error - not ICE! diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fsx b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fsx index 75069a4cbd..75d9811ec7 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fsx +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef01.fsx @@ -1,6 +1,6 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//Type '\(string -> byref> -> bool\)' is illegal because in byref, T cannot contain byref types\.$ +//Type 'string -> byref> -> bool' is illegal because in byref, T cannot contain byref types\.$ // SHould give an error - not ICE! let inline f x (y:_ byref) = (^a : (static member TryParse : string * ^a byref -> bool)(x,y)) diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fs b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fs index 9ddc03c0c3..cc23f2001b 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fs +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fs @@ -1,6 +1,6 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//Type '\('a -> string -> byref> -> bool\)' is illegal because in byref, T cannot contain byref types\.$ +//Type ''a -> string -> byref> -> bool' is illegal because in byref, T cannot contain byref types\.$ //Type 'byref>' is illegal because in byref, T cannot contain byref types\.$ module M // SHould give an error - not ICE! diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fsx b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fsx index e09db645b8..976795013a 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fsx +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef02.fsx @@ -1,6 +1,6 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//Type '\('a -> string -> byref> -> bool\)' is illegal because in byref, T cannot contain byref types\.$ +//Type ''a -> string -> byref> -> bool' is illegal because in byref, T cannot contain byref types\.$ // SHould give an error - not ICE! let inline f (_:^a) x (y:_ byref) = (^a : (static member TryParse : string * ^a byref -> bool)(x,y)) diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fs b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fs index 52ab6d2c51..da5ad234da 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fs +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fs @@ -1,6 +1,6 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//Type '\(string -> byref>> -> bool\)' is illegal because in byref, T cannot contain byref types\.$ +//Type 'string -> byref>> -> bool' is illegal because in byref, T cannot contain byref types\.$ //Type 'byref>>' is illegal because in byref, T cannot contain byref types\.$ module M // SHould give an error - not ICE! diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fsx b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fsx index 57b48a417e..c5393f9525 100644 --- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fsx +++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/CheckingSyntacticTypes/E_ByRef03.fsx @@ -1,6 +1,6 @@ // #ByRef #Regression #inline // Regression test for DevDiv:122445 ("Internal compiler error when evaluating code with inline/byref") -//Type '\(string -> byref>> -> bool\)' is illegal because in byref, T cannot contain byref types\.$ +//Type 'string -> byref>> -> bool' is illegal because in byref, T cannot contain byref types\.$ // SHould give an error - not ICE! let inline f x (y:_ byref byref) = (^a : (static member TryParse : string * ^a byref byref -> bool)(x,y))