diff --git a/.gitignore b/.gitignore index 013ade3ce24..f0dbae4d2f3 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,5 @@ tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstanda *.vsp /tests/AheadOfTime/Trimming/output.txt *.svclog +micro.exe +positive.exe \ No newline at end of file diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index 08c82f9b270..020aa4498a5 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -931,8 +931,9 @@ let mkCacheInt32 lowMem _inbase _nm _sz = (fun f x -> f x) else let mutable cache: ConcurrentDictionary MaybeNull = null // TODO NULLNESS: this explicit annotation should not be needed - let mutable count = 0 #if STATISTICS + let mutable count = 0 + addReport (fun oc -> if count <> 0 then oc.WriteLine((_inbase + string count + " " + _nm + " cache hits"): string)) @@ -948,7 +949,9 @@ let mkCacheInt32 lowMem _inbase _nm _sz = match cache.TryGetValue idx with | true, res -> +#if STATISTICS count <- count + 1 +#endif res | _ -> let res = f idx @@ -960,8 +963,9 @@ let mkCacheGeneric lowMem _inbase _nm _sz = (fun f x -> f x) else let mutable cache: ConcurrentDictionary<_, _> MaybeNull = null // TODO NULLNESS: this explicit annotation should not be needed - let mutable count = 0 #if STATISTICS + let mutable count = 0 + addReport (fun oc -> if !count <> 0 then oc.WriteLine((_inbase + string !count + " " + _nm + " cache hits"): string)) @@ -977,7 +981,9 @@ let mkCacheGeneric lowMem _inbase _nm _sz = match cache.TryGetValue idx with | true, v -> +#if STATISTICS count <- count + 1 +#endif v | _ -> let res = f idx diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 4187313ad99..ada2ea0abca 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -1040,6 +1040,7 @@ let TcAddNullnessToType (warn: bool) (cenv: cenv) (env: TcEnv) nullness innerTyC if not g.compilingFSharpCore || not (isTyparTy g innerTyC) then AddCxTypeDefnNotSupportsNull env.DisplayEnv cenv.css m NoTrace innerTyC + AddCxTypeIsReferenceType env.DisplayEnv cenv.css m NoTrace innerTyC if not g.compilingFSharpCore && isTyparTy g innerTyC then // A typar might be later infered into a type not supporting `| null|, like tuple or anon. @@ -5314,6 +5315,7 @@ and TcExprFlex (cenv: cenv) flex compat (desiredTy: TType) (env: TcEnv) tpenv (s if flex then let argTy = NewInferenceType g + (destTyparTy g argTy).SetSupportsNullFlex(true) if compat then (destTyparTy g argTy).SetIsCompatFlex(true) @@ -9601,7 +9603,8 @@ and TcEventItemThen (cenv: cenv) overallTy env tpenv mItem mExprAndItem objDetai | None, false -> error (Error (FSComp.SR.tcEventIsNotStatic nm, mItem)) | _ -> () - let delTy = einfo.GetDelegateType(cenv.amap, mItem) + // The F# wrappers around events are null safe (impl is in FSharp.Core). Therefore, from an F# perspective, the type of the delegate can be considered Not Null. + let delTy = einfo.GetDelegateType(cenv.amap, mItem) |> replaceNullnessOfTy KnownWithoutNull let (SigOfFunctionForDelegate(delInvokeMeth, delArgTys, _, _)) = GetSigOfFunctionForDelegate cenv.infoReader delTy mItem ad let objArgs = Option.toList (Option.map fst objDetails) MethInfoChecks g cenv.amap true None objArgs env.eAccessRights mItem delInvokeMeth diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 862ae747fdc..09eedf6c706 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -308,6 +308,9 @@ type ConstraintSolverEnv = // Is this speculative, with a trace allowing undo, and trial method overload resolution IsSpeculativeForMethodOverloading: bool + // Can this ignore the 'must support null' constraint, e.g. in a mutable assignment scenario + IsSupportsNullFlex: bool + /// Indicates that when unifying ty1 = ty2, only type variables in ty1 may be solved. Constraints /// can't be added to type variables in ty2 MatchingOnly: bool @@ -344,6 +347,7 @@ let MakeConstraintSolverEnv contextInfo css m denv = EquivEnv = TypeEquivEnv.Empty DisplayEnv = denv IsSpeculativeForMethodOverloading = false + IsSupportsNullFlex = false ExtraRigidTypars = emptyFreeTypars } @@ -953,6 +957,13 @@ let rec SolveTyparEqualsTypePart1 (csenv: ConstraintSolverEnv) m2 (trace: Option // Record the solution before we solve the constraints, since // We may need to make use of the equation when solving the constraints. // Record a entry in the undo trace if one is provided + + //let ty1AllowsNull = r.Constraints |> List.exists (function | TyparConstraint.SupportsNull _ -> true | _ -> false ) + //let tyAllowsNull() = TypeNullIsExtraValueNew csenv.g m2 ty + //if ty1AllowsNull && not (tyAllowsNull()) then + // trace.Exec (fun () -> r.typar_solution <- Some (ty |> replaceNullnessOfTy csenv.g.knownWithNull)) (fun () -> r.typar_solution <- None) + //else + // trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) trace.Exec (fun () -> r.typar_solution <- Some ty) (fun () -> r.typar_solution <- None) } @@ -1218,6 +1229,12 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr let sty1 = stripTyEqnsA csenv.g canShortcut ty1 let sty2 = stripTyEqnsA csenv.g canShortcut ty2 + let csenv = + match ty1 with + | TType.TType_var(r,_) when r.typar_flags.IsSupportsNullFlex -> + { csenv with IsSupportsNullFlex = true} + | _ -> csenv + match sty1, sty2 with // type vars inside forall-types may be alpha-equivalent | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when typarEq tp1 tp2 || (match aenv.EquivTypars.TryFind tp1 with | Some tpTy1 when typeEquiv g tpTy1 ty2 -> true | _ -> false) -> @@ -1273,6 +1290,15 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr // Unifying 'T1? and 'T2? | ValueSome NullnessInfo.WithNull, ValueSome NullnessInfo.WithNull -> SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2) + | ValueSome NullnessInfo.WithoutNull, ValueSome NullnessInfo.WithoutNull when + csenv.IsSupportsNullFlex && + isAppTy g sty2 && + tp1.Constraints |> List.exists (function TyparConstraint.SupportsNull _ -> true | _ -> false) -> + let tpNew = NewCompGenTypar(TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false) + trackErrors { + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln (TType_var(tpNew, g.knownWithoutNull)) sty2 + do! SolveTypeEqualsType csenv ndeep m2 trace cxsln ty1 (TType_var(tpNew, g.knownWithNull)) + } // Unifying 'T1 % and 'T2 % //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> // SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2) @@ -2354,6 +2380,10 @@ and EnforceConstraintConsistency (csenv: ConstraintSolverEnv) ndeep m2 trace ret | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsReferenceType _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsNonNullableStruct _ -> return! ErrorD (Error(FSComp.SR.csStructConstraintInconsistent(), m)) + + | TyparConstraint.SupportsNull _, TyparConstraint.NotSupportsNull _ + | TyparConstraint.NotSupportsNull _, TyparConstraint.SupportsNull _ -> + return! ErrorD (Error(FSComp.SR.csNullNotNullConstraintInconsistent(), m)) | TyparConstraint.IsUnmanaged _, TyparConstraint.IsReferenceType _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsUnmanaged _ -> @@ -2534,16 +2564,18 @@ and SolveTypeUseSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty = return! ErrorD (ConstraintSolverError(FSComp.SR.csNullableTypeDoesNotHaveNull(NicePrint.minimalStringOfType denv ty), m, m2)) else match tryDestTyparTy g ty with - | ValueSome tp -> + | ValueSome tp -> let nullness = nullnessOfTy g ty match nullness.TryEvaluate() with // NULLNESS TODO: This rule means turning on checkNullness changes type inference results for the cases // mentioned in the comment above. THat's OK but needs to be documented in the RFC. | ValueNone when not g.checkNullness -> - return! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m) - | ValueSome NullnessInfo.WithoutNull -> + return! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m) + | ValueSome NullnessInfo.WithoutNull -> return! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.SupportsNull m) | _ -> + if tp.Constraints |> List.exists (function | TyparConstraint.IsReferenceType _ -> true | _ -> false) |> not then + do! AddConstraint csenv ndeep m2 trace tp (TyparConstraint.IsReferenceType m) return! SolveNullnessSupportsNull csenv ndeep m2 trace ty nullness | _ -> let nullness = nullnessOfTy g ty @@ -2580,9 +2612,10 @@ and SolveNullnessSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 (trace: Opti match n1 with | NullnessInfo.AmbivalentToNull -> () | NullnessInfo.WithNull -> () - | NullnessInfo.WithoutNull -> + | NullnessInfo.WithoutNull -> if g.checkNullness then - return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2)) + // TODO nullness: Shouldn't this be an error? We have a 'must support null' situation which is not being met. + return! WarnD(ConstraintSolverNullnessWarningWithType(denv, ty, n1, m, m2)) } and SolveTypeUseNotSupportsNull (csenv: ConstraintSolverEnv) ndeep m2 trace ty = @@ -2635,7 +2668,9 @@ and SolveTypeCanCarryNullness (csenv: ConstraintSolverEnv) ty nullness = let m = csenv.m let strippedTy = stripTyEqnsA g true ty match tryAddNullnessToTy nullness strippedTy with - | Some _ -> () + | Some _ -> + if isTyparTy g strippedTy && not (isReferenceTyparTy g strippedTy) then + return! AddConstraint csenv 0 m NoTrace (destTyparTy g strippedTy) (TyparConstraint.IsReferenceType m) | None -> let tyString = NicePrint.minimalStringOfType csenv.DisplayEnv strippedTy return! ErrorD(Error(FSComp.SR.tcTypeDoesNotHaveAnyNull(tyString), m)) diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 5393978d77d..2bb1c5242f7 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -5648,7 +5648,7 @@ and GenGenericParam cenv eenv (tp: Typar) = | TyparConstraint.IsNonNullableStruct _ -> true | _ -> false) - let notNullReferenceTypeConstraint = + let nullnessOfTypar = if g.langFeatureNullness && g.checkNullness then let hasNotSupportsNull = tp.Constraints @@ -5656,9 +5656,15 @@ and GenGenericParam cenv eenv (tp: Typar) = | TyparConstraint.NotSupportsNull _ -> true | _ -> false) + let hasSupportsNull () = + tp.Constraints + |> List.exists (function + | TyparConstraint.SupportsNull _ -> true + | _ -> false) + if hasNotSupportsNull || notNullableValueTypeConstraint then NullnessInfo.WithoutNull - elif hasNotSupportsNull || refTypeConstraint then + elif refTypeConstraint || hasSupportsNull () then NullnessInfo.WithNull else NullnessInfo.AmbivalentToNull @@ -5711,7 +5717,7 @@ and GenGenericParam cenv eenv (tp: Typar) = yield! GenAttrs cenv eenv tp.Attribs if emitUnmanagedInIlOutput then yield (GetIsUnmanagedAttribute g) - match notNullReferenceTypeConstraint with + match nullnessOfTypar with | Some nullInfo -> yield GetNullableAttribute g [ nullInfo ] | _ -> () ] diff --git a/src/Compiler/CodeGen/IlxGenSupport.fs b/src/Compiler/CodeGen/IlxGenSupport.fs index 0c641898f24..4be01ced411 100644 --- a/src/Compiler/CodeGen/IlxGenSupport.fs +++ b/src/Compiler/CodeGen/IlxGenSupport.fs @@ -446,8 +446,8 @@ let rec GetNullnessFromTType (g: TcGlobals) ty = ] | TType_forall _ | TType_ucase _ - | TType_var _ | TType_measure _ -> [] + | TType_var(nullness = nullness) -> [ nullness.Evaluate() ] let GenNullnessIfNecessary (g: TcGlobals) ty = if g.langFeatureNullness && g.checkNullness then diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index e071c3cec89..4f313e1db39 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -300,7 +300,7 @@ type TyparRigidity = [] type TyparFlags(flags: int32) = - new (kind: TyparKind, rigidity: TyparRigidity, isFromError: bool, isCompGen: bool, staticReq: TyparStaticReq, dynamicReq: TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool) = + new (kind: TyparKind, rigidity: TyparRigidity, isFromError: bool, isCompGen: bool, staticReq: TyparStaticReq, dynamicReq: TyparDynamicReq, equalityDependsOn: bool, comparisonDependsOn: bool, supportsNullFlex: bool) = TyparFlags((if isFromError then 0b00000000000000010 else 0) ||| (if isCompGen then 0b00000000000000100 else 0) ||| (match staticReq with @@ -321,7 +321,11 @@ type TyparFlags(flags: int32) = | TyparDynamicReq.No -> 0b00000000000000000 | TyparDynamicReq.Yes -> 0b00000010000000000) ||| (if equalityDependsOn then - 0b00000100000000000 else 0)) + 0b00000100000000000 else 0) ||| + // 0b00001000100000000 is being checked by x.Kind, but never set in this version of the code + // 0b00010000000000000 is taken by compat flex + (if supportsNullFlex then + 0b00100000000000000 else 0)) /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns member x.IsFromError = (flags &&& 0b00000000000000010) <> 0x0 @@ -380,8 +384,20 @@ type TyparFlags(flags: int32) = else TyparFlags(flags &&& ~~~0b00010000000000000) + /// Indicates that whether this type parameter is flexible for 'supports null' constraint, e.g. in the case of assignment to a mutable value + member x.IsSupportsNullFlex = + (flags &&& 0b00100000000000000) <> 0x0 + + member x.WithSupportsNullFlex b = + if b then + TyparFlags(flags ||| 0b00100000000000000) + else + TyparFlags(flags &&& ~~~0b00100000000000000) + + + member x.WithStaticReq staticReq = - TyparFlags(x.Kind, x.Rigidity, x.IsFromError, x.IsCompilerGenerated, staticReq, x.DynamicReq, x.EqualityConditionalOn, x.ComparisonConditionalOn) + TyparFlags(x.Kind, x.Rigidity, x.IsFromError, x.IsCompilerGenerated, staticReq, x.DynamicReq, x.EqualityConditionalOn, x.ComparisonConditionalOn, x.IsSupportsNullFlex) /// Get the flags as included in the F# binary metadata. We pickle this as int64 to allow for future expansion member x.PickledBits = flags @@ -2321,6 +2337,8 @@ type Typar = /// Set whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) member x.SetIsCompatFlex b = x.typar_flags <- x.typar_flags.WithCompatFlex b + member x.SetSupportsNullFlex b = x.typar_flags <- x.typar_flags.WithSupportsNullFlex b + /// Indicates whether a type variable can be instantiated by types or units-of-measure. member x.Kind = x.typar_flags.Kind @@ -2425,12 +2443,12 @@ type Typar = /// Sets the rigidity of a type variable member x.SetRigidity b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, b, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, b, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether a type variable is compiler generated member x.SetCompilerGenerated b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, b, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, b, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether a type variable has a static requirement member x.SetStaticReq b = @@ -2439,17 +2457,17 @@ type Typar = /// Sets whether a type variable is required at runtime member x.SetDynamicReq b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, b, flags.EqualityConditionalOn, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, b, flags.EqualityConditionalOn, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether the equality constraint of a type definition depends on this type variable member x.SetEqualityDependsOn b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, b, flags.ComparisonConditionalOn) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, b, flags.ComparisonConditionalOn, flags.IsSupportsNullFlex) /// Sets whether the comparison constraint of a type definition depends on this type variable member x.SetComparisonDependsOn b = let flags = x.typar_flags - x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b) + x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b, flags.IsSupportsNullFlex) [] member x.DebugText = x.ToString() @@ -6118,7 +6136,7 @@ type Construct() = Typar.New { typar_id = id typar_stamp = newStamp() - typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep) + typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep, false) typar_solution = None typar_astype = Unchecked.defaultof<_> typar_opt_data = diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index a9d6e148411..9c688826ae0 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -205,7 +205,8 @@ type TyparFlags = staticReq: Syntax.TyparStaticReq * dynamicReq: TyparDynamicReq * equalityDependsOn: bool * - comparisonDependsOn: bool -> + comparisonDependsOn: bool * + supportsNullFlex: bool -> TyparFlags new: flags: int32 -> TyparFlags @@ -232,6 +233,9 @@ type TyparFlags = /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns member IsFromError: bool + /// Indicates whether this type parameter is flexible for 'supports null' constraint, e.g. in the case of assignment to a mutable value + member IsSupportsNullFlex: bool + /// Indicates whether a type variable can be instantiated by types or units-of-measure. member Kind: TyparKind @@ -1552,6 +1556,9 @@ type Typar = /// Set whether this type parameter is a compat-flex type parameter (i.e. where "expr :> tp" only emits an optional warning) member SetIsCompatFlex: b: bool -> unit + /// Set whether this type parameter is flexible for 'supports null' constraint, e.g. in the case of assignment to a mutable value + member SetSupportsNullFlex: b: bool -> unit + /// Sets the rigidity of a type variable member SetRigidity: b: TyparRigidity -> unit diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fs b/src/Compiler/TypedTree/TypedTreeBasics.fs index e3d152f84d1..dcde4261740 100644 --- a/src/Compiler/TypedTree/TypedTreeBasics.fs +++ b/src/Compiler/TypedTree/TypedTreeBasics.fs @@ -283,7 +283,12 @@ let addNullnessToTy (nullness: Nullness) (ty:TType) = | _ -> match ty with | TType_var (tp, nullnessOrig) -> TType_var (tp, combineNullness nullnessOrig nullness) - | TType_app (tcr, tinst, nullnessOrig) -> TType_app (tcr, tinst, combineNullness nullnessOrig nullness) + | TType_app (tcr, tinst, nullnessOrig) -> + let tycon = tcr.Deref + if tycon.IsStructRecordOrUnionTycon || tycon.IsStructOrEnumTycon then + ty + 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 diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1 index 0d4ce210652..ac29e823254 100644 --- a/tests/AheadOfTime/Trimming/check.ps1 +++ b/tests/AheadOfTime/Trimming/check.ps1 @@ -45,5 +45,5 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) { # Check net7.0 trimmed assemblies CheckTrim -root "SelfContained_Trimming_Test" -tfm "net8.0" -outputfile "FSharp.Core.dll" -expected_len 286208 -# Check net8.0 trimmed assemblies +# Check net7.0 trimmed assemblies CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net8.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8819200 \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs index 7245cd2cd8e..f289363294b 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs @@ -1,6 +1,6 @@ module MyTestModule -type Maybe<'T> = 'T | null +type Maybe<'T when 'T: not struct> = 'T | null type MaybeString = string | null let curried3Func (a:MaybeString) (b:string) (c:int) = (a,b,c) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl index 083abfd072c..a01419f0ed0 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.net472.bsl @@ -32,8 +32,7 @@ { .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) .field public string propperString - .method assembly specialname rtspecialname - instance void .ctor(string propperString) cil managed + .method assembly specialname rtspecialname instance void .ctor(string propperString) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -87,8 +86,7 @@ IL_0008: ret } - .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> - partiallyAplied(string propperString) cil managed + .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> partiallyAplied(string propperString) cil managed { .param [0] .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 06 00 00 00 01 01 01 01 02 01 00 00 ) @@ -99,11 +97,11 @@ IL_0006: ret } - .method public static !!b secondOutOfTriple(!!a a, - !!b b, - !!c c, - !!d d, - !!e e) cil managed + .method public static !!b secondOutOfTriple(!!a a, + !!b b, + !!c c, + !!d d, + !!e e) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 03 00 00 00 01 00 00 00 01 00 00 00 00 00 ) @@ -117,6 +115,10 @@ .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) .param type e .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param [0] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [2] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) .maxstack 8 IL_0000: ldarg.1 @@ -137,8 +139,7 @@ .field public uint8[] NullableFlags .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 scalarByteValue) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -157,8 +158,7 @@ IL_0016: ret } - .method public specialname rtspecialname - instance void .ctor(uint8[] NullableFlags) cil managed + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -181,8 +181,7 @@ .field public uint8 Flag .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 Flag) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl index 5d449672a57..02d5e2cbe40 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/CurriedFunctions.fs.il.netcore.bsl @@ -32,8 +32,7 @@ { .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) .field public string propperString - .method assembly specialname rtspecialname - instance void .ctor(string propperString) cil managed + .method assembly specialname rtspecialname instance void .ctor(string propperString) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -87,8 +86,7 @@ IL_0008: ret } - .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> - partiallyAplied(string propperString) cil managed + .method public static class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>> partiallyAplied(string propperString) cil managed { .param [0] .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 06 00 00 00 01 01 01 01 02 01 00 00 ) @@ -99,11 +97,11 @@ IL_0006: ret } - .method public static !!b secondOutOfTriple(!!a a, - !!b b, - !!c c, - !!d d, - !!e e) cil managed + .method public static !!b secondOutOfTriple(!!a a, + !!b b, + !!c c, + !!d d, + !!e e) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 03 00 00 00 01 00 00 00 01 00 00 00 00 00 ) @@ -117,6 +115,10 @@ .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) .param type e .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .param [0] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [2] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) .maxstack 8 IL_0000: ldarg.1 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl index 97f43391f53..8d49ce9610c 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.net472.bsl @@ -68,8 +68,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static valuetype TestModule/MyStructOption`1 - get_MyStructNone() cil managed + .method public static valuetype TestModule/MyStructOption`1 get_MyStructNone() cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -80,8 +79,7 @@ IL_0006: ret } - .method public hidebysig instance bool - get_IsMyStructNone() cil managed + .method public hidebysig instance bool get_IsMyStructNone() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -130,8 +128,7 @@ IL_0031: ret } - .method public hidebysig instance bool - get_IsMyStructSome() cil managed + .method public hidebysig instance bool get_IsMyStructSome() cil managed { .custom instance void System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, string[]) = ( 01 00 01 04 00 00 00 0D 6E 6F 74 4E 75 6C 6C 46 @@ -150,8 +147,7 @@ IL_0009: ret } - .method assembly specialname rtspecialname - instance void .ctor(int32 _tag) cil managed + .method assembly specialname rtspecialname instance void .ctor(int32 _tag) cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 1B 54 65 73 74 4D 6F 64 75 6C @@ -167,8 +163,7 @@ IL_0007: ret } - .method public hidebysig instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> - get_nestedGenericField() cil managed + .method public hidebysig instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> get_nestedGenericField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -181,8 +176,7 @@ IL_0006: ret } - .method public hidebysig instance string - get_notNullField2() cil managed + .method public hidebysig instance string get_notNullField2() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -195,8 +189,7 @@ IL_0006: ret } - .method public hidebysig instance string - get_canBeNullField() cil managed + .method public hidebysig instance string get_canBeNullField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -209,8 +202,7 @@ IL_0006: ret } - .method public hidebysig instance !T - get_notNullField1() cil managed + .method public hidebysig instance !T get_notNullField1() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -223,8 +215,7 @@ IL_0006: ret } - .method public hidebysig instance int32 - get_Tag() cil managed + .method public hidebysig instance int32 get_Tag() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -235,8 +226,7 @@ IL_0006: ret } - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -251,8 +241,7 @@ IL_001a: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -354,9 +343,9 @@ .param type b .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) .param [0] - .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) .param [2] - .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) .maxstack 7 .locals init (valuetype TestModule/MyStructOption`1 V_0, @@ -462,8 +451,7 @@ IL_0014: ret } - .method public hidebysig specialname instance class [runtime]System.Type - get_Type() cil managed + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -474,8 +462,7 @@ IL_0006: ret } - .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes - get_MemberType() cil managed + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -531,8 +518,7 @@ IL_0014: ret } - .method public hidebysig specialname instance string[] - get_Members() cil managed + .method public hidebysig specialname instance string[] get_Members() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -543,8 +529,7 @@ IL_0006: ret } - .method public hidebysig specialname instance bool - get_ReturnValue() cil managed + .method public hidebysig specialname instance bool get_ReturnValue() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -576,8 +561,7 @@ .field public uint8[] NullableFlags .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 scalarByteValue) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -596,8 +580,7 @@ IL_0016: ret } - .method public specialname rtspecialname - instance void .ctor(uint8[] NullableFlags) cil managed + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -620,8 +603,7 @@ .field public uint8 Flag .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 Flag) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl index 74b8ce8a49f..43a350944d8 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/GenericStructDu.fs.il.netcore.bsl @@ -68,8 +68,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public static valuetype TestModule/MyStructOption`1 - get_MyStructNone() cil managed + .method public static valuetype TestModule/MyStructOption`1 get_MyStructNone() cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -80,8 +79,7 @@ IL_0006: ret } - .method public hidebysig instance bool - get_IsMyStructNone() cil managed + .method public hidebysig instance bool get_IsMyStructNone() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -130,8 +128,7 @@ IL_0031: ret } - .method public hidebysig instance bool - get_IsMyStructSome() cil managed + .method public hidebysig instance bool get_IsMyStructSome() cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute::.ctor(bool, string[]) = ( 01 00 01 04 00 00 00 0D 6E 6F 74 4E 75 6C 6C 46 @@ -150,8 +147,7 @@ IL_0009: ret } - .method assembly specialname rtspecialname - instance void .ctor(int32 _tag) cil managed + .method assembly specialname rtspecialname instance void .ctor(int32 _tag) cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 1B 54 65 73 74 4D 6F 64 75 6C @@ -167,8 +163,7 @@ IL_0007: ret } - .method public hidebysig instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> - get_nestedGenericField() cil managed + .method public hidebysig instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1> get_nestedGenericField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -181,8 +176,7 @@ IL_0006: ret } - .method public hidebysig instance string - get_notNullField2() cil managed + .method public hidebysig instance string get_notNullField2() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -195,8 +189,7 @@ IL_0006: ret } - .method public hidebysig instance string - get_canBeNullField() cil managed + .method public hidebysig instance string get_canBeNullField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -209,8 +202,7 @@ IL_0006: ret } - .method public hidebysig instance !T - get_notNullField1() cil managed + .method public hidebysig instance !T get_notNullField1() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -223,8 +215,7 @@ IL_0006: ret } - .method public hidebysig instance int32 - get_Tag() cil managed + .method public hidebysig instance int32 get_Tag() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -235,8 +226,7 @@ IL_0006: ret } - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -251,8 +241,7 @@ IL_001a: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -354,9 +343,9 @@ .param type b .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) .param [0] - .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) .param [2] - .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 02 00 00 00 00 01 00 00 ) .maxstack 7 .locals init (valuetype TestModule/MyStructOption`1 V_0, diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl index e092d8fd8ea..f4977bfcd8d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.net472.bsl @@ -53,8 +53,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname - instance void .ctor() cil managed + .method assembly specialname rtspecialname instance void .ctor() cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 E0 07 00 00 1D 54 65 73 74 4D 6F 64 75 6C @@ -69,8 +68,7 @@ IL_0006: ret } - .method public static class TestModule/MyNullableOption`1 - get_MyNone() cil managed + .method public static class TestModule/MyNullableOption`1 get_MyNone() cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -82,8 +80,7 @@ IL_0001: ret } - .method public static class TestModule/MyNullableOption`1 - NewMySome(!T _value) cil managed + .method public static class TestModule/MyNullableOption`1 NewMySome(!T _value) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) @@ -94,8 +91,7 @@ IL_0006: ret } - .method assembly specialname rtspecialname - instance void .ctor(!T _value) cil managed + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 1D 54 65 73 74 4D 6F 64 75 6C @@ -113,8 +109,7 @@ IL_000d: ret } - .method public hidebysig instance !T - get_value() cil managed + .method public hidebysig instance !T get_value() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -141,8 +136,7 @@ IL_0007: ret } - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -156,8 +150,7 @@ IL_0015: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -170,8 +163,7 @@ IL_0015: ret } - .method public specialname static bool - get_IsMyNone(class TestModule/MyNullableOption`1 A_0) cil managed + .method public specialname static bool get_IsMyNone(class TestModule/MyNullableOption`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -182,8 +174,7 @@ IL_0004: ret } - .method public specialname static bool - get_IsMySome(class TestModule/MyNullableOption`1 A_0) cil managed + .method public specialname static bool get_IsMySome(class TestModule/MyNullableOption`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -254,8 +245,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname - instance void .ctor() cil managed + .method assembly specialname rtspecialname instance void .ctor() cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 E0 07 00 00 33 54 65 73 74 4D 6F 64 75 6C @@ -271,8 +261,7 @@ IL_0006: ret } - .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 - get_MyNotNullNone() cil managed + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 get_MyNotNullNone() cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -284,8 +273,7 @@ IL_0001: ret } - .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 - NewMyNotNullSome(!T _value) cil managed + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 NewMyNotNullSome(!T _value) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) @@ -296,8 +284,7 @@ IL_0006: ret } - .method assembly specialname rtspecialname - instance void .ctor(!T _value) cil managed + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 33 54 65 73 74 4D 6F 64 75 6C @@ -316,8 +303,7 @@ IL_000d: ret } - .method public hidebysig instance !T - get_value() cil managed + .method public hidebysig instance !T get_value() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -344,8 +330,7 @@ IL_0007: ret } - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -359,8 +344,7 @@ IL_0015: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -373,8 +357,7 @@ IL_0015: ret } - .method public specialname static bool - get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + .method public specialname static bool get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -385,8 +368,7 @@ IL_0004: ret } - .method public specialname static bool - get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + .method public specialname static bool get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -564,8 +546,7 @@ IL_0014: ret } - .method public hidebysig specialname instance class [runtime]System.Type - get_Type() cil managed + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -576,8 +557,7 @@ IL_0006: ret } - .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes - get_MemberType() cil managed + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -611,8 +591,7 @@ .field public uint8[] NullableFlags .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 scalarByteValue) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -631,8 +610,7 @@ IL_0016: ret } - .method public specialname rtspecialname - instance void .ctor(uint8[] NullableFlags) cil managed + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -655,8 +633,7 @@ .field public uint8 Flag .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 Flag) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl index d48f01435d7..057fa515964 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullAsTrueValue.fs.il.netcore.bsl @@ -53,8 +53,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname - instance void .ctor() cil managed + .method assembly specialname rtspecialname instance void .ctor() cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 E0 07 00 00 1D 54 65 73 74 4D 6F 64 75 6C @@ -69,8 +68,7 @@ IL_0006: ret } - .method public static class TestModule/MyNullableOption`1 - get_MyNone() cil managed + .method public static class TestModule/MyNullableOption`1 get_MyNone() cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -82,8 +80,7 @@ IL_0001: ret } - .method public static class TestModule/MyNullableOption`1 - NewMySome(!T _value) cil managed + .method public static class TestModule/MyNullableOption`1 NewMySome(!T _value) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) @@ -94,8 +91,7 @@ IL_0006: ret } - .method assembly specialname rtspecialname - instance void .ctor(!T _value) cil managed + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 1D 54 65 73 74 4D 6F 64 75 6C @@ -113,8 +109,7 @@ IL_000d: ret } - .method public hidebysig instance !T - get_value() cil managed + .method public hidebysig instance !T get_value() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -141,8 +136,7 @@ IL_0007: ret } - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -156,8 +150,7 @@ IL_0015: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -170,8 +163,7 @@ IL_0015: ret } - .method public specialname static bool - get_IsMyNone(class TestModule/MyNullableOption`1 A_0) cil managed + .method public specialname static bool get_IsMyNone(class TestModule/MyNullableOption`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -182,8 +174,7 @@ IL_0004: ret } - .method public specialname static bool - get_IsMySome(class TestModule/MyNullableOption`1 A_0) cil managed + .method public specialname static bool get_IsMySome(class TestModule/MyNullableOption`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -254,8 +245,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly specialname rtspecialname - instance void .ctor() cil managed + .method assembly specialname rtspecialname instance void .ctor() cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 E0 07 00 00 33 54 65 73 74 4D 6F 64 75 6C @@ -271,8 +261,7 @@ IL_0006: ret } - .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 - get_MyNotNullNone() cil managed + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 get_MyNotNullNone() cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -284,8 +273,7 @@ IL_0001: ret } - .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 - NewMyNotNullSome(!T _value) cil managed + .method public static class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 NewMyNotNullSome(!T _value) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 01 00 00 00 00 00 ) @@ -296,8 +284,7 @@ IL_0006: ret } - .method assembly specialname rtspecialname - instance void .ctor(!T _value) cil managed + .method assembly specialname rtspecialname instance void .ctor(!T _value) cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 33 54 65 73 74 4D 6F 64 75 6C @@ -316,8 +303,7 @@ IL_000d: ret } - .method public hidebysig instance !T - get_value() cil managed + .method public hidebysig instance !T get_value() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -344,8 +330,7 @@ IL_0007: ret } - .method assembly hidebysig specialname - instance object __DebugDisplay() cil managed + .method assembly hidebysig specialname instance object __DebugDisplay() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -359,8 +344,7 @@ IL_0015: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -373,8 +357,7 @@ IL_0015: ret } - .method public specialname static bool - get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + .method public specialname static bool get_IsMyNotNullNone(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -385,8 +368,7 @@ IL_0004: ret } - .method public specialname static bool - get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed + .method public specialname static bool get_IsMyNotNullSome(class TestModule/MyOptionWhichCannotHaveNullInTheInside`1 A_0) cil managed { .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs index 46672e0208c..061c6dba9d7 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs @@ -84,6 +84,12 @@ let ``Custom pipe`` compilation = compilation |> verifyCompilation DoNotOptimize +[] +let ``SupportsNull`` compilation = + compilation + |> withNoWarn 52 + |> verifyCompilation DoNotOptimize + module Interop = open System.IO diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl index 01a99cf449b..14108f77f92 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.net472.bsl @@ -62,8 +62,7 @@ .field assembly !Z GenericNotNullField@ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .method public hidebysig specialname - instance int32 get_JustInt() cil managed + .method public hidebysig specialname instance int32 get_JustInt() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -87,8 +86,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance string get_JustString() cil managed + .method public hidebysig specialname instance string get_JustString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -99,8 +97,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance string get_NullableString() cil managed + .method public hidebysig specialname instance string get_NullableString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -111,8 +108,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance !X get_GenericNormalField() cil managed + .method public hidebysig specialname instance !X get_GenericNormalField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -123,8 +119,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance !Y get_GenericNullableField() cil managed + .method public hidebysig specialname instance !Y get_GenericNullableField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -135,8 +130,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance !Z get_GenericNotNullField() cil managed + .method public hidebysig specialname instance !Z get_GenericNotNullField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -187,8 +181,7 @@ IL_003b: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -246,8 +239,7 @@ } } - .method public specialname static string - get_maybeString() cil managed + .method public specialname static string get_maybeString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -257,8 +249,7 @@ IL_0001: ret } - .method public static class MyTestModule/MyRecord`3 - createAnInstance() cil managed + .method public static class MyTestModule/MyRecord`3 createAnInstance() cil managed { .param [0] .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) @@ -348,8 +339,7 @@ IL_0014: ret } - .method public hidebysig specialname instance class [runtime]System.Type - get_Type() cil managed + .method public hidebysig specialname instance class [runtime]System.Type get_Type() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -360,8 +350,7 @@ IL_0006: ret } - .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes - get_MemberType() cil managed + .method public hidebysig specialname instance valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes get_MemberType() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -395,8 +384,7 @@ .field public uint8[] NullableFlags .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 scalarByteValue) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -415,8 +403,7 @@ IL_0016: ret } - .method public specialname rtspecialname - instance void .ctor(uint8[] NullableFlags) cil managed + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -439,8 +426,7 @@ .field public uint8 Flag .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(uint8 Flag) cil managed + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl index 8858ce8beac..46f7f58bdc6 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/Records.fs.il.netcore.bsl @@ -62,8 +62,7 @@ .field assembly !Z GenericNotNullField@ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) - .method public hidebysig specialname - instance int32 get_JustInt() cil managed + .method public hidebysig specialname instance int32 get_JustInt() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -87,8 +86,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance string get_JustString() cil managed + .method public hidebysig specialname instance string get_JustString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -99,8 +97,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance string get_NullableString() cil managed + .method public hidebysig specialname instance string get_NullableString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -111,8 +108,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance !X get_GenericNormalField() cil managed + .method public hidebysig specialname instance !X get_GenericNormalField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -123,8 +119,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance !Y get_GenericNullableField() cil managed + .method public hidebysig specialname instance !Y get_GenericNullableField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -135,8 +130,7 @@ IL_0006: ret } - .method public hidebysig specialname - instance !Z get_GenericNotNullField() cil managed + .method public hidebysig specialname instance !Z get_GenericNotNullField() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -187,8 +181,7 @@ IL_003b: ret } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -246,8 +239,7 @@ } } - .method public specialname static string - get_maybeString() cil managed + .method public specialname static string get_maybeString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -257,8 +249,7 @@ IL_0001: ret } - .method public static class MyTestModule/MyRecord`3 - createAnInstance() cil managed + .method public static class MyTestModule/MyRecord`3 createAnInstance() cil managed { .param [0] .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8[]) = ( 01 00 03 00 00 00 01 02 01 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs new file mode 100644 index 00000000000..ca7cc4d98bc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs @@ -0,0 +1,43 @@ +module MyTestModule + +let iCanProduceNullSometimes (arg:'a) : 'a = + let mutable cache = null + + if (System.DateTime.Now.Hour = 7) then + cache <- arg + + if (System.DateTime.Now.Hour = 7) then + null + else + arg + +let iPatternMatchOnArg arg = + match arg with + | null -> "null" + | _ -> "not null" + +let iAcceptNullPartiallyInferedFromUnderscore(arg: _ | null) = 0 + +let iAcceptNullPartiallyInferedFromNamedTypar(arg: 'a | null) = 0 + +let iAcceptNullWithNullAnnotation(arg: 'a | null when 'a: not struct) = + if isNull arg then + 1 + else + 0 + +let iAcceptNullExplicitAnnotation(arg: 'T when 'T:null) = + if isNull arg then + 1 + else + 0 + + +let fullyInferedTestCase arg1 arg2 = + System.Console.Write(iAcceptNullPartiallyInferedFromUnderscore arg1) + let maybeNull = iCanProduceNullSometimes arg2 + maybeNull + +let structShouldBeAllowedHere arg = + let boxed : obj | null = box arg + iAcceptNullPartiallyInferedFromUnderscore boxed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl new file mode 100644 index 00000000000..74d4cc4fc1e --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.net472.bsl @@ -0,0 +1,276 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static !!a iCanProduceNullSometimes(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (!!a V_0, + valuetype [runtime]System.DateTime V_1, + valuetype [runtime]System.DateTime V_2, + !!a V_3) + IL_0000: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0005: stloc.1 + IL_0006: ldloca.s V_1 + IL_0008: call instance int32 [runtime]System.DateTime::get_Hour() + IL_000d: ldc.i4.7 + IL_000e: bne.un.s IL_0014 + + IL_0010: ldarg.0 + IL_0011: stloc.0 + IL_0012: br.s IL_0014 + + IL_0014: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0019: stloc.2 + IL_001a: ldloca.s V_2 + IL_001c: call instance int32 [runtime]System.DateTime::get_Hour() + IL_0021: ldc.i4.7 + IL_0022: bne.un.s IL_0026 + + IL_0024: ldloc.3 + IL_0025: ret + + IL_0026: ldarg.0 + IL_0027: ret + } + + .method public static string iPatternMatchOnArg(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: brfalse.s IL_000a + + IL_0008: br.s IL_0010 + + IL_000a: ldstr "null" + IL_000f: ret + + IL_0010: ldstr "not null" + IL_0015: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromUnderscore(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromNamedTypar(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullWithNullAnnotation(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!a V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!a + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static int32 iAcceptNullExplicitAnnotation(!!T arg) cil managed + { + .param type T + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!T V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!T + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static !!b fullyInferedTestCase(!!a arg1, + !!b arg2) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!b V_0) + IL_0000: ldarg.0 + IL_0001: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_0006: call void [runtime]System.Console::Write(int32) + IL_000b: ldarg.1 + IL_000c: call !!0 MyTestModule::iCanProduceNullSometimes(!!0) + IL_0011: stloc.0 + IL_0012: ldloc.0 + IL_0013: ret + } + + .method public static int32 structShouldBeAllowedHere(!!a arg) cil managed + { + .param type a + .custom instance void System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 3 + .locals init (object V_0) + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_000d: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8[] NullableFlags + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 scalarByteValue) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldc.i4.1 + IL_0008: newarr [runtime]System.Byte + IL_000d: dup + IL_000e: ldc.i4.0 + IL_000f: ldarg.1 + IL_0010: stelem.i1 + IL_0011: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_0016: ret + } + + .method public specialname rtspecialname instance void .ctor(uint8[] NullableFlags) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8[] System.Runtime.CompilerServices.NullableAttribute::NullableFlags + IL_000d: ret + } + +} + +.class private auto ansi beforefieldinit System.Runtime.CompilerServices.NullableContextAttribute + extends [runtime]System.Attribute +{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public uint8 Flag + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method public specialname rtspecialname instance void .ctor(uint8 Flag) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [runtime]System.Attribute::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld uint8 System.Runtime.CompilerServices.NullableContextAttribute::Flag + IL_000d: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl new file mode 100644 index 00000000000..8c5236b881b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/SupportsNull.fs.il.netcore.bsl @@ -0,0 +1,212 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern runtime { } +.assembly assembly +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.dll + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed MyTestModule + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .custom instance void [runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .method public static !!a iCanProduceNullSometimes(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 4 + .locals init (!!a V_0, + valuetype [runtime]System.DateTime V_1, + valuetype [runtime]System.DateTime V_2, + !!a V_3) + IL_0000: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0005: stloc.1 + IL_0006: ldloca.s V_1 + IL_0008: call instance int32 [runtime]System.DateTime::get_Hour() + IL_000d: ldc.i4.7 + IL_000e: bne.un.s IL_0014 + + IL_0010: ldarg.0 + IL_0011: stloc.0 + IL_0012: br.s IL_0014 + + IL_0014: call valuetype [runtime]System.DateTime [runtime]System.DateTime::get_Now() + IL_0019: stloc.2 + IL_001a: ldloca.s V_2 + IL_001c: call instance int32 [runtime]System.DateTime::get_Hour() + IL_0021: ldc.i4.7 + IL_0022: bne.un.s IL_0026 + + IL_0024: ldloc.3 + IL_0025: ret + + IL_0026: ldarg.0 + IL_0027: ret + } + + .method public static string iPatternMatchOnArg(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: brfalse.s IL_000a + + IL_0008: br.s IL_0010 + + IL_000a: ldstr "null" + IL_000f: ret + + IL_0010: ldstr "not null" + IL_0015: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromUnderscore(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullPartiallyInferedFromNamedTypar(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public static int32 iAcceptNullWithNullAnnotation(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!a V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!a + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static int32 iAcceptNullExplicitAnnotation(!!T arg) cil managed + { + .param type T + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!T V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: box !!T + IL_0008: brtrue.s IL_000d + + IL_000a: ldc.i4.1 + IL_000b: br.s IL_000e + + IL_000d: ldc.i4.0 + IL_000e: brfalse.s IL_0012 + + IL_0010: ldc.i4.1 + IL_0011: ret + + IL_0012: ldc.i4.0 + IL_0013: ret + } + + .method public static !!b fullyInferedTestCase(!!a arg1, + !!b arg2) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 01 00 00 ) + .param type b + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + .param [1] + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 02 00 00 ) + + .maxstack 3 + .locals init (!!b V_0) + IL_0000: ldarg.0 + IL_0001: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_0006: call void [runtime]System.Console::Write(int32) + IL_000b: ldarg.1 + IL_000c: call !!0 MyTestModule::iCanProduceNullSometimes(!!0) + IL_0011: stloc.0 + IL_0012: ldloc.0 + IL_0013: ret + } + + .method public static int32 structShouldBeAllowedHere(!!a arg) cil managed + { + .param type a + .custom instance void [runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = ( 01 00 00 00 00 ) + + .maxstack 3 + .locals init (object V_0) + IL_0000: ldarg.0 + IL_0001: box !!a + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call int32 MyTestModule::iAcceptNullPartiallyInferedFromUnderscore(!!0) + IL_000d: ret + } + +} + +.class private abstract auto ansi sealed ''.$MyTestModule + extends [runtime]System.Object +{ +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs index 7c138db4e47..b7118fbe61e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/NullableCsharpImportTests.fs @@ -12,6 +12,7 @@ let typeCheckWithStrictNullness cu = |> withOptions ["--warnaserror+"] |> compile + [] let ``Passing null to IlGenerator BeginCatchBlock is fine`` () = FSharp """module MyLibrary @@ -34,6 +35,42 @@ let doSomethingAboutIt (ilg:ILGenerator) = |> typeCheckWithStrictNullness |> shouldSucceed +[] +let ``Consuming C# generic API which allows struct and yet uses question mark on the typar`` () = + FSharp """module MyLibrary +let ec = + { new System.Collections.Generic.IEqualityComparer with + member this.Equals(x, y) = (x+0) = (y+0) + member this.GetHashCode(obj) = obj * 2} +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``TypeBuilder CreateTypeInfo with an upcast`` () = + FSharp """module MyLibrary +open System +open System.Reflection.Emit + +let createType (typB:TypeBuilder) : Type= + typB.CreateTypeInfo() :> Type +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``CurrentDomain ProcessExit add to event`` () = + FSharp """module MyLibrary +open System + +do System.AppDomain.CurrentDomain.ProcessExit |> Event.add (fun args -> failwith $"{args.GetHashCode()}") +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + [] let ``Consuming C# extension methods which allow nullable this`` () = FSharp """module MyLibrary diff --git a/tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs index f546c8e8d59..2a7e5a74d87 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/NullableReferenceTypesTests.fs @@ -3,15 +3,18 @@ module Language.NullableReferenceTypes open Xunit open FSharp.Test.Compiler -let typeCheckWithStrictNullness cu = +let withNullnessOptions cu = cu |> withLangVersionPreview |> withCheckNulls |> withWarnOn 3261 |> withWarnOn 3262 |> withOptions ["--warnaserror+"] - |> compile +let typeCheckWithStrictNullness cu = + cu + |> withNullnessOptions + |> compile [] let ``Cannot pass possibly null value to a strict function``() = @@ -26,6 +29,167 @@ let nonStrictFunc(x:string | null) = strictFunc(x) |> withDiagnostics [ Error 3261, Line 4, Col 49, Line 4, Col 50, "Nullness warning: The types 'string' and 'string | null' do not have equivalent nullability."] + +// P1: inline or not +// P2: type annotation for function argument +// P3: type annotation for cache +let MutableBindingAnnotationCombinations = + [| + for functionInlineFlag in ["" + "inline"] do + for xArg in ["" + ":'T" + ":'T|null" + ": _" + ": _|null" + ": string|null" + ": string"] do + // No annotation or _ must work all the time + for cacheArg in ["" + ": _"] do + yield [|functionInlineFlag :> obj; xArg :> obj; cacheArg :> obj|] + + // If we have a named type, the same one must work for cache binding as well + if xArg.Contains("'T") || xArg.Contains("string|null") then + yield [|functionInlineFlag :> obj; xArg :> obj; xArg :> obj|] + + // If we have a type WithNull, using _|null should infer the exact same type + if xArg.Contains("|null") || xArg.Contains("string") then + yield [|functionInlineFlag :> obj; xArg :> obj; ":_|null" :> obj|] + + if xArg = ":'T" then + for guard in [" when 'T:null" + " when 'T:null and 'T:not struct"] do + yield [|functionInlineFlag :> obj; (xArg + guard) :> obj; "" :> obj|] + + if xArg = ":'T|null" then + for guard in [" when 'T:not struct" + " when 'T:not null" + " when 'T:not struct and 'T:not null"] do + yield [|functionInlineFlag :> obj; (xArg + guard) :> obj; "" :> obj|] + |] + +[] +[] +let ``Mutable binding with a null literal`` inln xArg cache = + FSharp $"""module MyLib + +let %s{inln} f (x %s{xArg}) = + let mutable cache %s{cache} = null + cache <- x + + match cache with + | null -> failwith "It was null" + | c -> c + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Mutable string binding initially assigned to null should not need type annotation``() = + FSharp """ +module MyLib + + +let name = "abc" +let mutable cache = null +cache <- name + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Mutable string binding assigned to null and matched againts null``() = + FSharp """ +module MyLib + +let whatEver() = + let mutable x = null + x <- "abc" + x + + +(* This is a comment +let name = "abc" +let mutable cache = null +cache <- name + +match cache with +| null -> () +| c -> ()*) + + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Mutable cache binding initially assigned to null should not need type annotation``() = + FSharp """ +module MyLib +open System.Collections.Concurrent +open System + +let mkCacheInt32 () = + let mutable topLevelCache = null + + fun f (idx: int32) -> + let cache = + match topLevelCache with + | null -> + let v = ConcurrentDictionary(Environment.ProcessorCount, 11) + topLevelCache <- v + v + | v -> v + + match cache.TryGetValue idx with + | true, res -> res + | _ -> + let res = f idx + cache[idx] <- res + res + + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Can infer underscore or null``() = + FSharp """ +module MyLib +let iAcceptNullPartiallyInfered(arg: _ | null) = 42 +let iHaveMissingContraint(arg: 'a | null) = 42 + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed + +[] +let ``Invalid usages of WithNull syntax``() = + FSharp """ +module MyLib +let f1(x: option | null) = () +let f2(x: int | null) = () +let f3(x: ('a*'b) | null) = () +let f4(x: option<'a> | null) = () +let f5(x: ('a | null) when 'a:struct) = () +let f6(x: 'a | null when 'a:null) = () + """ + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3261, Line 3, Col 11, Line 3, Col 32, "Nullness warning: The type 'string option' uses 'null' as a representation value but a non-null type is expected." + Error 3260, Line 4, Col 11, Line 4, Col 21, "The type 'int' does not support a nullness qualitification." + Error 43, Line 4, Col 11, Line 4, Col 21, "A generic construct requires that the type 'int' have reference semantics, but it does not, i.e. it is a struct" + Error 3260, Line 5, Col 11, Line 5, Col 25, "The type '('a * 'b)' does not support a nullness qualitification." + Error 3261, Line 6, Col 11, Line 6, Col 28, "Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected." + Error 43, Line 7, Col 28, Line 7, Col 37, "The constraints 'struct' and 'not struct' are inconsistent" + Error 43, Line 8, Col 26, Line 8, Col 33, "The constraints 'null' and 'not null' are inconsistent"] + [] let ``Boolean literal to string is not nullable`` () = FSharp """module MyLibrary @@ -130,6 +294,18 @@ let doStuff() = |> typeCheckWithStrictNullness |> shouldSucceed +[] +let ``Match null on two strings`` () = + FSharp """module MyLibrary +let len2r (str1: string | null) (str2: string | null) = + match str1, str2 with + | null, _ -> -1 + | _, null -> -1 + | s1, s2 -> s1.Length + s2.Length +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldSucceed [] [] @@ -190,7 +366,7 @@ let myFunction (input1 : string | null) (input2 : string | null): (string*string let ``Eliminate aliased nullness after matching`` () = FSharp $"""module MyLibrary -type Maybe<'T> = 'T | null +type Maybe<'T when 'T:not struct> = 'T | null let myFunction (input : string Maybe) : string = match input with @@ -280,7 +456,7 @@ strictFunc(null) |> ignore """ |> typeCheckWithStrictNullness |> shouldFail |> withDiagnostics - [ Error 3261, Line 4, Col 12, Line 4, Col 16, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."] + [ Error 43, Line 4, Col 12, Line 4, Col 16, "The constraints 'null' and 'not null' are inconsistent"] [] let ``Strict func null literal2`` () = @@ -294,9 +470,74 @@ strictFunc("hi") |> ignore """ |> typeCheckWithStrictNullness |> shouldFail |> withDiagnostics - [ Error 3261, Line 4, Col 12, Line 4, Col 16, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."] - - + [ Error 43, Line 4, Col 12, Line 4, Col 16, "The constraints 'null' and 'not null' are inconsistent"] + +[] +let ``Supports null in generic code`` () = + FSharp """module MyLibrary +let myGenericFunction p = + match p with + | null -> () + | p -> printfn "%s" (p.ToString()) + +[] +type X(p:int) = + member _.P = p + +let myValOfX : X = null + +myGenericFunction "HiThere" +myGenericFunction ("HiThere":string | null) +myGenericFunction (System.DateTime.Now) +myGenericFunction 123 +myGenericFunction myValOfX + +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [Error 3261, Line 13, Col 19, Line 13, Col 28, "Nullness warning: The type 'string' does not support 'null'." + Error 3261, Line 15, Col 20, Line 15, Col 39, "Nullness warning: The type 'System.DateTime' does not support 'null'." + Error 3261, Line 16, Col 19, Line 16, Col 22, "Nullness warning: The type 'int' does not support 'null'."] + +[] +let ``Null assignment in generic code`` () = + FSharp """module MyLibrary +let myNullReturningFunction p = + let mutable x = p + x <- null + x + +[] +type X(p:int) = + member _.P = p + +type Y (p:int) = + member _.P = p + +let myValOfX : X = null +let myValOfY : Y = Unchecked.defaultof + +myNullReturningFunction "HiThere" |> ignore +myNullReturningFunction ("HiThere":string | null) |> ignore +myNullReturningFunction (System.DateTime.Now) |> ignore +myNullReturningFunction {|Anon=42|} |> ignore +myNullReturningFunction (1,2,3) |> ignore +myNullReturningFunction myValOfX |> ignore +myNullReturningFunction myValOfY |> ignore + +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [Error 3261, Line 17, Col 25, Line 17, Col 34, "Nullness warning: The type 'string' does not support 'null'." + Error 3261, Line 19, Col 26, Line 19, Col 45, "Nullness warning: The type 'System.DateTime' does not support 'null'." + Error 3261, Line 20, Col 25, Line 20, Col 36, "Nullness warning: The type '{| Anon: 'a |}' does not support 'null'." + Error 3261, Line 21, Col 26, Line 21, Col 31, "Nullness warning: The type '('a * 'b * 'c)' does not support 'null'." + Error 3261, Line 23, Col 25, Line 23, Col 33, "Nullness warning: The type 'Y' does not support 'null'."] + [] let ``Nullnesss support for F# types`` () = FSharp """module MyLibrary @@ -346,7 +587,8 @@ looseFunc(maybeTuple2) |> ignore |> typeCheckWithStrictNullness |> shouldFail |> withDiagnostics - [ Error 3260, Line 27, Col 18, Line 27, Col 34, "The type '(int * int)' does not support a nullness qualitification." + [ Error 43, Line 21, Col 12, Line 21, Col 16, "The constraints 'null' and 'not null' are inconsistent" + Error 3260, Line 27, Col 18, Line 27, Col 34, "The type '(int * int)' does not support a nullness qualitification." Error 3261, Line 27, Col 37, Line 27, Col 41, "Nullness warning: The type '(int * int)' does not support 'null'." Error 3261, Line 29, Col 12, Line 29, Col 19, "Nullness warning: The type 'MyDu | null' supports 'null' but a non-null type is expected." Error 3261, Line 30, Col 12, Line 30, Col 21, "Nullness warning: The type 'MyRecord | null' supports 'null' but a non-null type is expected." @@ -536,4 +778,31 @@ let mappableFunc = """ |> asLibrary |> typeCheckWithStrictNullness - |> shouldSucceed \ No newline at end of file + |> shouldSucceed + +[] +let ``Notnull constraint and inline annotated value`` () = + FSharp """module MyLibrary +open System + +let f3 (x: 'T when 'T : not null) = 1 + +let v3 = f3 (null: obj) +let v4 = f3 (null: String | null) +let v5 = f3 (Some 1) + +let w3 = (null: obj) |> f3 +let w4 = (null: String | null) |> f3 + +let v3WithNull = f3 (null: obj | null) +""" + |> asLibrary + |> typeCheckWithStrictNullness + |> shouldFail + |> withDiagnostics + [ Error 3261, Line 6, Col 14, Line 6, Col 18, "Nullness warning: The type 'obj' does not support 'null'." + Error 3261, Line 7, Col 14, Line 7, Col 33, "Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected." + Error 3261, Line 8, Col 14, Line 8, Col 20, "Nullness warning: The type ''a option' uses 'null' as a representation value but a non-null type is expected." + Error 3261, Line 10, Col 11, Line 10, Col 15, "Nullness warning: The type 'obj' does not support 'null'." + Error 3261, Line 11, Col 35, Line 11, Col 37, "Nullness warning: The type 'String | null' supports 'null' but a non-null type is expected." + Error 3261, Line 13, Col 22, Line 13, Col 38, "Nullness warning: The type 'obj | null' supports 'null' but a non-null type is expected."] \ No newline at end of file diff --git a/tests/adhoc/nullness/enabled/positive.fs b/tests/adhoc/nullness/enabled/positive.fs index 3a7afebf6ef..66c3847d3b3 100644 --- a/tests/adhoc/nullness/enabled/positive.fs +++ b/tests/adhoc/nullness/enabled/positive.fs @@ -48,19 +48,19 @@ type C(s: String) = // This give a warning since 'T is not known to be reference type non-null -let f<'T when 'T: not null > (x: 'T | null, y: 'T | null) = () +let f<'T when 'T: not null and 'T: not struct > (x: 'T | null, y: 'T | null) = () module Extractions0c = let x = null - let f<'T when 'T : not null> (x: 'T | null, y: 'T | null) = () + let f<'T when 'T : not null and 'T: not struct> (x: 'T | null, y: 'T | null) = () let s : String = "" let result = f (x, s) // expect no warning in any configuration module Extractions0e = let x = null - let f<'T when 'T : not null> (x: 'T | null, y: 'T | null) = () + let f<'T when 'T : not null and 'T: not struct> (x: 'T | null, y: 'T | null) = () let result = f (x, "") // expect no warning in any configuration module Extractions1 = diff --git a/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl b/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl index 43b59356de0..d8125c7aee9 100644 --- a/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl +++ b/tests/adhoc/nullness/enabled/positive.next.enabled.checknulls.bsl @@ -1,8 +1,12 @@ +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. @@ -47,9 +51,9 @@ tests\adhoc\nullness\enabled\positive.fs(92,83): warning FS3261: Nullness warnin 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 types 'System.String (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)' and 'System.String (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)' do not have compatible nullability. +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 types 'System.String (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)' and 'System.String (mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)' do not have compatible nullability. +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'. @@ -57,4 +61,6 @@ tests\adhoc\nullness\enabled\positive.fs(162,41): warning FS3261: Nullness warni 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.enabled.checknulls.bsl b/tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl index 5244ca862a8..ab814c80f8a 100644 --- a/tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl +++ b/tests/adhoc/nullness/existing/negative.next.enabled.checknulls.bsl @@ -1,6 +1,8 @@ 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 diff --git a/tests/adhoc/nullness/existing/positive.fs b/tests/adhoc/nullness/existing/positive.fs index a87d5dff156..727a1a8b69d 100644 --- a/tests/adhoc/nullness/existing/positive.fs +++ b/tests/adhoc/nullness/existing/positive.fs @@ -6,19 +6,19 @@ open System.Runtime.CompilerServices module Extractions0a = let x = null - let result = (x = "") // expect no warning under any configuration + let result = (x = "") //The type 'string' does not support 'null'. module Extractions0b = let x = null let f (x: 'T, y: 'T) = () - let result = f (x, "") // expect no warning under any configuration + let result = f (x, "") //The type 'string' does not support 'null'. module Extractions0d = let x = null let f<'T when 'T : null> (x: 'T, y: 'T) = () - let result = f (x, "") // expect no warning under any configuration + let result = f (x, "") //The type 'string' does not support 'null'. module Basics = let x1 : String = null // expect a warning when checknulls is on @@ -46,7 +46,7 @@ System.Console.WriteLine("a", (null: obj[])) // expect a warning when checknulls let f0 line = let add (s:String) = () match line with - | null | "" -> () + | null | "" -> () //The type 'string' does not support 'null'. | _ -> add line module NullConstraintTests = diff --git a/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl b/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl index 2788d57d704..05053aaf03c 100644 --- a/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl +++ b/tests/adhoc/nullness/existing/positive.next.enabled.checknulls.bsl @@ -1,8 +1,16 @@ +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/out.fsi b/tests/adhoc/nullness/out.fsi index 9e577b20247..2ef8d77eb31 100644 --- a/tests/adhoc/nullness/out.fsi +++ b/tests/adhoc/nullness/out.fsi @@ -5,9 +5,9 @@ val internal fsProductVersion: string val internal fsLanguageVersion: string +namespace FSharp -namespace FSharp module ExistingPositive @@ -152,7 +152,7 @@ module Basics2 = val f2: unit -> System.String | null - val f3: unit -> 'T | null when 'T: not 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 @@ -166,13 +166,14 @@ type C = member Value: System.String -val f: x: 'T | null * y: 'T | null -> unit when 'T: not null +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 + val f: + x: 'T | null * y: 'T | null -> unit when 'T: not null and 'T: not struct val s: System.String @@ -182,7 +183,8 @@ module Extractions0e = val x: 'a when 'a: null - val f: x: 'T | null * y: 'T | null -> unit when 'T: not null + val f: + x: 'T | null * y: 'T | null -> unit when 'T: not null and 'T: not struct val result: unit diff --git a/tests/adhoc/nullness/validate.cmd b/tests/adhoc/nullness/validate.cmd index 9b9bd182f92..7aa5f84e88b 100644 --- a/tests/adhoc/nullness/validate.cmd +++ b/tests/adhoc/nullness/validate.cmd @@ -1,35 +1,35 @@ 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 -fsc.exe tests\adhoc\nullness\micro.fs -i -fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i +dotnet %fsiLocation% tests\adhoc\nullness\micro.fs -i +dotnet %fsiLocation% tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i -artifacts\bin\fsc\Proto\net472\fsc.exe tests\adhoc\nullness\micro.fs -i -artifacts\bin\fsc\Proto\net472\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 +artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i -artifacts\bin\fsc\Proto\net472\fsc.exe tests\adhoc\nullness\micro.fs -i --langversion:preview -artifacts\bin\fsc\Proto\net472\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 +artifacts\bin\fsc\Release\net8.0\fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i --langversion:preview -artifacts\bin\fsc\Proto\net472\fsc.exe tests\adhoc\nullness\micro.fs -i --langversion:preview --checknulls -artifacts\bin\fsc\Proto\net472\fsc.exe tests\adhoc\nullness\micro.fsi tests\adhoc\nullness\micro.fs -i --langversion:preview --checknulls +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 ------------- -fsc.exe 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\Proto\net472\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\Proto\net472\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\Proto\net472\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\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 -fsc.exe 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\Proto\net472\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\Proto\net472\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\Proto\net472\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 +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\Proto\net472\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\Proto\net472\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\Proto\net472\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 +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 -------------