From e74bbf9d58d4aff7b70f3fa2e163f5bd59226aad Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 12 Jun 2024 15:23:20 +0200 Subject: [PATCH 1/7] cleanups --- src/Compiler/AbstractIL/ilread.fs | 2 +- src/Compiler/Checking/CheckExpressions.fs | 1 + src/Compiler/Checking/ConstraintSolver.fs | 5 +---- src/Compiler/Checking/import.fs | 15 ++++++++++----- src/Compiler/Checking/infos.fs | 2 +- src/Compiler/TypedTree/TcGlobals.fs | 4 ++-- src/Compiler/TypedTree/TypedTreeBasics.fs | 14 ++++---------- src/Compiler/TypedTree/TypedTreeOps.fs | 2 +- .../Microsoft.FSharp.Core/BigIntType.fs | 2 +- .../Microsoft.FSharp.Core/OptionModule.fs | 4 ++-- 10 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index 698b14ccc2e..f372f6253c1 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -930,7 +930,7 @@ let mkCacheGeneric lowMem _inbase _nm (sz: int) = if lowMem then (fun f x -> f x) else - let mutable cache: ConcurrentDictionary<_, _> MaybeNull = null // TODO NULLNESS: this explicit annotation should not be needed + let mutable cache = null #if STATISTICS addReport (fun oc -> diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index e04e822d14c..de0a51edce9 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5205,6 +5205,7 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags | TyparConstraint.IsDelegate _ | TyparConstraint.IsEnum _ | TyparConstraint.IsNonNullableStruct _ + | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsUnmanaged _ | TyparConstraint.RequiresDefaultConstructor _ | TyparConstraint.SimpleChoice _ diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 299850d542f..dd2faa900aa 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -1062,8 +1062,7 @@ and SolveNullnessEquiv (csenv: ConstraintSolverEnv) m2 (trace: OptionalTrace) ty // Warn for 'strict "must pass null"` APIs like Option.ofObj | NullnessInfo.WithNull, NullnessInfo.WithoutNull when shouldWarnUselessNullCheck csenv -> WarnD(Error(FSComp.SR.tcPassingWithoutNullToANullableExpectingFunc (csenv.SolverState.WarnWhenUsingWithoutNullOnAWithNullTarget.Value),m2)) - // Allow expected of WithNull and actual of WithoutNull - // TODO NULLNESS: this is not sound in contravariant cases etc. It is assuming covariance. + // Allow expected of WithNull and actual of WithoutNull except for specially marked APIs (handled above) | NullnessInfo.WithNull, NullnessInfo.WithoutNull -> CompleteD | _ -> if csenv.g.checkNullness then @@ -1414,8 +1413,6 @@ and SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln origl1 origl2 = and SolveFunTypeEqn csenv ndeep m2 trace cxsln domainTy1 domainTy2 rangeTy1 rangeTy2 = trackErrors { - // TODO NULLNESS: consider whether flipping the actual and expected in argument position - // causes other problems, e.g. better/worse diagnostics let g = csenv.g let domainTy2 = reqTyForArgumentNullnessInference g domainTy1 domainTy2 do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln domainTy2 domainTy1 diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs index e2d5419e71e..df3881824bc 100644 --- a/src/Compiler/Checking/import.fs +++ b/src/Compiler/Checking/import.fs @@ -266,7 +266,9 @@ For value types, a value is passed even though it is always 0 | n when n > this.Idx -> this.Data[this.Idx] |> mapping // This is an errornous case, we need more nullnessinfo then the metadata contains | _ -> - failwithf "Length of Nullable metadata and needs of its processing do not match: %A" this // TODO nullness - once being confident that our bugs are solved and what remains are incoming metadata bugs, remove failwith and replace with dprintfn + // TODO nullness - once being confident that our bugs are solved and what remains are incoming metadata bugs, remove failwith and replace with dprintfn + // Testing with .NET compilers other then Roslyn producing nullness metadata? + failwithf "Length of Nullable metadata and needs of its processing do not match: %A" this knownAmbivalent member this.Advance() = {Data = this.Data; Idx = this.Idx + 1} @@ -274,7 +276,8 @@ For value types, a value is passed even though it is always 0 let inline evaluateFirstOrderNullnessAndAdvance (ilt:ILType) (flags:NullableFlags) = match ilt with | ILType.Value tspec when tspec.GenericArgs.IsEmpty -> KnownWithoutNull, flags - // TODO nullness - System.Nullable might be tricky, since you CAN assign 'null' to it, and when boxed, it CAN be boxed to 'null'. + // System.Nullable is special-cased in C# spec for nullnes metadata. + // You CAN assign 'null' to it, and when boxed, it CAN be boxed to 'null'. | ILType.Value tspec when tspec.Name = "Nullable`1" && tspec.Enclosing = ["System"] -> KnownWithoutNull, flags | ILType.Value _ -> KnownWithoutNull, flags.Advance() | _ -> flags.GetNullness(), flags.Advance() @@ -436,7 +439,8 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( let g = env.g if st.PUntaint((fun st -> st.IsArray), m) then let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) - let nullness = Nullness.knownAmbivalent // TODO nullness import :: type providers Nullness.ImportNullness env.g + // TODO Nullness - integration into type providers as a separate feature for later. + let nullness = Nullness.knownAmbivalent mkArrayTy g (st.PUntaint((fun st -> st.GetArrayRank()), m)) nullness elemTy m elif st.PUntaint((fun st -> st.IsByRef), m) then let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) @@ -509,7 +513,8 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( else genericArg) - let nullness = Nullness.knownAmbivalent // TODO nullness import :: type providers Nullness.ImportNullnessForTyconRef env.g m tcref + // TODO Nullness - integration into type providers as a separate feature for later. + let nullness = Nullness.knownAmbivalent ImportTyconRefApp env tcref genericArgs nullness @@ -562,7 +567,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta let formalParamTysAfterInst = [ for p in ctor.PApplyArray((fun x -> x.GetParameters()), "GetParameters", m) do let ilFormalTy = ImportProvidedTypeAsILType env m (p.PApply((fun p -> p.ParameterType), m)) - // TODO nullness import :: of Nullness in type providers + // TODO Nullness - integration into type providers as a separate feature for later. yield ImportILType env m actualGenericArgs ilFormalTy ] (formalParamTysAfterInst, actualParamTys) ||> List.lengthsEqAndForall2 (typeEquiv env.g)) diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs index de2348eb7be..6ab2bed3931 100644 --- a/src/Compiler/Checking/infos.fs +++ b/src/Compiler/Checking/infos.fs @@ -396,7 +396,7 @@ let OptionalArgInfoOfProvidedParameter (amap: ImportMap) m (provParam : Tainted< /// Compute the ILFieldInit for the given provided constant value for a provided enum type. let GetAndSanityCheckProviderMethod m (mi: Tainted<'T :> ProvidedMemberInfo>) (get : 'T -> ProvidedMethodInfo MaybeNull) err = match mi.PApply((fun mi -> (get mi :> ProvidedMethodBase MaybeNull)),m) with - | Tainted.Null -> error(Error(err(mi.PUntaint((fun mi -> mi.Name),m),mi.PUntaint((fun mi -> (nonNull mi.DeclaringType).Name), m)), m)) // TODO NULLNESS: type isntantiation should not be needed + | Tainted.Null -> error(Error(err(mi.PUntaint((fun mi -> mi.Name),m),mi.PUntaint((fun mi -> (nonNull mi.DeclaringType).Name), m)), m)) | Tainted.NonNull meth -> meth /// Try to get an arbitrary ProvidedMethodInfo associated with a property. diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs index 59c31c3c55c..d9d2270bcb4 100644 --- a/src/Compiler/TypedTree/TcGlobals.fs +++ b/src/Compiler/TypedTree/TcGlobals.fs @@ -663,12 +663,12 @@ type TcGlobals( | [_] -> None | _ -> TType_tuple (tupInfo, l) |> Some - let decodeTupleTyAndNullness tupInfo tinst _nullness = // TODO nullness + let decodeTupleTyAndNullness tupInfo tinst _nullness = match tryDecodeTupleTy tupInfo tinst with | Some ty -> ty | None -> failwith "couldn't decode tuple ty" - let decodeTupleTyAndNullnessIfPossible tcref tupInfo tinst nullness = // TODO nullness + let decodeTupleTyAndNullnessIfPossible tcref tupInfo tinst nullness = match tryDecodeTupleTy tupInfo tinst with | Some ty -> ty | None -> TType_app(tcref, tinst, nullness) diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fs b/src/Compiler/TypedTree/TypedTreeBasics.fs index 3217aca41bb..303d18fdec5 100644 --- a/src/Compiler/TypedTree/TypedTreeBasics.fs +++ b/src/Compiler/TypedTree/TypedTreeBasics.fs @@ -192,7 +192,7 @@ let KnownWithoutNull = Nullness.Known NullnessInfo.WithoutNull let mkTyparTy (tp:Typar) = match tp.Kind with - | TyparKind.Type -> tp.AsType KnownWithoutNull // TODO NULLNESS: check various callers + | TyparKind.Type -> tp.AsType KnownWithoutNull | TyparKind.Measure -> TType_measure (Measure.Var tp) // For fresh type variables clear the StaticReq when copying because the requirement will be re-established through the @@ -269,9 +269,9 @@ let tryAddNullnessToTy nullnessNew (ty:TType) = Some ty else Some (TType_app (tcr, tinst, nullnessAfter)) - | TType_ucase _ -> None // TODO NULLNESS - | TType_tuple _ -> None // TODO NULLNESS - | TType_anon _ -> None // TODO NULLNESS + | TType_ucase _ -> None + | TType_tuple _ -> None + | TType_anon _ -> None | TType_fun (d, r, nullnessOrig) -> let nullnessAfter = combineNullness nullnessOrig nullnessNew if nullnessEquiv nullnessAfter nullnessOrig then @@ -295,9 +295,6 @@ let addNullnessToTy (nullness: Nullness) (ty:TType) = else TType_app (tcr, tinst, combineNullness nullnessOrig nullness) | TType_fun (d, r, nullnessOrig) -> TType_fun (d, r, combineNullness nullnessOrig nullness) - //| TType_ucase _ -> None // TODO NULLNESS - //| TType_tuple _ -> None // TODO NULLNESS - //| TType_anon _ -> None // TODO NULLNESS | _ -> ty let rec stripTyparEqnsAux nullness0 canShortcut ty = @@ -336,9 +333,6 @@ let replaceNullnessOfTy nullness (ty:TType) = | TType_var (tp, _) -> TType_var (tp, nullness) | TType_app (tcr, tinst, _) -> TType_app (tcr, tinst, nullness) | TType_fun (d, r, _) -> TType_fun (d, r, nullness) - //| TType_ucase _ -> None // TODO NULLNESS - //| TType_tuple _ -> None // TODO NULLNESS - //| TType_anon _ -> None // TODO NULLNESS | sty -> sty /// Detect a use of a nominal type, including type abbreviations. diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 50329b011eb..81466446bde 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -1165,7 +1165,7 @@ let rec getErasedTypes g ty checkForNullness = | TType_var (tp, nullness) -> match checkForNullness, nullness.Evaluate() with - | true, NullnessInfo.WithNull -> [ty] // with-null annotations can't be tested at runtime (TODO NULLNESS: for value types Nullable<_> they can be) + | true, NullnessInfo.WithNull -> [ty] // with-null annotations can't be tested at runtime, Nullabe<> is not part of Nullness feature as of now. | _ -> if tp.IsErased then [ty] else [] | TType_app (_, b, nullness) -> diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs index 8e0a6eb44f1..caa7e84591c 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/BigIntType.fs @@ -93,7 +93,7 @@ type BigIntType() = Assert.True(z4.Equals(z4)) // Null - Assert.False(a.Equals(null:obj)) // TODO NULLNESS - this type annoation was needed to resolve overloading, even with --checknulls off + Assert.False(a.Equals(null)) Assert.True(0I.GetHashCode() = (BigInteger()).GetHashCode()) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs index 7b0ff69b420..9a566f5361d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Core/OptionModule.fs @@ -131,7 +131,7 @@ type OptionModule() = member this.OfToObj() = Assert.True( Option.toObj (Some "3") = "3") Assert.True( Option.toObj (Some "") = "") - Assert.True( Option.toObj (Some null) = null) // TODO NULLNESS: this type annotation should not be needed + Assert.True( Option.toObj (Some null) = null) // TODO NULLNESS: this type annotation should not be needed Assert.True( Option.toObj None = null) Assert.True( Option.ofObj "3" = Some "3") @@ -369,7 +369,7 @@ type ValueOptionTests() = member this.OfToObj() = Assert.True(ValueOption.toObj (ValueSome "3") = "3") Assert.True(ValueOption.toObj (ValueSome "") = "") - Assert.True(ValueOption.toObj (ValueSome null) = null) // TODO NULLNESS: this type annotation should not be needed + Assert.True(ValueOption.toObj (ValueSome null) = null) Assert.True(ValueOption.toObj ValueNone = null) Assert.True(ValueOption.ofObj "3" = ValueSome "3") From 13f187d5f26306df81991f7a4a93781518c39bb3 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 14 Jun 2024 10:04:09 +0200 Subject: [PATCH 2/7] tests reorg, incremental build fix --- src/Compiler/Service/IncrementalBuild.fs | 5 +- src/Compiler/Service/IncrementalBuild.fsi | 3 +- src/Compiler/Service/TransparentCompiler.fs | 3 +- .../FSharp.Compiler.ComponentTests.fsproj | 7 +- .../NullableCsharpImportTests.fs | 11 +- .../NullableLibraryConstructsTests.fs | 0 .../NullableReferenceTypesTests.fs | 2 +- .../Nullness/NullableRegressionTests.fs | 89 +++++ .../Language/Nullness/existing-negative.fs} | 2 + ...existing-negative.fs.checknulls_on.err.bsl | 12 + ...ting-negative.fs.nullness_disabled.err.bsl | 5 + .../Language/Nullness/existing-positive.fs} | 0 ...existing-positive.fs.checknulls_on.err.bsl | 8 + ...ing-positive.fs.nullness_disabled.err.bsl} | 0 .../Language/Nullness/library-functions.fs | 41 ++ ...library-functions.fs.checknulls_on.err.bsl | 13 + ...ry-functions.fs.nullness_disabled.err.bsl} | 0 .../Language/Nullness}/micro.fs | 6 +- .../Language/Nullness}/micro.fsi | 0 .../using-nullness-syntax-positive.fs} | 0 ...s-syntax-positive.fs.checknulls_on.err.bsl | 38 ++ ...ntax-positive.fs.nullness_disabled.err.bsl | 6 + tests/adhoc/nullness/enabled/negative.fs | 52 --- .../adhoc/nullness/enabled/positive.next.bsl | 24 -- .../enabled/positive.next.enabled.bsl | 8 - .../positive.next.enabled.checknulls.bsl | 66 ---- .../adhoc/nullness/existing/negative.next.bsl | 6 - .../existing/negative.next.enabled.bsl | 6 - .../negative.next.enabled.checknulls.bsl | 20 - .../nullness/existing/negative.previous.bsl | 6 - .../positive.next.enabled.checknulls.bsl | 16 - .../nullness/existing/positive.previous.bsl | 0 tests/adhoc/nullness/interop/positive.fs | 18 - tests/adhoc/nullness/library/positive.fs | 75 ---- tests/adhoc/nullness/nullness.fsproj | 26 -- tests/adhoc/nullness/out.fsi | 352 ------------------ tests/adhoc/nullness/validate.cmd | 36 -- 37 files changed, 239 insertions(+), 723 deletions(-) rename tests/FSharp.Compiler.ComponentTests/Language/{ => Nullness}/NullableCsharpImportTests.fs (98%) rename tests/FSharp.Compiler.ComponentTests/Language/{ => Nullness}/NullableLibraryConstructsTests.fs (100%) rename tests/FSharp.Compiler.ComponentTests/Language/{ => Nullness}/NullableReferenceTypesTests.fs (99%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs rename tests/{adhoc/nullness/existing/negative.fs => FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs} (98%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl rename tests/{adhoc/nullness/existing/positive.fs => FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs} (100%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl rename tests/{adhoc/nullness/existing/positive.next.bsl => FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.nullness_disabled.err.bsl} (100%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl rename tests/{adhoc/nullness/existing/positive.next.enabled.bsl => FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.nullness_disabled.err.bsl} (100%) rename tests/{adhoc/nullness => FSharp.Compiler.ComponentTests/Language/Nullness}/micro.fs (52%) rename tests/{adhoc/nullness => FSharp.Compiler.ComponentTests/Language/Nullness}/micro.fsi (100%) rename tests/{adhoc/nullness/enabled/positive.fs => FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs} (100%) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl delete mode 100644 tests/adhoc/nullness/enabled/negative.fs delete mode 100644 tests/adhoc/nullness/enabled/positive.next.bsl delete mode 100644 tests/adhoc/nullness/enabled/positive.next.enabled.bsl delete mode 100644 tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl delete mode 100644 tests/adhoc/nullness/existing/negative.next.bsl delete mode 100644 tests/adhoc/nullness/existing/negative.next.enabled.bsl delete mode 100644 tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl delete mode 100644 tests/adhoc/nullness/existing/negative.previous.bsl delete mode 100644 tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl delete mode 100644 tests/adhoc/nullness/existing/positive.previous.bsl delete mode 100644 tests/adhoc/nullness/interop/positive.fs delete mode 100644 tests/adhoc/nullness/library/positive.fs delete mode 100644 tests/adhoc/nullness/nullness.fsproj delete mode 100644 tests/adhoc/nullness/out.fsi delete mode 100644 tests/adhoc/nullness/validate.cmd diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index b2ed3538cd5..c8cc9a77e1f 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -487,7 +487,7 @@ type BoundModel private ( /// Global service state type FrameworkImportsCacheKey = - | FrameworkImportsCacheKey of resolvedpath: string list * assemblyName: string * targetFrameworkDirectories: string list * fsharpBinaries: string * langVersion: decimal + | FrameworkImportsCacheKey of resolvedpath: string list * assemblyName: string * targetFrameworkDirectories: string list * fsharpBinaries: string * langVersion: decimal * checkNulls: bool interface ICacheKey with member this.GetKey() = @@ -529,7 +529,8 @@ type FrameworkImportsCache(size) = tcConfig.primaryAssembly.Name, tcConfig.GetTargetFrameworkDirectories(), tcConfig.fsharpBinariesDir, - tcConfig.langVersion.SpecifiedVersion) + tcConfig.langVersion.SpecifiedVersion, + tcConfig.checkNullness) let node = lock gate (fun () -> diff --git a/src/Compiler/Service/IncrementalBuild.fsi b/src/Compiler/Service/IncrementalBuild.fsi index 0fd380631e4..21b2fb23404 100644 --- a/src/Compiler/Service/IncrementalBuild.fsi +++ b/src/Compiler/Service/IncrementalBuild.fsi @@ -30,7 +30,8 @@ type internal FrameworkImportsCacheKey = assemblyName: string * targetFrameworkDirectories: string list * fsharpBinaries: string * - langVersion: decimal + langVersion: decimal * + checkNulls: bool interface ICacheKey diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index f2af93736e3..32766202cd4 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -510,7 +510,8 @@ type internal TransparentCompiler tcConfig.primaryAssembly.Name, tcConfig.GetTargetFrameworkDirectories(), tcConfig.fsharpBinariesDir, - tcConfig.langVersion.SpecifiedVersion + tcConfig.langVersion.SpecifiedVersion, + tcConfig.checkNullness ) caches.FrameworkImports.Get( diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index bc5ace33d29..095565a1e4e 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -235,9 +235,10 @@ - - - + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs similarity index 98% rename from tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs index b7118fbe61e..c477417e75a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableCsharpImportTests.fs @@ -4,13 +4,17 @@ open Xunit open FSharp.Test open FSharp.Test.Compiler -let typeCheckWithStrictNullness cu = +let withStrictNullness cu = cu |> withLangVersionPreview |> withCheckNulls |> withWarnOn 3261 |> withOptions ["--warnaserror+"] - |> compile + +let typeCheckWithStrictNullness cu = + cu + |> withStrictNullness + |> typecheck [] @@ -211,7 +215,8 @@ let ``Consumption of nullable C# - no generics, just strings in methods and fiel """ |> asLibrary |> withReferences [csharpLib] - |> typeCheckWithStrictNullness + |> withStrictNullness + |> compile |> shouldFail |> withDiagnostics [ Error 3261, Line 5, Col 40, Line 5, Col 85, "Nullness warning: The types 'string' and 'string | null' do not have compatible nullability." diff --git a/tests/FSharp.Compiler.ComponentTests/Language/NullableLibraryConstructsTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableLibraryConstructsTests.fs similarity index 100% rename from tests/FSharp.Compiler.ComponentTests/Language/NullableLibraryConstructsTests.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableLibraryConstructsTests.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs similarity index 99% rename from tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs index 0a409783185..9ee080928a7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs @@ -14,7 +14,7 @@ let withNullnessOptions cu = let typeCheckWithStrictNullness cu = cu |> withNullnessOptions - |> compile + |> typecheck [] let ``Cannot pass possibly null value to a strict function``() = diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs new file mode 100644 index 00000000000..9445ade1c1f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs @@ -0,0 +1,89 @@ +module Language.NullableRegressions + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +let withVersionAndCheckNulls (version,checknulls) cu = + cu + |> withLangVersion version + |> withWarnOn 3261 + |> withOptions ["--warnaserror+"] + |> if checknulls then withCheckNulls else id + + +[] +[] +[] +[] +let ``Micro compilation`` langVersion checknulls = + + FsFromPath (__SOURCE_DIRECTORY__ ++ "micro.fsi") + |> withAdditionalSourceFile (SourceFromPath (__SOURCE_DIRECTORY__ ++ "micro.fs")) + |> withLangVersion langVersion + |> fun x -> + if checknulls then + x |> withCheckNulls |> withDefines ["CHECKNULLS"] + else x + |> compile + |> shouldSucceed + +[] +let ``Existing positive v8 disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("8.0",false) + |> verifyBaseline + +[] +let ``Existing positive vPreview disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``Existing positive vPreview enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + +[] +let ``Existing negative v8 disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("8.0",false) + |> verifyBaseline + +[] +let ``Existing negative vPreview disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``Existing negative vPreview enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + +[] +let ``Library functions nullness disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``Library functions nullness enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline + +[] +let ``With new nullness syntax nullness disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + +[] +let ``With new nullness syntax nullness enabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",true) + |> verifyBaseline \ No newline at end of file diff --git a/tests/adhoc/nullness/existing/negative.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs similarity index 98% rename from tests/adhoc/nullness/existing/negative.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs index 42994095622..0052503aef8 100644 --- a/tests/adhoc/nullness/existing/negative.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs @@ -1,3 +1,5 @@ +module ExistingNegative + open System open System.Diagnostics open System.Runtime.CompilerServices 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 new file mode 100644 index 00000000000..c18a0386eaf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.checknulls_on.err.bsl @@ -0,0 +1,12 @@ +existing-negative.fs (10,17)-(10,33) typecheck error Nullness warning: The type '(int * int)' does not support 'null'. +existing-negative.fs (12,17)-(12,28) typecheck error Nullness warning: The type 'int list' does not support 'null'. +existing-negative.fs (14,17)-(14,30) typecheck error Nullness warning: The type '(int -> int)' does not support 'null'. +existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' is not structurally comparable because the type '(int -> int)' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C6' to clarify that the type is not comparable +existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' does not support structural equality because the type '(int -> int)' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C6' to clarify that the type does not support structural equality +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 +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 +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 +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 +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 +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 +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 \ 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 new file mode 100644 index 00000000000..910f3bc6ce3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs.nullness_disabled.err.bsl @@ -0,0 +1,5 @@ +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 +existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' is not structurally comparable because the type '(int -> int)' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C6' to clarify that the type is not comparable +existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' does not support structural equality because the type '(int -> int)' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C6' to clarify that the type does not support structural equality \ No newline at end of file diff --git a/tests/adhoc/nullness/existing/positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs similarity index 100% rename from tests/adhoc/nullness/existing/positive.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..82848eae396 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.checknulls_on.err.bsl @@ -0,0 +1,8 @@ +existing-positive.fs (9,23)-(9,25) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (15,24)-(15,26) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (21,24)-(21,26) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (24,23)-(24,27) typecheck error Nullness warning: The type 'String' does not support 'null'. +existing-positive.fs (29,26)-(29,30) typecheck error Nullness warning: The type 'String' does not support 'null'. +existing-positive.fs (44,32)-(44,36) typecheck error Nullness warning: The type 'obj array' does not support 'null'. +existing-positive.fs (49,14)-(49,16) typecheck error Nullness warning: The type 'string' does not support 'null'. +existing-positive.fs (55,17)-(55,26) typecheck error Nullness warning: The type 'String' does not support 'null'. \ No newline at end of file diff --git a/tests/adhoc/nullness/existing/positive.next.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.nullness_disabled.err.bsl similarity index 100% rename from tests/adhoc/nullness/existing/positive.next.bsl rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-positive.fs.nullness_disabled.err.bsl diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs new file mode 100644 index 00000000000..03dc226b725 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs @@ -0,0 +1,41 @@ +module LibraryFunctions + +open System + +let x4 : string = "plain string" +let x5 = nonNull ("": string | null) // Should not give a Nullness warning +let x6 = nonNull "" // **Expected to give a Nullness warning +let x7 = nonNull "" +let _x7 : String = x7 +let x8 = nonNull Array.empty +let x9 = nonNull [| "" |] +let x10 = nonNullV (Nullable(3)) +let x11 = try nonNullV (Nullable()) with :? System.NullReferenceException -> 10 +let x12 = nullV +let x13 = nullV +let x14 = withNullV 6L +let x15 : String | null = withNull x4 // This should not warn (is OK if typar is passed, this is wrong) +let x15a : String | null = withNull "" // This should not warn (is OK if typar is passed, this is wrong) +let x15b : String | null = withNull x4 +let x15c : String | null = withNull x4 // **Expected to give a Nullness warning +let x16 : Nullable = withNullV 3 + +let y0 = isNull null // Should not give a Nullness warning (obj) +let y1 = isNull (null: obj | null) // Should not give a Nullness warning +let y1b = isNull (null: String | null) // Should not give a Nullness warning +let y2 = isNull "" // **Expected to give a Nullness warning - type instantiation of a nullable type is non-nullable String +let y9 = isNull "" // **Expected to give a Nullness warning - type instantiation of a nullable type is non-nullable String +let y10 = isNull "" // Should not give a Nullness warning. +// Not yet allowed +//let f7 () : 'T | null when 'T : struct = null +let f7b () : Nullable<'T> = nullV + +let f0b (line:string | null) = + let add (s:String) = () + match line with + | null -> () + | _ -> add (line) // warning expected + +let add (s:String) = () +let f0c line = + add (nonNull "") \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..a74b139264c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.checknulls_on.err.bsl @@ -0,0 +1,13 @@ +library-functions.fs (6,27)-(6,29) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (7,10)-(7,17) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +library-functions.fs (7,33)-(7,35) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (8,18)-(8,20) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (10,28)-(10,39) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (11,18)-(11,26) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. +library-functions.fs (17,27)-(17,38) typecheck error Nullness warning: The types 'String' and 'String | null' do not have equivalent nullability. +library-functions.fs (18,28)-(18,39) typecheck error Nullness warning: The types 'String' and 'String | null' do not have equivalent nullability. +library-functions.fs (20,28)-(20,36) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +library-functions.fs (26,17)-(26,19) typecheck error Nullness warning: The type 'string' does not support 'null'. +library-functions.fs (27,10)-(27,16) typecheck error Nullness warning: The type 'String' does not support 'null'. +library-functions.fs (37,17)-(37,21) typecheck error Nullness warning: The types 'String' and 'string | null' do not have equivalent nullability. +library-functions.fs (41,26)-(41,28) typecheck error Value known to be without null passed to a function meant for nullables: You can remove this `nonNull` assertion. \ No newline at end of file diff --git a/tests/adhoc/nullness/existing/positive.next.enabled.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.nullness_disabled.err.bsl similarity index 100% rename from tests/adhoc/nullness/existing/positive.next.enabled.bsl rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/library-functions.fs.nullness_disabled.err.bsl diff --git a/tests/adhoc/nullness/micro.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs similarity index 52% rename from tests/adhoc/nullness/micro.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs index d95d0b48ede..a0027c2d0a9 100644 --- a/tests/adhoc/nullness/micro.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs @@ -6,4 +6,8 @@ let isNotNull (value: 'T) = | null -> false | _ -> true -let s: System.String = null \ No newline at end of file +#if CHECKNULLS +let s: System.String | null = null +#else +let s: System.String = null +#endif \ No newline at end of file diff --git a/tests/adhoc/nullness/micro.fsi b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi similarity index 100% rename from tests/adhoc/nullness/micro.fsi rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi diff --git a/tests/adhoc/nullness/enabled/positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs similarity index 100% rename from tests/adhoc/nullness/enabled/positive.fs rename to tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl new file mode 100644 index 00000000000..ceb1aa1a311 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl @@ -0,0 +1,38 @@ +using-nullness-syntax-positive.fs (11,18)-(11,22) typecheck error Nullness warning: The type 'obj' does not support 'null'. +using-nullness-syntax-positive.fs (12,18)-(12,37) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +using-nullness-syntax-positive.fs (13,18)-(13,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (17,15)-(17,19) typecheck error Nullness warning: The type 'obj' does not support 'null'. +using-nullness-syntax-positive.fs (18,39)-(18,41) typecheck error Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. +using-nullness-syntax-positive.fs (19,26)-(19,28) typecheck error Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (27,14)-(27,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (27,14)-(27,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (28,14)-(28,19) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (28,14)-(28,19) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (29,14)-(29,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (29,14)-(29,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (43,26)-(43,30) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (83,72)-(83,100) typecheck error Nullness warning: The types 'string' and 'String | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (84,95)-(84,123) typecheck error Nullness warning: The types 'string' and 'String | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (85,63)-(85,70) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (85,63)-(85,70) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,81)-(86,90) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,81)-(86,90) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,92)-(86,102) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (86,92)-(86,102) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (90,63)-(90,91) typecheck error Nullness warning: The types 'string' and 'String | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (91,53)-(91,60) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (91,53)-(91,60) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,72)-(92,81) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,72)-(92,81) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,83)-(92,93) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (92,83)-(92,93) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. +using-nullness-syntax-positive.fs (120,32)-(120,36) typecheck error Nullness warning: The type 'obj array' does not support 'null'. +using-nullness-syntax-positive.fs (129,4)-(129,34) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (134,5)-(134,44) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (159,36)-(159,40) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (162,41)-(162,45) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (164,37)-(164,41) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (183,14)-(183,16) typecheck error Nullness warning: The type 'string' does not support 'null'. +using-nullness-syntax-positive.fs (189,17)-(189,26) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' is not structurally comparable because the type '(int -> int) | null' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C7' to clarify that the type is not comparable +using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' does not support structural equality because the type '(int -> int) | null' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C7' to clarify that the type does not support structural equality \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..a13a4882dd6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl @@ -0,0 +1,6 @@ +using-nullness-syntax-positive.fs (13,18)-(13,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (19,26)-(19,28) typecheck error Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. +using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' is not structurally comparable because the type '(int -> int) | null' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C7' to clarify that the type is not comparable +using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' does not support structural equality because the type '(int -> int) | null' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C7' to clarify that the type does not support structural equality +using-nullness-syntax-positive.fs (214,25)-(214,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 +using-nullness-syntax-positive.fs (219,25)-(219,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 \ No newline at end of file diff --git a/tests/adhoc/nullness/enabled/negative.fs b/tests/adhoc/nullness/enabled/negative.fs deleted file mode 100644 index 3f90d956fe5..00000000000 --- a/tests/adhoc/nullness/enabled/negative.fs +++ /dev/null @@ -1,52 +0,0 @@ -open System - -module Basics2 = - let f6 () : 'T | null when 'T : not struct and 'T : null = null // Expected to give an error about inconistent constraints - -module NullConstraintTests = - type C<'T when 'T : null>() = class end - - let f1 (y : C< (int * int) >) = y // This gave an error in previous F# and we expect it to continue to give an error - - let f2 (y : C>) = y // This gave an error in previous F# and we expect it to continue to give an error - - let f7 (y : C> | null) = y // We expect this to give an error - - module StructExamples = - - [] - type C1 = - [] - val mutable Whoops : String // expect a warning - - [] - type C4a = - [] - val mutable Whoops : int FSharp.Collections.List // expect a hard error like in previous F# - - [] - type C5 = - [] - val mutable Whoops : int * int // expect an error like previous F# - - [] - type C6 = - [] - val mutable Whoops : int -> int // expect an error like previous F# - - module ClassExamples = - type C1 = - [] - val mutable Whoops : String // expect an error if checknulls is on - - type C4a = - [] - val mutable Whoops : int FSharp.Collections.List // expect an error if checknulls is on - - type C5 = - [] - val mutable Whoops : int * int // expect an error like previous F# - - type C6 = - [] - val mutable Whoops : int -> int // expect an error like previous F# diff --git a/tests/adhoc/nullness/enabled/positive.next.bsl b/tests/adhoc/nullness/enabled/positive.next.bsl deleted file mode 100644 index ca9680d9aa5..00000000000 --- a/tests/adhoc/nullness/enabled/positive.next.bsl +++ /dev/null @@ -1,24 +0,0 @@ - -tests\adhoc\nullness\enabled\positive.fs(4,21): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(5,21): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(12,31): error FS0010: Unexpected symbol '|' in expression - -tests\adhoc\nullness\enabled\positive.fs(18,28): error FS0010: Unexpected symbol '|' in expression - -tests\adhoc\nullness\enabled\positive.fs(26,15): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(35,24): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(37,20): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(39,20): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(68,23): error FS0010: Unexpected symbol '|' in binding. Expected '=' or other token. - -tests\adhoc\nullness\enabled\positive.fs(84,75): error FS0010: Unexpected symbol '|' in pattern. Expected ',' or other token. - -tests\adhoc\nullness\enabled\positive.fs(174,44): error FS0010: Unexpected symbol '|' in expression - -tests\adhoc\nullness\enabled\positive.fs(174,51): error FS0010: Unexpected symbol ')' in definition. Expected incomplete structured construct at or before this point or other token. diff --git a/tests/adhoc/nullness/enabled/positive.next.enabled.bsl b/tests/adhoc/nullness/enabled/positive.next.enabled.bsl deleted file mode 100644 index a63c8033adc..00000000000 --- a/tests/adhoc/nullness/enabled/positive.next.enabled.bsl +++ /dev/null @@ -1,8 +0,0 @@ - -tests\adhoc\nullness\enabled\positive.fs(13,18): warning FS3261: Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. - -tests\adhoc\nullness\enabled\positive.fs(19,26): warning FS3261: Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. - -tests\adhoc\nullness\enabled\positive.fs(214,25): error FS0444: 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 - -tests\adhoc\nullness\enabled\positive.fs(219,25): error FS0444: 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 diff --git a/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl b/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl deleted file mode 100644 index d8125c7aee9..00000000000 --- a/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl +++ /dev/null @@ -1,66 +0,0 @@ - -tests\adhoc\nullness\enabled\positive.fs(11,18): warning FS3261: Nullness warning: The type 'obj' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(12,18): warning FS3261: Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. - -tests\adhoc\nullness\enabled\positive.fs(13,18): warning FS3261: Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. - -tests\adhoc\nullness\enabled\positive.fs(17,15): warning FS3261: Nullness warning: The type 'obj' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(18,39): warning FS3261: Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected. - -tests\adhoc\nullness\enabled\positive.fs(19,26): warning FS3261: Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. - -tests\adhoc\nullness\enabled\positive.fs(27,14): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(27,14): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(28,14): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(28,14): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(29,14): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(29,14): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(43,26): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(85,63): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(85,63): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(86,81): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(86,81): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(86,92): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(86,92): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(91,53): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(91,53): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(92,72): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(92,72): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(92,83): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(92,83): warning FS3261: Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. - -tests\adhoc\nullness\enabled\positive.fs(120,32): warning FS3261: Nullness warning: The type 'obj array' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(129,4): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(134,5): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(159,36): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(162,41): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(164,37): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(183,14): warning FS3261: Nullness warning: The type 'string' does not support 'null'. - -tests\adhoc\nullness\enabled\positive.fs(189,17): warning FS3261: Nullness warning: The type 'String' does not support 'null'. diff --git a/tests/adhoc/nullness/existing/negative.next.bsl b/tests/adhoc/nullness/existing/negative.next.bsl deleted file mode 100644 index 9cb7a4b46e4..00000000000 --- a/tests/adhoc/nullness/existing/negative.next.bsl +++ /dev/null @@ -1,6 +0,0 @@ - -tests\adhoc\nullness\existing\negative.fs(8,17): error FS0001: The type '(int * int)' does not have 'null' as a proper value - -tests\adhoc\nullness\existing\negative.fs(10,17): error FS0001: The type 'int list' does not have 'null' as a proper value - -tests\adhoc\nullness\existing\negative.fs(12,17): error FS0001: The type '(int -> int)' does not have 'null' as a proper value diff --git a/tests/adhoc/nullness/existing/negative.next.enabled.bsl b/tests/adhoc/nullness/existing/negative.next.enabled.bsl deleted file mode 100644 index 9cb7a4b46e4..00000000000 --- a/tests/adhoc/nullness/existing/negative.next.enabled.bsl +++ /dev/null @@ -1,6 +0,0 @@ - -tests\adhoc\nullness\existing\negative.fs(8,17): error FS0001: The type '(int * int)' does not have 'null' as a proper value - -tests\adhoc\nullness\existing\negative.fs(10,17): error FS0001: The type 'int list' does not have 'null' as a proper value - -tests\adhoc\nullness\existing\negative.fs(12,17): error FS0001: The type '(int -> int)' does not have 'null' as a proper value diff --git a/tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl b/tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl deleted file mode 100644 index ab814c80f8a..00000000000 --- a/tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl +++ /dev/null @@ -1,20 +0,0 @@ - -tests\adhoc\nullness\existing\negative.fs(8,17): warning FS3261: Nullness warning: The type '(int * int)' does not support 'null'. - -tests\adhoc\nullness\existing\negative.fs(10,17): warning FS3261: Nullness warning: The type 'int list' does not support 'null'. - -tests\adhoc\nullness\existing\negative.fs(12,17): warning FS3261: Nullness warning: The type '(int -> int)' does not support 'null'. - -tests\adhoc\nullness\existing\negative.fs(20,25): warning FS0444: 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 - -tests\adhoc\nullness\existing\negative.fs(25,25): error FS0444: 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 - -tests\adhoc\nullness\existing\negative.fs(30,25): error FS0444: 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 - -tests\adhoc\nullness\existing\negative.fs(35,25): error FS0444: 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 - -tests\adhoc\nullness\existing\negative.fs(41,25): error FS0444: 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 - -tests\adhoc\nullness\existing\negative.fs(45,25): error FS0444: 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 - -tests\adhoc\nullness\existing\negative.fs(49,25): error FS0444: 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 diff --git a/tests/adhoc/nullness/existing/negative.previous.bsl b/tests/adhoc/nullness/existing/negative.previous.bsl deleted file mode 100644 index 9cb7a4b46e4..00000000000 --- a/tests/adhoc/nullness/existing/negative.previous.bsl +++ /dev/null @@ -1,6 +0,0 @@ - -tests\adhoc\nullness\existing\negative.fs(8,17): error FS0001: The type '(int * int)' does not have 'null' as a proper value - -tests\adhoc\nullness\existing\negative.fs(10,17): error FS0001: The type 'int list' does not have 'null' as a proper value - -tests\adhoc\nullness\existing\negative.fs(12,17): error FS0001: The type '(int -> int)' does not have 'null' as a proper value diff --git a/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl b/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl deleted file mode 100644 index 05053aaf03c..00000000000 --- a/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl +++ /dev/null @@ -1,16 +0,0 @@ - -tests\adhoc\nullness\existing\positive.fs(9,23): warning FS3261: Nullness warning: The type 'string' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(15,24): warning FS3261: Nullness warning: The type 'string' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(21,24): warning FS3261: Nullness warning: The type 'string' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(24,23): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(29,26): warning FS3261: Nullness warning: The type 'String' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(44,32): warning FS3261: Nullness warning: The type 'obj array' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(49,14): warning FS3261: Nullness warning: The type 'string' does not support 'null'. - -tests\adhoc\nullness\existing\positive.fs(55,17): warning FS3261: Nullness warning: The type 'String' does not support 'null'. diff --git a/tests/adhoc/nullness/existing/positive.previous.bsl b/tests/adhoc/nullness/existing/positive.previous.bsl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/adhoc/nullness/interop/positive.fs b/tests/adhoc/nullness/interop/positive.fs deleted file mode 100644 index 1358168244f..00000000000 --- a/tests/adhoc/nullness/interop/positive.fs +++ /dev/null @@ -1,18 +0,0 @@ -open System - -module Extractions2 = - - let f (x: ActivitySource) = - x.CreateActivity("aaa", ActivityKind.Client) - - let source = new ActivitySource("aaab") - let activity = f source - let baggage = activity.Baggage // TODO NULLNESS: should trigger a nullness warning - - // TODO NULLNESS test matrix - // - Import null annotated .NET non-generic type (above) - // - Import null annotated .NET array type - // - Import null annotated .NET generic type instantiated at non-null .NET type - // - Import .NET generic type instantiated at null annotated .NET type - - diff --git a/tests/adhoc/nullness/library/positive.fs b/tests/adhoc/nullness/library/positive.fs deleted file mode 100644 index 77b8c6f7b5a..00000000000 --- a/tests/adhoc/nullness/library/positive.fs +++ /dev/null @@ -1,75 +0,0 @@ -let failures = ref [] - -let report_failure (s : string) = - stderr.Write" NO: " - stderr.WriteLine s - failures.Value <- failures.Value @ [s] - -let test (s : string) b = - stderr.Write(s) - if b then stderr.WriteLine " OK" - else report_failure (s) - -let check s b1 b2 = test s (b1 = b2) - -module Library = - - let x5 = nonNull "" // Should not give a Nullness warning - check "ekjnceoiwe5" x5 "" - let x6 = nonNull "" // **Expected to give a Nullness warning, expected also to give a warning with nullness checking off - check "ekjnceoiwe6" x6 "" - let x7 = nonNull "" - check "ekjnceoiwe7" x7 "" - let _x7 : String = x7 - let x8 = nonNull Array.empty - check "ekjnceoiwe8" x8 [| |] - let x9 = nonNull [| "" |] - check "ekjnceoiwe9" x9 [| "" |] - let x10 = nonNullV (Nullable(3)) - check "ekjnceoiwe10" x10 3 - let x11 = try nonNullV (Nullable()) with :? System.NullReferenceException -> 10 - check "ekjnceoiwe11" x11 10 - let x12 = nullV - check "ekjnceoiwe12" x12 (Nullable()) - let x13 = nullV - check "ekjnceoiwe13" x13 (Nullable()) - let x14 = withNullV 6L - check "ekjnceoiwe14" x14 (Nullable(6L)) - let x15 : String | null = withNull x4 - check "ekjnceoiwe15" x15 "" - let x15a : String | null = withNull "" - check "ekjnceoiwe15a" x15a "" - let x15b : String | null = withNull x4 - check "ekjnceoiwe15b" x15b "" - let x15c : String | null = withNull x4 // **Expected to give a Nullness warning - check "ekjnceoiwe15c" x15c "" - let x16 : Nullable = withNullV 3 - check "ekjnceoiwe16" x16 (Nullable(3)) - - let y0 = isNull null // Should not give a Nullness warning (obj) - check "ekjnceoiwey0" y0 true - let y1 = isNull (null: obj | null) // Should not give a Nullness warning - check "ekjnceoiwey1" y1 true - let y1b = isNull (null: String | null) // Should not give a Nullness warning - check "ekjnceoiwey1b" y1b true - let y2 = isNull "" // **Expected to give a Nullness warning - type instantiation of a nullable type is non-nullable String - check "ekjnceoiwey2" y2 false - let y9 = isNull "" // **Expected to give a Nullness warning - type instantiation of a nullable type is non-nullable String - check "ekjnceoiwey9" y9 false - let y10 = isNull "" // Should not give a Nullness warning. - check "ekjnceoiwey10" y10 false - // Not yet allowed - //let f7 () : 'T | null when 'T : struct = null - let f7b () : Nullable<'T> = nullV // BUG: Incorrectly gives a warning about System.ValueType with /test:AssumeNullOnImport - - let f0b line = - let add (s:String) = () - match line with - | null -> () - | _ -> add (nonNull line) // Exected to give a nullness warning - - let add (s:String) = () - let f0c line = - add (nonNull "") // WRONG: should not give a nullness warning - - diff --git a/tests/adhoc/nullness/nullness.fsproj b/tests/adhoc/nullness/nullness.fsproj deleted file mode 100644 index bd7b9bb75e1..00000000000 --- a/tests/adhoc/nullness/nullness.fsproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net8.0 - Exe - true - - $(OtherFlags) --nowarn:1204 - - $(OtherFlags) --nowarn:57 - $(OtherFlags) --langversion:preview - $(OtherFlags) /checknulls /sig:out.fsi - - $(OtherFlags) --nowarn:3261 - $(OtherFlags) --nowarn:3262 - $(OtherFlags) --nowarn:444 - - - - - - - - - - diff --git a/tests/adhoc/nullness/out.fsi b/tests/adhoc/nullness/out.fsi deleted file mode 100644 index a238a1651d0..00000000000 --- a/tests/adhoc/nullness/out.fsi +++ /dev/null @@ -1,352 +0,0 @@ - -module FSharp.BuildProperties - -val internal fsProductVersion: string - -val internal fsLanguageVersion: string - -namespace FSharp - - - - -module ExistingPositive - -module Extractions0a = - - val x: 'a when 'a: null - - val result: bool - -module Extractions0b = - - val x: 'a when 'a: null - - val f: x: 'T * y: 'T -> unit - - val result: unit - -module Extractions0d = - - val x: 'a when 'a: null - - val f: x: 'T * y: 'T -> unit when 'T: null - - val result: unit - -module Basics = - - val x1: System.String - - val x4: System.String - -module Basics2 = - - val f1: unit -> 'a when 'a: null - - val f8: unit -> System.String - -type C = - - new: s: System.String -> C - - member Value: System.String - -module InteropBasics = - - val s0: string - - val s1: System.String - - val test1: unit -> string - - val test2: s1: System.String * s2: System.String -> string - - val test3: unit -> System.String - - val test4: unit -> System.AppDomain - - val test5: System.AppDomain - -val f0: line: string -> unit - -module NullConstraintTests = - - type C<'T when 'T: null> = - - new: unit -> C<'T> - - val f3: y: C -> C - -module DefaultValueTests = - - module StructExamples = - - [] - type C2 = - - [] - val mutable Whoops: System.String - - module ClassExamples = - - type C2 = - - [] - val mutable Whoops: System.String - - -module EnabledPositive - -module Basics = - - val x2: System.String | null - - val x3: System.String | null - -module NotNullConstraint = - - val f3: x: 'T -> int when 'T: not null - - val v1: int - - val v2: int - - val v3: int - - val v4: int - - val v5: int - - val w1: int - - val w2: int - - val w3: int - - val w4: int - - val w5: int - -module MemberBasics = - - type C = - - new: unit -> C - - member M: unit -> int - - member P: int - - val c: C | null - - val v1: int - - val v2: int - - val f1: (unit -> int) - -module Basics2 = - - val f1: unit -> 'a when 'a: null - - val f2: unit -> System.String | null - - val f3: unit -> 'T | null when 'T: not null and 'T: not struct - - val f4: unit -> 'T | null when 'T: not null and 'T: not struct - - val f5: unit -> 'T when 'T: not struct and 'T: null - - val f8: unit -> System.String - -type C = - - new: s: System.String -> C - - member Value: System.String - -val f: x: 'T | null * y: 'T | null -> unit when 'T: not null and 'T: not struct - -module Extractions0c = - - val x: 'a when 'a: null - - val f: - x: 'T | null * y: 'T | null -> unit when 'T: not null and 'T: not struct - - val s: System.String - - val result: unit - -module Extractions0e = - - val x: 'a when 'a: null - - val f: - x: 'T | null * y: 'T | null -> unit when 'T: not null and 'T: not struct - - val result: unit - -module Extractions1 = - - val mutable x: string | null - -module InteropBasics = - - val s0: string - - val s1: System.String - - val test1: unit -> string - - val test2: s1: System.String * s2: System.String -> string - - val test3: unit -> System.String - - val test4: unit -> System.AppDomain - - val test5: System.AppDomain - -[] -type KonsoleWithNulls = - - static member WriteLine: s: System.String -> unit - - static member - WriteLine: fmt: System.String * [] args: obj array -> - unit - - static member WriteLine: fmt: System.String * arg1: System.String -> unit - - static member WriteLineC: s: C -> unit - - static member WriteLineC: fmt: C * arg1: C -> unit - -module KonsoleWithNullsModule = - - val WriteLine: s: System.String | null -> unit - - val WriteLine2: - fmt: System.String | null * arg1: System.String | null -> unit - - val WriteLineC: s: C | null -> unit - - val WriteLineC2: fmt: C | null * arg1: C | null -> unit - -module KonsoleWithNullsModule2 = - - val WriteLine: x: string | null -> unit - - val WriteLine2: fmt: string | null * arg1: string | null -> unit - - val WriteLineC: - s: 'a | null -> unit - when 'a: not null and 'a: not struct and 'a :> C | null - - val WriteLineC2: - fmt: 'a | null * arg1: 'b | null -> unit - when 'a: not null and 'a: not struct and 'a :> C | null and 'b: not null and - 'b: not struct and 'b :> C | null - -[] -type KonsoleNoNulls = - - static member WriteLine: s: System.String -> unit - - static member - WriteLine: fmt: System.String * [] args: obj array -> - unit - - static member WriteLine: fmt: System.String * arg1: System.String -> unit - - static member WriteLineC: s: C -> unit - - static member WriteLineC: fmt: C * arg1: C -> unit - -module KonsoleNoNullsModule = - - val WriteLine: s: System.String -> unit - - val WriteLine2: fmt: System.String * arg1: System.String -> unit - - val WriteLineC: s: C -> unit - - val WriteLineC2: fmt: C * arg1: C -> unit - -module KonsoleNoNullsModule2 = - - val WriteLine: x: System.String -> unit - - val WriteLine2: fmt: System.String * arg1: System.String -> unit - - val WriteLineC: s: C -> unit - - val WriteLineC2: fmt: C * arg1: C -> unit - -val f0: line: string -> unit - -module NullConstraintTests = - - type C<'T when 'T: null> = - - new: unit -> C<'T> - - val f3: y: C -> C - - val f4: y: C -> C - - val f5: y: C | null> -> C | null> - - val f6: y: C | null> -> C | null> - -module DefaultValueTests = - - module StructExamples = - - [] - type C2 = - - [] - val mutable Whoops: System.String - - [] - type C3 = - - [] - val mutable Whoops: System.String | null - - [] - type C4b = - - [] - val mutable Whoops: List | null - - [] - type C7 = - - [] - val mutable Whoops: (int -> int | null) - - module ClassExamples = - - type C2 = - - [] - val mutable Whoops: System.String - - type C3 = - - [] - val mutable Whoops: System.String | null - - type C4b = - - [] - val mutable Whoops: List | null - - type C7 = - - [] - val mutable Whoops: (int -> int | null) - diff --git a/tests/adhoc/nullness/validate.cmd b/tests/adhoc/nullness/validate.cmd deleted file mode 100644 index 7aa5f84e88b..00000000000 --- a/tests/adhoc/nullness/validate.cmd +++ /dev/null @@ -1,36 +0,0 @@ -REM devenv FSharp.sln /ProjectConfig Proto -set "fsiLocation="C:\Program Files\dotnet\sdk\8.0.300\FSharp\fsc.dll"" -REM dotnet build src\fsc\fscProject -f net472 -c Proto -p ProtoDebug=true - -dotnet %fsiLocation% tests\adhoc\nullness\micro.fs -i -dotnet %fsiLocation% tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i - -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fs -i -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i - -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fs -i --langversion:preview -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i --langversion:preview - -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fs -i --langversion:preview --checknulls -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i --langversion:preview --checknulls - -REM ------------- - - -dotnet %fsiLocation% tests\adhoc\nullness\existing\positive.fs 2> tests\adhoc\nullness\existing\positive.previous.bsl & type tests\adhoc\nullness\existing\positive.previous.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\existing\positive.fs 2> tests\adhoc\nullness\existing\positive.next.bsl & type tests\adhoc\nullness\existing\positive.next.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\existing\positive.fs --langversion:preview 2> tests\adhoc\nullness\existing\positive.next.enabled.bsl & type tests\adhoc\nullness\existing\positive.next.enabled.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\existing\positive.fs --langversion:preview --checknulls 2> tests\adhoc\nullness\existing\positive.next.enabled.checknulls.bsl & type tests\adhoc\nullness\existing\positive.next.enabled.checknulls.bsl - -dotnet %fsiLocation% tests\adhoc\nullness\existing\negative.fs 2> tests\adhoc\nullness\existing\negative.previous.bsl & type tests\adhoc\nullness\existing\negative.previous.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\existing\negative.fs 2> tests\adhoc\nullness\existing\negative.next.bsl & type tests\adhoc\nullness\existing\negative.next.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\existing\negative.fs --langversion:preview 2> tests\adhoc\nullness\existing\negative.next.enabled.bsl & type tests\adhoc\nullness\existing\negative.next.enabled.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\existing\negative.fs --langversion:preview --checknulls 2> tests\adhoc\nullness\existing\negative.next.enabled.checknulls.bsl & type tests\adhoc\nullness\existing\negative.next.enabled.checknulls.bsl - -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\enabled\positive.fs 2> tests\adhoc\nullness\enabled\positive.next.bsl & type tests\adhoc\nullness\enabled\positive.next.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\enabled\positive.fs --langversion:preview 2> tests\adhoc\nullness\enabled\positive.next.enabled.bsl & type tests\adhoc\nullness\enabled\positive.next.enabled.bsl -artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\enabled\positive.fs --langversion:preview --checknulls 2> tests\adhoc\nullness\enabled\positive.next.enabled.checknulls.bsl & type tests\adhoc\nullness\enabled\positive.next.enabled.checknulls.bsl - - -REM ------------- - From a8422c9511afc4590169e06131ce14feaa54e33b Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 14 Jun 2024 10:39:27 +0200 Subject: [PATCH 3/7] removed from .sln --- VisualFSharp.sln | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/VisualFSharp.sln b/VisualFSharp.sln index 09fbb1e2bbe..4f1ab0fa06f 100644 --- a/VisualFSharp.sln +++ b/VisualFSharp.sln @@ -187,7 +187,6 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Editor.Tests", "vsin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.Editor.IntegrationTests", "vsintegration\tests\FSharp.Editor.IntegrationTests\FSharp.Editor.IntegrationTests.csproj", "{E31F9B59-FCF1-4D04-8762-C7BB60285A7B}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "nullness", "tests\adhoc\nullness\nullness.fsproj", "{6992D926-AB1C-4CD4-94D5-0319D14DB54B}" Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Benchmarks.Common", "tests\benchmarks\FSharp.Benchmarks.Common\FSharp.Benchmarks.Common.fsproj", "{6734FC6F-B5F3-45E1-9A72-720378BB49C9}" EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MicroPerf", "tests\benchmarks\CompiledCodeBenchmarks\MicroPerf\MicroPerf.fsproj", "{601CD5C1-EAFA-4AE3-8FB9-F667B5728213}" @@ -984,18 +983,6 @@ Global {E31F9B59-FCF1-4D04-8762-C7BB60285A7B}.Release|Any CPU.Build.0 = Release|Any CPU {E31F9B59-FCF1-4D04-8762-C7BB60285A7B}.Release|x86.ActiveCfg = Release|Any CPU {E31F9B59-FCF1-4D04-8762-C7BB60285A7B}.Release|x86.Build.0 = Release|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Debug|x86.ActiveCfg = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Debug|x86.Build.0 = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Proto|Any CPU.ActiveCfg = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Proto|Any CPU.Build.0 = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Proto|x86.ActiveCfg = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Proto|x86.Build.0 = Debug|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Release|Any CPU.Build.0 = Release|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Release|x86.ActiveCfg = Release|Any CPU - {6992D926-AB1C-4CD4-94D5-0319D14DB54B}.Release|x86.Build.0 = Release|Any CPU {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {6734FC6F-B5F3-45E1-9A72-720378BB49C9}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -1109,7 +1096,6 @@ Global {39CDF34B-FB23-49AE-AB27-0975DA379BB5} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} {CBC96CC7-65AB-46EA-A82E-F6A788DABF80} = {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} {E31F9B59-FCF1-4D04-8762-C7BB60285A7B} = {F7876C9B-FB6A-4EFB-B058-D6967DB75FB2} - {6992D926-AB1C-4CD4-94D5-0319D14DB54B} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449} {6734FC6F-B5F3-45E1-9A72-720378BB49C9} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} {601CD5C1-EAFA-4AE3-8FB9-F667B5728213} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} {9F9DD315-37DA-4413-928E-1CFC6924B64F} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B} From 0ef6b4f7b48c72b538c5c8ce26ea96614556f7dc Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 17 Jun 2024 14:36:34 +0200 Subject: [PATCH 4/7] 'format' on Console.WriteLine is not nullable, adjusting tests --- .../Nullness/using-nullness-syntax-positive.fs | 10 +++++----- ...g-nullness-syntax-positive.fs.checknulls_on.err.bsl | 5 ++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs index 30d1b647779..205fbc16ff0 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs @@ -80,22 +80,22 @@ module InteropBasics = type KonsoleWithNulls = static member WriteLine(s: String | null) = Console.WriteLine(s) - static member WriteLine(fmt: String | null, arg1: String | null) = Console.WriteLine(fmt, arg1) - static member WriteLine(fmt: String | null, [] args: (obj | null)[] | null) = Console.WriteLine(fmt, args) + static member WriteLine(fmt: String, arg1: String | null) = Console.WriteLine(fmt, arg1) + static member WriteLine(fmt: String, [] args: (obj | null)[] | null) = Console.WriteLine(fmt, args) static member WriteLineC(s: C | null) = Console.WriteLine(s.Value) static member WriteLineC(fmt: C | null, arg1: C | null) = Console.WriteLine(fmt.Value, arg1.Value) module KonsoleWithNullsModule = let WriteLine(s: String | null) = Console.WriteLine(s) - let WriteLine2(fmt: String | null, arg1: String | null) = Console.WriteLine(fmt, arg1) + let WriteLine2(fmt: String, arg1: String | null) = Console.WriteLine(fmt, arg1) let WriteLineC(s: C | null) = Console.WriteLine(s.Value) let WriteLineC2(fmt: C | null, arg1: C | null) = Console.WriteLine(fmt.Value, arg1.Value) module KonsoleWithNullsModule2 = let WriteLine (x : string | null) = KonsoleWithNullsModule.WriteLine x - let WriteLine2 (fmt: string | null, arg1: string | null) = KonsoleWithNullsModule.WriteLine2(fmt, arg1) + let WriteLine2 (fmt: string, arg1: string | null) = KonsoleWithNullsModule.WriteLine2(fmt, arg1) let WriteLineC(s: _ | null) = KonsoleWithNullsModule.WriteLineC(s) - let WriteLineC2(fmt: _ | null, arg1: _ | null) = KonsoleWithNullsModule.WriteLineC2(fmt, arg1) + let WriteLineC2(fmt: _ , arg1: _ | null) = KonsoleWithNullsModule.WriteLineC2(fmt, arg1) type KonsoleNoNulls = static member WriteLine(s: String) = Console.WriteLine(s) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl index ceb1aa1a311..d3a2490d94d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl @@ -11,15 +11,12 @@ using-nullness-syntax-positive.fs (28,14)-(28,19) typecheck error Nullness warni using-nullness-syntax-positive.fs (29,14)-(29,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (29,14)-(29,17) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (43,26)-(43,30) typecheck error Nullness warning: The type 'String' does not support 'null'. -using-nullness-syntax-positive.fs (83,72)-(83,100) typecheck error Nullness warning: The types 'string' and 'String | null' do not have compatible nullability. -using-nullness-syntax-positive.fs (84,95)-(84,123) typecheck error Nullness warning: The types 'string' and 'String | null' do not have compatible nullability. using-nullness-syntax-positive.fs (85,63)-(85,70) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (85,63)-(85,70) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (86,81)-(86,90) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (86,81)-(86,90) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (86,92)-(86,102) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (86,92)-(86,102) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. -using-nullness-syntax-positive.fs (90,63)-(90,91) typecheck error Nullness warning: The types 'string' and 'String | null' do not have compatible nullability. using-nullness-syntax-positive.fs (91,53)-(91,60) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (91,53)-(91,60) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. using-nullness-syntax-positive.fs (92,72)-(92,81) typecheck error Nullness warning: The types 'C' and 'C | null' do not have compatible nullability. @@ -29,6 +26,8 @@ using-nullness-syntax-positive.fs (92,83)-(92,93) typecheck error Nullness warni using-nullness-syntax-positive.fs (120,32)-(120,36) typecheck error Nullness warning: The type 'obj array' does not support 'null'. using-nullness-syntax-positive.fs (129,4)-(129,34) typecheck error Nullness warning: The type 'String' does not support 'null'. using-nullness-syntax-positive.fs (134,5)-(134,44) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (144,39)-(144,43) typecheck error Nullness warning: The type 'String' does not support 'null'. +using-nullness-syntax-positive.fs (154,40)-(154,44) typecheck error Nullness warning: The type 'string' does not support 'null'. using-nullness-syntax-positive.fs (159,36)-(159,40) typecheck error Nullness warning: The type 'String' does not support 'null'. using-nullness-syntax-positive.fs (162,41)-(162,45) typecheck error Nullness warning: The type 'String' does not support 'null'. using-nullness-syntax-positive.fs (164,37)-(164,41) typecheck error Nullness warning: The type 'String' does not support 'null'. From 3d094e1e1fa248d828c3c45718b784067f9c14d9 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 17 Jun 2024 16:09:23 +0200 Subject: [PATCH 5/7] Fix DefaultValue() checks in legacy mode --- src/Compiler/Checking/PostInferenceChecks.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs index e3d12a61ebe..878a70939d0 100644 --- a/src/Compiler/Checking/PostInferenceChecks.fs +++ b/src/Compiler/Checking/PostInferenceChecks.fs @@ -2555,7 +2555,7 @@ let CheckEntityDefn cenv env (tycon: Entity) = // Check if it's marked unsafe let zeroInitUnsafe = TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute f.FieldAttribs if zeroInitUnsafe = Some true then - if not (TypeHasDefaultValue g m ty) then + if not (TypeHasDefaultValue g m f.FormalType) then errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) // Check type abbreviations From 16f127cac889b6abbab3a2df86bdb331d568daed Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 17 Jun 2024 17:18:37 +0200 Subject: [PATCH 6/7] DefaultValue regression - still fails at TRANSPARENT_COMPILER setting --- .../Nullness/NullableRegressionTests.fs | 30 ++++++++++++++++++- .../Language/Nullness/existing-negative.fs | 2 +- ...existing-negative.fs.checknulls_on.err.bsl | 2 -- ...ting-negative.fs.nullness_disabled.err.bsl | 4 +-- .../using-nullness-syntax-positive.fs | 2 +- ...s-syntax-positive.fs.checknulls_on.err.bsl | 4 +-- ...ntax-positive.fs.nullness_disabled.err.bsl | 2 -- 7 files changed, 33 insertions(+), 13 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs index 9445ade1c1f..37860cfae4f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs @@ -86,4 +86,32 @@ let ``With new nullness syntax nullness disabled`` compilation = let ``With new nullness syntax nullness enabled`` compilation = compilation |> withVersionAndCheckNulls ("preview",true) - |> verifyBaseline \ No newline at end of file + |> verifyBaseline + +[] +[] +[] +[] +[] +[] +[] +let ``DefaultValue regression`` (version,checknulls,fullCompile) = + FSharp $""" +module MyLib + +[] +type C7 = + [] + val mutable Whoops : (int -> int) {if version="preview" then " | null" else ""} // no warnings in checknulls+ + """ + |> asLibrary + |> withVersionAndCheckNulls (version,checknulls) + |> (if fullCompile then compile else typecheck) + |> fun x -> + if checknulls then + x |> shouldSucceed + else + x + |> shouldFail + |> withDiagnostics + [(Error 444, Line 7, Col 17, Line 7, Col 23, "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")] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs index 0052503aef8..2f46eb0370e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/existing-negative.fs @@ -31,7 +31,7 @@ module DefaultValueTests = [] val mutable Whoops : int * int // This gave an error in F# 4.5 and we expect it to continue to give an error - [] + [] type C6 = [] val mutable Whoops : int -> int // This gave an error in F# 4.5 and we expect it to continue to give an error 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 c18a0386eaf..cada047d442 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,8 +1,6 @@ existing-negative.fs (10,17)-(10,33) typecheck error Nullness warning: The type '(int * int)' does not support 'null'. existing-negative.fs (12,17)-(12,28) typecheck error Nullness warning: The type 'int list' does not support 'null'. existing-negative.fs (14,17)-(14,30) typecheck error Nullness warning: The type '(int -> int)' does not support 'null'. -existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' is not structurally comparable because the type '(int -> int)' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C6' to clarify that the type is not comparable -existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' does not support structural equality because the type '(int -> int)' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C6' to clarify that the type does not support structural equality 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 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 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 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 910f3bc6ce3..eaffe804e94 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,5 +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 (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 -existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' is not structurally comparable because the type '(int -> int)' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C6' to clarify that the type is not comparable -existing-negative.fs (35,14)-(35,16) typecheck error The struct, record or union type 'C6' does not support structural equality because the type '(int -> int)' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C6' to clarify that the type does not support structural equality \ 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/using-nullness-syntax-positive.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs index 205fbc16ff0..8f2efd0e02d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs @@ -213,7 +213,7 @@ module DefaultValueTests = [] val mutable Whoops : FSharp.Collections.List | null // expect no warning - [] + [] type C7 = [] val mutable Whoops : (int -> int) | null // expect no warning diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl index d3a2490d94d..5154ce43e79 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.checknulls_on.err.bsl @@ -32,6 +32,4 @@ using-nullness-syntax-positive.fs (159,36)-(159,40) typecheck error Nullness war using-nullness-syntax-positive.fs (162,41)-(162,45) typecheck error Nullness warning: The type 'String' does not support 'null'. using-nullness-syntax-positive.fs (164,37)-(164,41) typecheck error Nullness warning: The type 'String' does not support 'null'. using-nullness-syntax-positive.fs (183,14)-(183,16) typecheck error Nullness warning: The type 'string' does not support 'null'. -using-nullness-syntax-positive.fs (189,17)-(189,26) typecheck error Nullness warning: The type 'String' does not support 'null'. -using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' is not structurally comparable because the type '(int -> int) | null' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C7' to clarify that the type is not comparable -using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' does not support structural equality because the type '(int -> int) | null' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C7' to clarify that the type does not support structural equality \ No newline at end of file +using-nullness-syntax-positive.fs (189,17)-(189,26) typecheck error Nullness warning: The type 'String' does not support 'null'. \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl index a13a4882dd6..cd596951cfe 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/using-nullness-syntax-positive.fs.nullness_disabled.err.bsl @@ -1,6 +1,4 @@ using-nullness-syntax-positive.fs (13,18)-(13,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. using-nullness-syntax-positive.fs (19,26)-(19,28) typecheck error Nullness warning: The type 'int option' uses 'null' as a representation value but a non-null type is expected. -using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' is not structurally comparable because the type '(int -> int) | null' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type 'C7' to clarify that the type is not comparable -using-nullness-syntax-positive.fs (217,14)-(217,16) typecheck error The struct, record or union type 'C7' does not support structural equality because the type '(int -> int) | null' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type 'C7' to clarify that the type does not support structural equality using-nullness-syntax-positive.fs (214,25)-(214,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 using-nullness-syntax-positive.fs (219,25)-(219,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 \ No newline at end of file From 5fd3562848df3b1df0c3f7ebbf319f29115b539f Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 18 Jun 2024 14:12:41 +0200 Subject: [PATCH 7/7] Fix TransparentCompiler - it should report PostInference errors if it only encountered a warning (reported as an error due to confiig) --- src/Compiler/Driver/CompilerDiagnostics.fs | 5 +++++ src/Compiler/Facilities/DiagnosticsLogger.fs | 3 +++ src/Compiler/Facilities/DiagnosticsLogger.fsi | 3 +++ src/Compiler/Service/IncrementalBuild.fs | 4 ++-- src/Compiler/Service/TransparentCompiler.fs | 2 +- .../Language/Nullness/NullableRegressionTests.fs | 8 ++++++++ .../Language/Nullness/positive-defaultValue-bug.fs | 13 +++++++++++++ ...ve-defaultValue-bug.fs.nullness_disabled.err.bsl | 2 ++ 8 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 51eb8ece3a0..5ac8f448448 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -2236,8 +2236,11 @@ type DiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) = inherit DiagnosticsLogger("DiagnosticsLoggerFilteringByScopedPragmas") + let mutable realErrorPresent = false + override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity) = if severity = FSharpDiagnosticSeverity.Error then + realErrorPresent <- true diagnosticsLogger.DiagnosticSink(diagnostic, severity) else let report = @@ -2265,5 +2268,7 @@ type DiagnosticsLoggerFilteringByScopedPragmas override _.ErrorCount = diagnosticsLogger.ErrorCount + override _.CheckForRealErrorsIgnoringWarnings = realErrorPresent + let GetDiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) = DiagnosticsLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index f562e5df494..194ee479717 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -351,6 +351,9 @@ type DiagnosticsLogger(nameForDebugging: string) = member x.CheckForErrors() = (x.ErrorCount > 0) + abstract CheckForRealErrorsIgnoringWarnings: bool + default x.CheckForRealErrorsIgnoringWarnings = x.CheckForErrors() + member _.DebugDisplay() = sprintf "DiagnosticsLogger(%s)" nameForDebugging diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index 69aa0eddec1..ef75d0e5b28 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -208,6 +208,9 @@ type DiagnosticsLogger = /// Checks if ErrorCount > 0 member CheckForErrors: unit -> bool + abstract CheckForRealErrorsIgnoringWarnings: bool + default CheckForRealErrorsIgnoringWarnings: bool + /// Represents a DiagnosticsLogger that discards diagnostics val DiscardErrorsLogger: DiagnosticsLogger diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs index c8cc9a77e1f..43a7a9cde96 100644 --- a/src/Compiler/Service/IncrementalBuild.fs +++ b/src/Compiler/Service/IncrementalBuild.fs @@ -491,10 +491,10 @@ type FrameworkImportsCacheKey = interface ICacheKey with member this.GetKey() = - this |> function FrameworkImportsCacheKey(assemblyName=a) -> a + this |> function FrameworkImportsCacheKey(assemblyName=a;checkNulls=c) -> if c then a + "CheckNulls" else a member this.GetLabel() = - this |> function FrameworkImportsCacheKey(assemblyName=a) -> a + this |> function FrameworkImportsCacheKey(assemblyName=a;checkNulls=c) -> if c then a + "CheckNulls" else a member this.GetVersion() = this diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs index 32766202cd4..734dd2a1eee 100644 --- a/src/Compiler/Service/TransparentCompiler.fs +++ b/src/Compiler/Service/TransparentCompiler.fs @@ -1320,7 +1320,7 @@ type internal TransparentCompiler let! finisher = CheckOneInputWithCallback nodeToCheck - ((fun () -> hadParseErrors || diagnosticsLogger.ErrorCount > 0), + ((fun () -> hadParseErrors || diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), tcConfig, tcImports, tcGlobals, diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs index 37860cfae4f..e6398675a01 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs @@ -82,12 +82,20 @@ let ``With new nullness syntax nullness disabled`` compilation = |> withVersionAndCheckNulls ("preview",false) |> verifyBaseline +[] +let ``DefaultValueBug when checknulls is disabled`` compilation = + compilation + |> withVersionAndCheckNulls ("preview",false) + |> verifyBaseline + [] let ``With new nullness syntax nullness enabled`` compilation = compilation |> withVersionAndCheckNulls ("preview",true) |> verifyBaseline + + [] [] [] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs new file mode 100644 index 00000000000..f4b7c1b03d2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs @@ -0,0 +1,13 @@ +module EnabledPositive +open System + +module NotNullConstraint = + let f3 (x: 'T when 'T : not null) = 1 + let v5 = f3 (Some 1) // Expect to give a warning + //let w5 = (Some 1) |> f3 // Expect to give a warning + + +[] +type C4b = + [] + val mutable Whoops : FSharp.Collections.List | null // expect no warning \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl new file mode 100644 index 00000000000..22970adc345 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/positive-defaultValue-bug.fs.nullness_disabled.err.bsl @@ -0,0 +1,2 @@ +positive-defaultValue-bug.fs (6,18)-(6,24) typecheck error Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected. +positive-defaultValue-bug.fs (13,17)-(13,23) 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 \ No newline at end of file