diff --git a/.fantomasignore b/.fantomasignore index d1bea49f566..9c12ffa8e2c 100644 --- a/.fantomasignore +++ b/.fantomasignore @@ -42,6 +42,8 @@ src/Compiler/Checking/TypeRelations.fs # nullness-related problems src/Compiler/DependencyManager/DependencyProvider.fs +src/FSharp.Core/fslib-extra-pervasives.fs +src/FSharp.Core/fslib-extra-pervasives.fsi # Incorrectly formatted: https://github.com/dotnet/fsharp/pull/14645/commits/49443a67ea8a17670c8a7c80c8bdf91f82231e91 or https://github.com/fsprojects/fantomas/issues/2733 # This CompilerImports.fs behavior is not fixed yet, following up in https://github.com/fsprojects/fantomas/issues/2733 @@ -124,6 +126,9 @@ src/Compiler/SyntaxTree/LexerStore.fs src/Compiler/Driver/GraphChecking/Graph.fsi src/Compiler/Driver/GraphChecking/Graph.fs +src/Compiler/DependencyManager/NativeDllResolveHandler.fsi +src/Compiler/DependencyManager/AssemblyResolveHandler.fsi + # Fantomas limitations on implementation files (to investigate) src/Compiler/AbstractIL/ilwrite.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md index 368513722c9..f41b4ca9289 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md @@ -11,6 +11,7 @@ ### Added * Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241)) * The 'use' keyword can be used on IDisposable|null without nullness warnings ([PR #18262](https://github.com/dotnet/fsharp/pull/18262)) +* Nullness warnings are issued for signature<>implementation conformance ([PR #18186](https://github.com/dotnet/fsharp/pull/18186)) * Symbols: Add FSharpAssembly.IsFSharp ([PR #18290](https://github.com/dotnet/fsharp/pull/18290)) ### Changed diff --git a/src/Compiler/AbstractIL/ilreflect.fs b/src/Compiler/AbstractIL/ilreflect.fs index d88cc24d689..45c0652c59d 100644 --- a/src/Compiler/AbstractIL/ilreflect.fs +++ b/src/Compiler/AbstractIL/ilreflect.fs @@ -2548,7 +2548,7 @@ let EmitDynamicAssemblyFragment ignore (typB.InvokeMemberAndLog(methodName, BindingFlags.InvokeMethod ||| BindingFlags.Public ||| BindingFlags.Static, [||])) None with :? TargetInvocationException as exn -> - Some exn.InnerException + Option.ofObj exn.InnerException let emEnv, entryPts = envPopEntryPts emEnv let execs = List.map execEntryPtFun entryPts diff --git a/src/Compiler/Checking/AttributeChecking.fsi b/src/Compiler/Checking/AttributeChecking.fsi index 5885c1b39e9..143763f889c 100644 --- a/src/Compiler/Checking/AttributeChecking.fsi +++ b/src/Compiler/Checking/AttributeChecking.fsi @@ -24,8 +24,8 @@ type AttribInfo = | FSAttribInfo of TcGlobals * Attrib | ILAttribInfo of TcGlobals * Import.ImportMap * ILScopeRef * ILAttribute * range - member ConstructorArguments: (TType * obj) list - member NamedArguments: (TType * string * bool * obj) list + member ConstructorArguments: (TType * objnull) list + member NamedArguments: (TType * string * bool * objnull) list member Range: range member TyconRef: TyconRef diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index af3e712a8db..f6b405bf1d6 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3060,7 +3060,7 @@ module EstablishTypeDefinitionCores = if not isRootGenerated then let desig = theRootTypeWithRemapping.TypeProviderDesignation - let nm = theRootTypeWithRemapping.PUntaint((fun st -> st.FullName), m) + let nm = theRootTypeWithRemapping.PUntaint((fun st -> string st.FullName), m) error(Error(FSComp.SR.etErasedTypeUsedInGeneration(desig, nm), m)) cenv.createsGeneratedProvidedTypes <- true @@ -3101,7 +3101,7 @@ module EstablishTypeDefinitionCores = if not isGenerated then let desig = st.TypeProviderDesignation - let nm = st.PUntaint((fun st -> st.FullName), m) + let nm = st.PUntaint((fun st -> string st.FullName), m) error(Error(FSComp.SR.etErasedTypeUsedInGeneration(desig, nm), m)) // Embed the type into the module we're compiling @@ -4251,7 +4251,7 @@ module TcDeclarations = // For historical reasons we only give a warning for incorrect type parameters on intrinsic extensions if nReqTypars <> synTypars.Length then errorR(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) - if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then + if not (typarsAEquiv g (TypeEquivEnv.EmptyWithNullChecks g) reqTypars declaredTypars) then warning(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) // Note we return 'reqTypars' for intrinsic extensions since we may only have given warnings IntrinsicExtensionBinding, reqTypars @@ -4260,7 +4260,7 @@ module TcDeclarations = errorR(Error(FSComp.SR.tcMembersThatExtendInterfaceMustBePlacedInSeparateModule(), tcref.Range)) if nReqTypars <> synTypars.Length then error(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) - if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then + if not (typarsAEquiv g (TypeEquivEnv.EmptyWithNullChecks g) reqTypars declaredTypars) then errorR(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m)) ExtrinsicExtensionBinding, declaredTypars @@ -5702,7 +5702,7 @@ let CheckModuleSignature g (cenv: cenv) m denvAtEnd rootSigOpt implFileTypePrior |] // We want to show imperative type variables in any types in error messages at this late point - let denv = { denvAtEnd with showInferenceTyparAnnotations=true } + let denv = { denvAtEnd with showInferenceTyparAnnotations=true;showNullnessAnnotations=Some g.checkNullness } try // As typechecked the signature and implementation use different tycons etc. @@ -5714,7 +5714,7 @@ let CheckModuleSignature g (cenv: cenv) m denvAtEnd rootSigOpt implFileTypePrior // Compute the remapping from implementation to signature let remapInfo, _ = ComputeRemappingFromInferredSignatureToExplicitSignature g implFileTypePriorToSig sigFileType - let aenv = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } + let aenv = { TypeEquivEnv.EmptyWithNullChecks g with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } if not (SignatureConformance.Checker(g, cenv.amap, denv, remapInfo, true).CheckSignature aenv cenv.infoReader (mkLocalModuleRef implFileSpecPriorToSig) sigFileType) then // We can just raise 'ReportedError' since CheckModuleOrNamespace raises its own error diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 902bf331d85..50026fe382a 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -345,7 +345,7 @@ let MakeConstraintSolverEnv contextInfo css m denv = eContextInfo = contextInfo MatchingOnly = false ErrorOnFailedMemberConstraintResolution = false - EquivEnv = TypeEquivEnv.Empty + EquivEnv = TypeEquivEnv.EmptyIgnoreNulls DisplayEnv = denv IsSpeculativeForMethodOverloading = false IsSupportsNullFlex = false diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index f33c7239063..d34d9cf2978 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -12687,7 +12687,7 @@ and FixupLetrecBind (cenv: cenv) denv generalizedTyparsForRecursiveBlock (bind: | Some _ -> match PartitionValTyparsForApparentEnclosingType g vspec with | Some(parentTypars, memberParentTypars, _, _, _) -> - ignore(SignatureConformance.Checker(g, cenv.amap, denv, SignatureRepackageInfo.Empty, false).CheckTypars vspec.Range TypeEquivEnv.Empty memberParentTypars parentTypars) + ignore(SignatureConformance.Checker(g, cenv.amap, denv, SignatureRepackageInfo.Empty, false).CheckTypars vspec.Range TypeEquivEnv.EmptyIgnoreNulls memberParentTypars parentTypars) | None -> errorR(Error(FSComp.SR.tcMemberIsNotSufficientlyGeneric(), vspec.Range)) | _ -> () diff --git a/src/Compiler/Checking/InfoReader.fs b/src/Compiler/Checking/InfoReader.fs index 77fb623efb0..b8a0efd14af 100644 --- a/src/Compiler/Checking/InfoReader.fs +++ b/src/Compiler/Checking/InfoReader.fs @@ -63,7 +63,8 @@ let rec GetImmediateIntrinsicMethInfosOfTypeAux (optFilter, ad) g amap m withExp let st = info.ProvidedType let meths = match optFilter with - | Some name -> st.PApplyArray ((fun st -> st.GetMethods() |> Array.filter (fun mi -> mi.Name = name) ), "GetMethods", m) + | Some name -> + st.PApplyFilteredArray ((fun st -> st.GetMethods()),(fun mi -> mi.Name = name), "GetMethods", m) | None -> st.PApplyArray ((fun st -> st.GetMethods()), "GetMethods", m) [ for mi in meths -> ProvidedMeth(amap, mi.Coerce(m), None, m) ] #endif diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 4c561dd7fee..41d731f007e 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -1120,7 +1120,7 @@ let TryImportProvidedMethodBaseAsLibraryIntrinsic (amap: Import.ImportMap, m: ra match tryTcrefOfAppTy amap.g declaringType with | ValueSome declaringEntity -> if not declaringEntity.IsLocalRef && ccuEq declaringEntity.nlr.Ccu amap.g.fslibCcu then - let n = mbase.PUntaint((fun x -> x.GetParameters().Length), m) + let n = mbase.PApplyArray((fun x -> x.GetParameters()),"GetParameters", m).Length match amap.g.knownIntrinsics.TryGetValue ((declaringEntity.LogicalName, None, methodName, n)) with | true, vref -> Some vref | _ -> @@ -1815,14 +1815,14 @@ module ProvidedMethodCalls = let rec loop (st: Tainted) = if st.PUntaint((fun st -> st.IsGenericParameter), m) then st elif st.PUntaint((fun st -> st.IsArray), m) then - let et = st.PApply((fun st -> st.GetElementType()), m) + let et = st.PApply((fun st -> !! st.GetElementType()), m) let rank = st.PUntaint((fun st -> st.GetArrayRank()), m) (loop et).PApply((fun st -> if rank = 1 then st.MakeArrayType() else st.MakeArrayType(rank)), m) elif st.PUntaint((fun st -> st.IsByRef), m) then - let et = st.PApply((fun st -> st.GetElementType()), m) + let et = st.PApply((fun st -> !! st.GetElementType()), m) (loop et).PApply((fun st -> st.MakeByRefType()), m) elif st.PUntaint((fun st -> st.IsPointer), m) then - let et = st.PApply((fun st -> st.GetElementType()), m) + let et = st.PApply((fun st -> !! st.GetElementType()), m) (loop et).PApply((fun st -> st.MakePointerType()), m) else let isGeneric = st.PUntaint((fun st -> st.IsGenericType), m) @@ -1863,7 +1863,7 @@ module ProvidedMethodCalls = allArgs: Exprs, paramVars: Tainted[], g, amap, mut, isProp, isSuperInit, m, - expr: Tainted) = + expr: Tainted) = let varConv = // note: Assuming the size based on paramVars @@ -1873,7 +1873,7 @@ module ProvidedMethodCalls = dict.Add(v, (None, e)) dict - let rec exprToExprAndWitness top (ea: Tainted) = + let rec exprToExprAndWitness top (ea: Tainted) = let fail() = error(Error(FSComp.SR.etUnsupportedProvidedExpression(ea.PUntaint((fun etree -> etree.UnderlyingExpressionString), m)), m)) match ea with | Tainted.Null -> error(Error(FSComp.SR.etNullProvidedExpression(ea.TypeProviderDesignation), m)) @@ -2115,7 +2115,7 @@ module ProvidedMethodCalls = methInfoOpt, expr, exprTy with | :? TypeProviderError as tpe -> - let typeName = mi.PUntaint((fun mb -> (nonNull mb.DeclaringType).FullName), m) + let typeName = mi.PUntaint((fun mb -> (nonNull mb.DeclaringType).FullName |> string), m) let methName = mi.PUntaint((fun mb -> mb.Name), m) raise( tpe.WithContext(typeName, methName) ) // loses original stack trace #endif diff --git a/src/Compiler/Checking/MethodOverrides.fs b/src/Compiler/Checking/MethodOverrides.fs index 18b3f23190f..4621aed620e 100644 --- a/src/Compiler/Checking/MethodOverrides.fs +++ b/src/Compiler/Checking/MethodOverrides.fs @@ -269,7 +269,7 @@ module DispatchSlotChecking = // Compare the types. CompiledSigOfMeth, GetObjectExprOverrideInfo and GetTypeMemberOverrideInfo have already // applied all relevant substitutions except the renamings from fvtmps <-> methTypars - let aenv = TypeEquivEnv.FromEquivTypars fvmethTypars methTypars + let aenv = (TypeEquivEnv.EmptyIgnoreNulls).FromEquivTypars fvmethTypars methTypars List.forall2 (List.lengthsEqAndForall2 (typeAEquiv g aenv)) vargTys argTys && returnTypesAEquiv g aenv vrty retTy && @@ -305,7 +305,7 @@ module DispatchSlotChecking = ComposeTyparInsts ttpinst (ReverseTyparRenaming g memberToParentInst) // Compare under the composed substitutions - let aenv = TypeEquivEnv.FromTyparInst ttpinst + let aenv = (TypeEquivEnv.EmptyIgnoreNulls).FromTyparInst ttpinst typarsAEquiv g aenv fvmethTypars methTypars diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 5b0c9842f77..e3ad26d3ed7 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -991,7 +991,7 @@ let ResolveProvidedTypeNameInEntity (amap, m, typeName, modref: ModuleOrNamespac //if staticResInfo.NumStaticArgs > 0 then // error(Error(FSComp.SR.etNestedProvidedTypesDoNotTakeStaticArgumentsOrGenericParameters(), m)) [] - | nestedSty -> + | Tainted.NonNull nestedSty -> [AddEntityForProvidedType (amap, modref, resolutionEnvironment, nestedSty, m) ] | _ -> [] #endif diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index a01802b1d7c..282773b6b8b 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -764,7 +764,7 @@ module PrintTypes = |> ListSet.setify (fun (_, cx1) (_, cx2) -> match cx1, cx2 with | TyparConstraint.MayResolveMember(traitInfo1, _), - TyparConstraint.MayResolveMember(traitInfo2, _) -> traitsAEquiv denv.g TypeEquivEnv.Empty traitInfo1 traitInfo2 + TyparConstraint.MayResolveMember(traitInfo2, _) -> traitsAEquiv denv.g (TypeEquivEnv.EmptyWithNullChecks denv.g) traitInfo1 traitInfo2 | _ -> false) let cxsL = List.collect (layoutConstraintWithInfo denv env) cxs @@ -2177,7 +2177,7 @@ module TastDefinitionPrinting = match tcref.TypeReprInfo with | TProvidedTypeRepr info -> [ - for nestedType in info.ProvidedType.PApplyArray((fun sty -> sty.GetNestedTypes() |> Array.filter (fun t -> t.IsPublic || t.IsNestedPublic)), "GetNestedTypes", m) do + for nestedType in info.ProvidedType.PApplyFilteredArray((fun sty -> sty.GetNestedTypes()),(fun t -> t.IsPublic || t.IsNestedPublic), "GetNestedTypes", m) do yield nestedType.PUntaint((fun t -> t.IsClass, t.Name), m) ] |> List.sortBy snd @@ -2930,7 +2930,7 @@ let minimalStringsOfTwoTypes denv ty1 ty2 = let denv = denv.SetOpenPaths [] let denv = { denv with includeStaticParametersInTypeNames=true } let makeName t = - let assemblyName = PrintTypes.layoutAssemblyName denv t |> function Null | NonNull "" -> "" | NonNull name -> sprintf " (%s)" name + let assemblyName = PrintTypes.layoutAssemblyName denv t |> function | "" -> "" | name -> $" (%s{name})" sprintf "%s%s" (stringOfTy denv t) assemblyName (makeName ty1, makeName ty2, stringOfTyparConstraints denv tpcs) diff --git a/src/Compiler/Checking/SignatureConformance.fs b/src/Compiler/Checking/SignatureConformance.fs index 8e8dc84eb2b..d922423017f 100644 --- a/src/Compiler/Checking/SignatureConformance.fs +++ b/src/Compiler/Checking/SignatureConformance.fs @@ -25,15 +25,17 @@ open FSharp.Compiler.TypeHierarchy open FSharp.Compiler.TypeProviders #endif +type TypeMismatchSource = NullnessOnlyMismatch | RegularMismatch + exception RequiredButNotSpecified of DisplayEnv * ModuleOrNamespaceRef * string * (StringBuilder -> unit) * range -exception ValueNotContained of DisplayEnv * InfoReader * ModuleOrNamespaceRef * Val * Val * (string * string * string -> string) +exception ValueNotContained of kind:TypeMismatchSource * DisplayEnv * InfoReader * ModuleOrNamespaceRef * Val * Val * (string * string * string -> string) exception UnionCaseNotContained of DisplayEnv * InfoReader * Tycon * UnionCase * UnionCase * (string * string -> string) exception FSharpExceptionNotContained of DisplayEnv * InfoReader * Tycon * Tycon * (string * string -> string) -exception FieldNotContained of DisplayEnv * InfoReader * Tycon * Tycon * RecdField * RecdField * (string * string -> string) +exception FieldNotContained of kind:TypeMismatchSource * DisplayEnv * InfoReader * Tycon * Tycon * RecdField * RecdField * (string * string -> string) exception InterfaceNotRevealed of DisplayEnv * TType * range @@ -338,8 +340,8 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = implVal.SetOtherRange (sigVal.Range, false) implVal.SetOtherXmlDoc(sigVal.XmlDoc) - let mk_err denv f = ValueNotContained(denv, infoReader, implModRef, implVal, sigVal, f) - let err denv f = errorR(mk_err denv f); false + let mk_err kind denv f = ValueNotContained(kind,denv, infoReader, implModRef, implVal, sigVal, f) + let err denv f = errorR(mk_err RegularMismatch denv f); false let m = implVal.Range if implVal.IsMutable <> sigVal.IsMutable then (err denv FSComp.SR.ValueNotContainedMutabilityAttributesDiffer) elif implVal.LogicalName <> sigVal.LogicalName then (err denv FSComp.SR.ValueNotContainedMutabilityNamesDiffer) @@ -352,14 +354,22 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = else let implTypars, implValTy = implVal.GeneralizedType let sigTypars, sigValTy = sigVal.GeneralizedType - if implTypars.Length <> sigTypars.Length then (err {denv with showTyparBinding=true} FSComp.SR.ValueNotContainedMutabilityParameterCountsDiffer) else - let aenv = aenv.BindEquivTypars implTypars sigTypars - checkTypars m aenv implTypars sigTypars && - if not (typeAEquiv g aenv implValTy sigValTy) then err denv FSComp.SR.ValueNotContainedMutabilityTypesDiffer - elif not (checkValInfo aenv (err denv) implVal sigVal) then false - elif implVal.IsExtensionMember <> sigVal.IsExtensionMember then err denv FSComp.SR.ValueNotContainedMutabilityExtensionsDiffer - elif not (checkMemberDatasConform (err denv) (implVal.Attribs, implVal, implVal.MemberInfo) (sigVal.Attribs, sigVal, sigVal.MemberInfo)) then false - else checkAttribs aenv implVal.Attribs sigVal.Attribs (fun attribs -> implVal.SetAttribs attribs) + if implTypars.Length <> sigTypars.Length then (err {denv with showTyparBinding=true} FSComp.SR.ValueNotContainedMutabilityParameterCountsDiffer) + else + let aenv = aenv.BindEquivTypars implTypars sigTypars + checkTypars m aenv implTypars sigTypars && + let strictTyEquals = typeAEquiv g aenv implValTy sigValTy + let onlyDiffersInNullness = not(strictTyEquals) && g.checkNullness && typeAEquiv g {aenv with NullnessMustEqual = false} implValTy sigValTy + + // The types would be equal if we did not have nullness checks => lets just generate a warning, not an error + if onlyDiffersInNullness then + warning(mk_err NullnessOnlyMismatch denv FSComp.SR.ValueNotContainedMutabilityTypesDifferNullness) + + if not strictTyEquals && not onlyDiffersInNullness then err denv FSComp.SR.ValueNotContainedMutabilityTypesDiffer + elif not (checkValInfo aenv (err denv) implVal sigVal) then false + elif implVal.IsExtensionMember <> sigVal.IsExtensionMember then err denv FSComp.SR.ValueNotContainedMutabilityExtensionsDiffer + elif not (checkMemberDatasConform (err denv) (implVal.Attribs, implVal, implVal.MemberInfo) (sigVal.Attribs, sigVal, sigVal.MemberInfo)) then false + else checkAttribs aenv implVal.Attribs sigVal.Attribs (fun attribs -> implVal.SetAttribs attribs) and checkExnInfo err aenv (infoReader: InfoReader) (enclosingImplTycon: Tycon) (enclosingSigTycon: Tycon) implTypeRepr sigTypeRepr = @@ -394,7 +404,21 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = and checkField aenv infoReader (enclosingImplTycon: Tycon) (enclosingSigTycon: Tycon) implField sigField = implField.SetOtherXmlDoc(sigField.XmlDoc) - let err f = errorR(FieldNotContained(denv, infoReader, enclosingImplTycon, enclosingSigTycon, implField, sigField, f)); false + let diag kind f = FieldNotContained(kind,denv, infoReader, enclosingImplTycon, enclosingSigTycon, implField, sigField, f) + let err f = errorR(diag RegularMismatch f); false + + let areTypesDifferent() = + let strictTyEquals = typeAEquiv g aenv implField.FormalType sigField.FormalType + let onlyDiffersInNullness = not(strictTyEquals) && g.checkNullness && typeAEquiv g {aenv with NullnessMustEqual = false} implField.FormalType sigField.FormalType + + // The types would be equal if we did not have nullness checks => lets just generate a warning, not an error + if onlyDiffersInNullness then + warning(diag NullnessOnlyMismatch FSComp.SR.FieldNotContainedTypesDifferNullness) + false + else + not strictTyEquals + + sigField.rfield_other_range <- Some (implField.Range, true) implField.rfield_other_range <- Some (sigField.Range, false) if implField.rfield_id.idText <> sigField.rfield_id.idText then err FSComp.SR.FieldNotContainedNamesDiffer @@ -402,7 +426,7 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = elif implField.IsStatic <> sigField.IsStatic then err FSComp.SR.FieldNotContainedStaticsDiffer elif implField.IsMutable <> sigField.IsMutable then err FSComp.SR.FieldNotContainedMutablesDiffer elif implField.LiteralValue <> sigField.LiteralValue then err FSComp.SR.FieldNotContainedLiteralsDiffer - elif not (typeAEquiv g aenv implField.FormalType sigField.FormalType) then err FSComp.SR.FieldNotContainedTypesDiffer + elif areTypesDifferent() then err FSComp.SR.FieldNotContainedTypesDiffer else checkAttribs aenv implField.FieldAttribs sigField.FieldAttribs (fun attribs -> implField.rfield_fattribs <- attribs) && checkAttribs aenv implField.PropertyAttribs sigField.PropertyAttribs (fun attribs -> implField.rfield_pattribs <- attribs) diff --git a/src/Compiler/Checking/SignatureConformance.fsi b/src/Compiler/Checking/SignatureConformance.fsi index 1b137968945..136cedce94f 100644 --- a/src/Compiler/Checking/SignatureConformance.fsi +++ b/src/Compiler/Checking/SignatureConformance.fsi @@ -13,9 +13,14 @@ open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeOps open FSharp.Compiler.InfoReader +type TypeMismatchSource = + | NullnessOnlyMismatch + | RegularMismatch + exception RequiredButNotSpecified of DisplayEnv * ModuleOrNamespaceRef * string * (StringBuilder -> unit) * range exception ValueNotContained of + kind: TypeMismatchSource * DisplayEnv * InfoReader * ModuleOrNamespaceRef * @@ -28,6 +33,7 @@ exception UnionCaseNotContained of DisplayEnv * InfoReader * Tycon * UnionCase * exception FSharpExceptionNotContained of DisplayEnv * InfoReader * Tycon * Tycon * (string * string -> string) exception FieldNotContained of + kind: TypeMismatchSource * DisplayEnv * InfoReader * Tycon * diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs index c40fd73b234..c87d6cdad03 100644 --- a/src/Compiler/Checking/import.fs +++ b/src/Compiler/Checking/import.fs @@ -75,7 +75,7 @@ type [] TTypeCacheKey = stampEquals this.tcGlobals this.ty1 other.ty1 && stampEquals this.tcGlobals this.ty2 other.ty2 - override this.Equals other = + override this.Equals(other:objnull) = match other with | :? TTypeCacheKey as p -> (this :> System.IEquatable).Equals p | _ -> false @@ -450,13 +450,13 @@ let rec ImportProvidedTypeAsILType (env: ImportMap) (m: range) (st: Tainted st.IsGenericParameter), m) then mkILTyvarTy (uint16 (st.PUntaint((fun st -> st.GenericParameterPosition), m))) elif st.PUntaint((fun st -> st.IsArray), m) then - let et = ImportProvidedTypeAsILType env m (st.PApply((fun st -> st.GetElementType()), m)) + let et = ImportProvidedTypeAsILType env m (st.PApply((fun st -> !! st.GetElementType()), m)) ILType.Array(ILArrayShape.FromRank (st.PUntaint((fun st -> st.GetArrayRank()), m)), et) elif st.PUntaint((fun st -> st.IsByRef), m) then - let et = ImportProvidedTypeAsILType env m (st.PApply((fun st -> st.GetElementType()), m)) + let et = ImportProvidedTypeAsILType env m (st.PApply((fun st -> !! st.GetElementType()), m)) ILType.Byref et elif st.PUntaint((fun st -> st.IsPointer), m) then - let et = ImportProvidedTypeAsILType env m (st.PApply((fun st -> st.GetElementType()), m)) + let et = ImportProvidedTypeAsILType env m (st.PApply((fun st -> !! st.GetElementType()), m)) ILType.Ptr et else let gst, genericArgs = @@ -494,15 +494,15 @@ let rec ImportProvidedType (env: ImportMap) (m: range) (* (tinst: TypeInst) *) ( let g = env.g if st.PUntaint((fun st -> st.IsArray), m) then - let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) + let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> !! st.GetElementType()), m)) // TODO Nullness - integration into type providers as a separate feature for later. let nullness = Nullness.knownAmbivalent mkArrayTy g (st.PUntaint((fun st -> st.GetArrayRank()), m)) nullness elemTy m elif st.PUntaint((fun st -> st.IsByRef), m) then - let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) + let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> !! st.GetElementType()), m)) mkByrefTy g elemTy elif st.PUntaint((fun st -> st.IsPointer), m) then - let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()), m)) + let elemTy = ImportProvidedType env m (* tinst *) (st.PApply((fun st -> !! st.GetElementType()), m)) if isUnitTy g elemTy || isVoidTy g elemTy && g.voidptr_tcr.CanDeref then mkVoidPtrTy g else @@ -602,7 +602,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta | Some found -> found.Coerce(m) | None -> let methodName = minfo.PUntaint((fun minfo -> minfo.Name), m) - let typeName = declaringGenericTypeDefn.PUntaint((fun declaringGenericTypeDefn -> declaringGenericTypeDefn.FullName), m) + let typeName = declaringGenericTypeDefn.PUntaint((fun declaringGenericTypeDefn -> string declaringGenericTypeDefn.FullName), m) error(Error(FSComp.SR.etIncorrectProvidedMethod(DisplayNameOfTypeProvider(minfo.TypeProvider, m), methodName, metadataToken, typeName), m)) | _ -> match mbase.OfType() with @@ -634,7 +634,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta match found with | Some found -> found.Coerce(m) | None -> - let typeName = declaringGenericTypeDefn.PUntaint((fun x -> x.FullName), m) + let typeName = declaringGenericTypeDefn.PUntaint((fun x -> string x.FullName), m) error(Error(FSComp.SR.etIncorrectProvidedConstructor(DisplayNameOfTypeProvider(cinfo.TypeProvider, m), typeName), m)) | _ -> mbase @@ -648,7 +648,7 @@ let ImportProvidedMethodBaseAsILMethodRef (env: ImportMap) (m: range) (mbase: Ta let genericArity = if mbase.PUntaint((fun x -> x.IsGenericMethod), m) then - mbase.PUntaint((fun x -> x.GetGenericArguments().Length), m) + mbase.PApplyArray((fun x -> x.GetGenericArguments()),"GetGenericArguments", m).Length else 0 let callingConv = (if mbase.PUntaint((fun x -> x.IsStatic), m) then ILCallingConv.Static else ILCallingConv.Instance) diff --git a/src/Compiler/Checking/import.fsi b/src/Compiler/Checking/import.fsi index 001f9367989..c387558fcba 100644 --- a/src/Compiler/Checking/import.fsi +++ b/src/Compiler/Checking/import.fsi @@ -54,7 +54,6 @@ type TTypeCacheKey = val ty2: TType val canCoerce: CanCoerce val tcGlobals: TcGlobals - override Equals: other: obj -> bool override GetHashCode: unit -> int /// Represents a context used for converting AbstractIL .NET and provided types to F# internal compiler data structures. diff --git a/src/Compiler/Checking/infos.fs b/src/Compiler/Checking/infos.fs index 18add6588d0..3fe1ba2f7b1 100644 --- a/src/Compiler/Checking/infos.fs +++ b/src/Compiler/Checking/infos.fs @@ -859,7 +859,7 @@ type MethInfo = | MethInfoWithModifiedReturnType(mi, _) -> mi.NumArgs | DefaultStructCtor _ -> [0] #if !NO_TYPEPROVIDERS - | ProvidedMeth(_, mi, _, m) -> [mi.PUntaint((fun mi -> mi.GetParameters().Length), m)] // Why is this a list? Answer: because the method might be curried + | ProvidedMeth(_, mi, _, m) -> [mi.PApplyArray((fun mi -> mi.GetParameters()),"GetParameters", m).Length] // Why is this a list? Answer: because the method might be curried #endif /// Indicates if the property is a IsABC union case tester implied by a union case definition @@ -2030,7 +2030,7 @@ type PropInfo = failwith "unreachable" #if !NO_TYPEPROVIDERS | ProvidedProp(_, pi, m) -> - pi.PUntaint((fun pi -> pi.GetIndexParameters().Length), m)>0 + pi.PApplyArray((fun pi -> pi.GetIndexParameters()),"GetIndexParameters", m).Length>0 #endif /// Indicates if this is an F# property compiled as a CLI event, e.g. a [] property. @@ -2503,7 +2503,7 @@ let MethInfosEquivByPartialSig erasureFlag ignoreFinal g amap m (minfo: MethInfo let argTys = minfo.GetParamTypes(amap, m, fminst) let argTys2 = minfo2.GetParamTypes(amap, m, fminst2) (argTys, argTys2) ||> List.lengthsEqAndForall2 (List.lengthsEqAndForall2 (fun ty1 ty2 -> - typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2) (stripByrefTy g ty1) (stripByrefTy g ty2))) + typeAEquivAux erasureFlag g (TypeEquivEnv.EmptyIgnoreNulls.FromEquivTypars formalMethTypars formalMethTypars2) (stripByrefTy g ty1) (stripByrefTy g ty2))) /// Used to hide/filter members from super classes based on signature /// Inref and outref parameter types will be treated as a byref type for equivalency. @@ -2525,7 +2525,7 @@ let MethInfosEquivByNameAndSig erasureFlag ignoreFinal g amap m minfo minfo2 = let (CompiledSig(_, retTy2, formalMethTypars2, _)) = CompiledSigOfMeth g amap m minfo2 match retTy, retTy2 with | None, None -> true - | Some retTy, Some retTy2 -> typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2) retTy retTy2 + | Some retTy, Some retTy2 -> typeAEquivAux erasureFlag g (TypeEquivEnv.EmptyIgnoreNulls.FromEquivTypars formalMethTypars formalMethTypars2) retTy retTy2 | _ -> false /// Used to hide/filter members from super classes based on signature diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index ff0859486d7..53cfb3e77cd 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -12227,7 +12227,7 @@ let LookupGeneratedValue (cenv: cenv) (ctxt: ExecutionContext) eenv (v: Val) = // Lookup the compiled v value (as an object). match StorageForVal v.Range v eenv with | StaticPropertyWithField(fspec, _, hasLiteralAttr, ilContainerTy, _, _, ilGetterMethRef, _, _) -> - let obj = + let obj: objnull = if hasLiteralAttr then let staticTy = ctxt.LookupTypeRef fspec.DeclaringTypeRef // Checked: This FieldInfo (FieldBuilder) supports GetValue(). @@ -12245,7 +12245,7 @@ let LookupGeneratedValue (cenv: cenv) (ctxt: ExecutionContext) eenv (v: Val) = Some(obj, objTyp ()) | StaticProperty(ilGetterMethSpec, _) -> - let obj = + let obj: objnull = let staticTy = ctxt.LookupTypeRef ilGetterMethSpec.MethodRef.DeclaringTypeRef // We can't call .Invoke on the ILMethodRef's MethodInfo, // because it is the MethodBuilder and that does not support Invoke. @@ -12373,7 +12373,7 @@ type IlxAssemblyGenerator(amap: ImportMap, g: TcGlobals, tcVal: ConstraintSolver member _.ClearGeneratedValue(ctxt, v) = ClearGeneratedValue ctxt ilxGenEnv v /// Invert the compilation of the given value and set the storage of the value, even if it is immutable - member _.ForceSetGeneratedValue(ctxt, v, value: obj) = + member _.ForceSetGeneratedValue(ctxt, v, value: objnull) = SetGeneratedValue ctxt ilxGenEnv true v value /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type diff --git a/src/Compiler/CodeGen/IlxGen.fsi b/src/Compiler/CodeGen/IlxGen.fsi index 4658dd0693b..bb78a30fe41 100644 --- a/src/Compiler/CodeGen/IlxGen.fsi +++ b/src/Compiler/CodeGen/IlxGen.fsi @@ -111,10 +111,10 @@ type public IlxAssemblyGenerator = member ClearGeneratedValue: ExecutionContext * Val -> unit /// Invert the compilation of the given value and set the storage of the value, even if it is immutable - member ForceSetGeneratedValue: ExecutionContext * Val * obj -> unit + member ForceSetGeneratedValue: ExecutionContext * Val * objnull -> unit /// Invert the compilation of the given value and return its current dynamic value and its compiled System.Type - member LookupGeneratedValue: ExecutionContext * Val -> (obj * Type) option + member LookupGeneratedValue: ExecutionContext * Val -> (objnull * Type) option val ReportStatistics: TextWriter -> unit diff --git a/src/Compiler/DependencyManager/AssemblyResolveHandler.fs b/src/Compiler/DependencyManager/AssemblyResolveHandler.fs index 0c87130608e..1f20caa392e 100644 --- a/src/Compiler/DependencyManager/AssemblyResolveHandler.fs +++ b/src/Compiler/DependencyManager/AssemblyResolveHandler.fs @@ -113,7 +113,7 @@ type AssemblyResolveHandler internal (assemblyProbingPaths: AssemblyResolutionPr else new AssemblyResolveHandlerDeskTop(assemblyProbingPaths) :> IDisposable) - new(assemblyProbingPaths: AssemblyResolutionProbe MaybeNull) = new AssemblyResolveHandler(Option.ofObj assemblyProbingPaths) + new(assemblyProbingPaths: AssemblyResolutionProbe | null) = new AssemblyResolveHandler(Option.ofObj assemblyProbingPaths) interface IDisposable with member _.Dispose() = diff --git a/src/Compiler/DependencyManager/AssemblyResolveHandler.fsi b/src/Compiler/DependencyManager/AssemblyResolveHandler.fsi index 0fbb6c33535..e1c0b2574e3 100644 --- a/src/Compiler/DependencyManager/AssemblyResolveHandler.fsi +++ b/src/Compiler/DependencyManager/AssemblyResolveHandler.fsi @@ -12,7 +12,7 @@ type AssemblyResolutionProbe = delegate of Unit -> seq type AssemblyResolveHandler = /// Construct a new DependencyProvider - new: assemblyProbingPaths: AssemblyResolutionProbe -> AssemblyResolveHandler + new: assemblyProbingPaths: AssemblyResolutionProbe|null -> AssemblyResolveHandler /// Construct a new DependencyProvider internal new: assemblyProbingPaths: AssemblyResolutionProbe option -> AssemblyResolveHandler diff --git a/src/Compiler/DependencyManager/DependencyProvider.fs b/src/Compiler/DependencyManager/DependencyProvider.fs index 1bf72a76e5b..6e641af607b 100644 --- a/src/Compiler/DependencyManager/DependencyProvider.fs +++ b/src/Compiler/DependencyManager/DependencyProvider.fs @@ -564,7 +564,7 @@ type DependencyProvider new() = new DependencyProvider(None, None, true) /// Returns a formatted help messages for registered dependencymanagers for the host to present - member _.GetRegisteredDependencyManagerHelpText(compilerTools, outputDir, errorReport) = + member _.GetRegisteredDependencyManagerHelpText(compilerTools, outputDir : string | null, errorReport) = [| let managers = RegisteredDependencyManagers compilerTools (Option.ofString outputDir) errorReport @@ -575,7 +575,7 @@ type DependencyProvider |] /// Clear the DependencyManager results caches - member _.ClearResultsCache(compilerTools, outputDir, errorReport) = + member _.ClearResultsCache(compilerTools, outputDir : string | null, errorReport) = let managers = RegisteredDependencyManagers compilerTools (Option.ofString outputDir) errorReport diff --git a/src/Compiler/DependencyManager/DependencyProvider.fsi b/src/Compiler/DependencyManager/DependencyProvider.fsi index fffaa9a2026..aa1bd27d5b7 100644 --- a/src/Compiler/DependencyManager/DependencyProvider.fsi +++ b/src/Compiler/DependencyManager/DependencyProvider.fsi @@ -108,10 +108,10 @@ type DependencyProvider = DependencyProvider /// Returns a formatted help messages for registered dependencymanagers for the host to present - member GetRegisteredDependencyManagerHelpText: string seq * string * ResolvingErrorReport -> string[] + member GetRegisteredDependencyManagerHelpText: string seq * string MaybeNull * ResolvingErrorReport -> string[] /// Clear the DependencyManager results caches - member ClearResultsCache: string seq * string * ResolvingErrorReport -> unit + member ClearResultsCache: string seq * string MaybeNull * ResolvingErrorReport -> unit /// Returns a formatted error message for the host to present member CreatePackageManagerUnknownError: string seq * string * string * ResolvingErrorReport -> int * string @@ -123,7 +123,7 @@ type DependencyProvider = packageManagerTextLines: (string * string) seq * reportError: ResolvingErrorReport * executionTfm: string * - [] executionRid: string * + [] executionRid: string MaybeNull* [] implicitIncludeDir: string * [] mainScriptName: string * [] fileName: string * diff --git a/src/Compiler/DependencyManager/NativeDllResolveHandler.fs b/src/Compiler/DependencyManager/NativeDllResolveHandler.fs index 6319f3df48b..3c6bbe0a900 100644 --- a/src/Compiler/DependencyManager/NativeDllResolveHandler.fs +++ b/src/Compiler/DependencyManager/NativeDllResolveHandler.fs @@ -184,7 +184,7 @@ type NativeDllResolveHandler(nativeProbingRoots: NativeResolutionProbe option) = |> Option.filter (fun _ -> isRunningOnCoreClr) |> Option.map (fun _ -> new NativeDllResolveHandlerCoreClr(nativeProbingRoots)) - new(nativeProbingRoots: NativeResolutionProbe MaybeNull) = new NativeDllResolveHandler(Option.ofObj nativeProbingRoots) + new(nativeProbingRoots: NativeResolutionProbe | null) = new NativeDllResolveHandler(Option.ofObj nativeProbingRoots) member internal _.RefreshPathsInEnvironment(roots: string seq) = handler |> Option.iter (fun handler -> handler.RefreshPathsInEnvironment(roots)) diff --git a/src/Compiler/DependencyManager/NativeDllResolveHandler.fsi b/src/Compiler/DependencyManager/NativeDllResolveHandler.fsi index 8bb2babae2a..9d2961aa94e 100644 --- a/src/Compiler/DependencyManager/NativeDllResolveHandler.fsi +++ b/src/Compiler/DependencyManager/NativeDllResolveHandler.fsi @@ -12,7 +12,7 @@ type NativeResolutionProbe = delegate of Unit -> seq type NativeDllResolveHandler = /// Construct a new NativeDllResolveHandler - new: nativeProbingRoots: NativeResolutionProbe -> NativeDllResolveHandler + new: nativeProbingRoots: NativeResolutionProbe|null -> NativeDllResolveHandler /// Construct a new NativeDllResolveHandler internal new: nativeProbingRoots: NativeResolutionProbe option -> NativeDllResolveHandler diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 997f7a50aae..cf875be4959 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -317,14 +317,15 @@ type AssemblyReference = member x.ProjectReference = (let (AssemblyReference(_, _, contents)) = x in contents) - member x.SimpleAssemblyNameIs name = + member x.SimpleAssemblyNameIs(name: string) = (String.Compare(FileSystemUtils.fileNameWithoutExtensionWithValidate false x.Text, name, StringComparison.OrdinalIgnoreCase) = 0) || not (x.Text.Contains "/") && not (x.Text.Contains "\\") && not (x.Text.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase)) && not (x.Text.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) && (try - let aname = System.Reflection.AssemblyName x.Text in aname.Name = name + let aname = System.Reflection.AssemblyName x.Text + aname.Name = name with _ -> false) @@ -699,9 +700,6 @@ type TcConfigBuilder = rangeForErrors ) = - let defaultFSharpBinariesDir = - nullArgCheck "defaultFSharpBinariesDir" defaultFSharpBinariesDir - // These are all default values, many can be overridden using the command line switch { primaryAssembly = PrimaryAssembly.Mscorlib diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 019226f46e4..289d993e96e 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -158,8 +158,8 @@ type Exception with | IndeterminateType m | TyconBadArgs(_, _, _, m) -> Some m - | FieldNotContained(_, _, _, _, arf, _, _) -> Some arf.Range - | ValueNotContained(_, _, _, aval, _, _) -> Some aval.Range + | FieldNotContained(_, _, _, _, _, arf, _, _) -> Some arf.Range + | ValueNotContained(_, _, _, _, aval, _, _) -> Some aval.Range | UnionCaseNotContained(_, _, _, aval, _, _) -> Some aval.Id.idRange | FSharpExceptionNotContained(_, _, aexnc, _, _) -> Some aexnc.Range @@ -255,6 +255,8 @@ type Exception with | LetRecUnsound _ -> 31 | FieldsFromDifferentTypes _ -> 32 | TyconBadArgs _ -> 33 + | FieldNotContained(kind = TypeMismatchSource.NullnessOnlyMismatch) -> 3261 + | ValueNotContained(kind = TypeMismatchSource.NullnessOnlyMismatch) -> 3261 | ValueNotContained _ -> 34 | Deprecated _ -> 35 | UnionCaseNotContained _ -> 36 @@ -1616,7 +1618,7 @@ type Exception with | UnionPatternsBindDifferentNames _ -> os.AppendString(UnionPatternsBindDifferentNamesE().Format) - | ValueNotContained(denv, infoReader, mref, implVal, sigVal, f) -> + | ValueNotContained(_, denv, infoReader, mref, implVal, sigVal, f) -> let text1, text2 = NicePrint.minimalStringsOfTwoValues denv infoReader (mkLocalValRef implVal) (mkLocalValRef sigVal) @@ -1640,7 +1642,7 @@ type Exception with ) ) - | FieldNotContained(denv, infoReader, enclosingTycon, _, v1, v2, f) -> + | FieldNotContained(_, denv, infoReader, enclosingTycon, _, v1, v2, f) -> let enclosingTcref = mkLocalEntityRef enclosingTycon os.AppendString( diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 22ea3c7f033..975bfeef66f 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -828,7 +828,7 @@ let ParseInputFilesInParallel (tcConfig: TcConfig, lexResourceManager, sourceFil UseMultipleDiagnosticLoggers (sourceFiles, delayLogger, None) (fun sourceFilesWithDelayLoggers -> sourceFilesWithDelayLoggers |> ListParallel.map (fun ((fileName, isLastCompiland), delayLogger) -> - let directoryName = Path.GetDirectoryName fileName + let directoryName = !!(Path.GetDirectoryName fileName) let input = parseInputFileAux (tcConfig, lexResourceManager, fileName, (isLastCompiland, isExe), delayLogger, retryLocked) @@ -841,7 +841,7 @@ let ParseInputFilesSequential (tcConfig: TcConfig, lexResourceManager, sourceFil sourceFiles |> Array.map (fun (fileName, isLastCompiland) -> - let directoryName = Path.GetDirectoryName fileName + let directoryName = !!(Path.GetDirectoryName fileName) let input = ParseOneInputFile(tcConfig, lexResourceManager, fileName, (isLastCompiland, isExe), diagnosticsLogger, retryLocked) @@ -1907,7 +1907,10 @@ let CheckMultipleInputsUsingGraphMode let (Finisher(finisher = finisher)) = cancellable { use _ = UseDiagnosticsLogger logger - let checkForErrors2 () = priorErrors || (logger.ErrorCount > 0) + + let checkForErrors2 () = + priorErrors || (logger.CheckForRealErrorsIgnoringWarnings) + let tcSink = TcResultsSink.NoSink return! @@ -1922,7 +1925,7 @@ let CheckMultipleInputsUsingGraphMode (fun (state: State) -> let tcState, priorErrors = state let (partialResult: PartialResult, tcState) = finisher tcState - let hasErrors = logger.ErrorCount > 0 + let hasErrors = logger.CheckForRealErrorsIgnoringWarnings let priorOrCurrentErrors = priorErrors || hasErrors let state: State = tcState, priorOrCurrentErrors partialResult, state) diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 696761f43da..0e26f2db4ac 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -164,7 +164,7 @@ let TypeCheck CheckClosedInputSet( ctok, - diagnosticsLogger.CheckForErrors, + (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), tcConfig, tcImports, tcGlobals, diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 4bdee0183ea..ad95dc6556b 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -112,6 +112,7 @@ ValueNotContainedMutabilityLiteralConstantValuesDiffer,"Module '%s' contains\n ValueNotContainedMutabilityOneIsTypeFunction,"Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is a type function and the other is not. The signature requires explicit type parameters if they are present in the implementation." ValueNotContainedMutabilityParameterCountsDiffer,"Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe respective type parameter counts differ" ValueNotContainedMutabilityTypesDiffer,"Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe types differ" +ValueNotContainedMutabilityTypesDifferNullness,"Nullness warning: Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe types differ in their nullness annotations" ValueNotContainedMutabilityExtensionsDiffer,"Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is an extension member and the other is not" ValueNotContainedMutabilityArityNotInferred,"Module '%s' contains\n %s \nbut its signature specifies\n %s \nAn arity was not inferred for this value" ValueNotContainedMutabilityGenericParametersDiffer,"Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe number of generic parameters in the signature and implementation differ (the signature declares %s but the implementation declares %s" @@ -167,6 +168,7 @@ FieldNotContainedStaticsDiffer,"The module contains the field\n %s \nbut i FieldNotContainedMutablesDiffer,"The module contains the field\n %s \nbut its signature specifies\n %s \nThe 'mutable' modifiers differ" FieldNotContainedLiteralsDiffer,"The module contains the field\n %s \nbut its signature specifies\n %s \nThe 'literal' modifiers differ" FieldNotContainedTypesDiffer,"The module contains the field\n %s \nbut its signature specifies\n %s \nThe types differ" +FieldNotContainedTypesDifferNullness,"Nullness warning: The module contains the field\n %s \nbut its signature specifies\n %s \nThe types differ in their nullness annotations" 331,typrelCannotResolveImplicitGenericInstantiation,"The implicit instantiation of a generic construct at or near this point could not be resolved because it could resolve to multiple unrelated types, e.g. '%s' and '%s'. Consider using type annotations to resolve the ambiguity" 333,typrelCannotResolveAmbiguityInPrintf,"Could not resolve the ambiguity inherent in the use of a 'printf'-style format string" 334,typrelCannotResolveAmbiguityInEnum,"Could not resolve the ambiguity in the use of a generic construct with an 'enum' constraint at or near this position" diff --git a/src/Compiler/Facilities/CompilerLocation.fs b/src/Compiler/Facilities/CompilerLocation.fs index 9cd20c1863e..2e9137fc75d 100644 --- a/src/Compiler/Facilities/CompilerLocation.fs +++ b/src/Compiler/Facilities/CompilerLocation.fs @@ -32,6 +32,7 @@ module internal FSharpEnvironment = let FSharpCoreLibRunningVersion = try match versionOf with + | null -> None | s when String.IsNullOrEmpty(s) -> None | s -> Some(s) with _ -> diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index 69d1f4fc306..cf5c20fe84c 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -795,8 +795,7 @@ let NewlineifyErrorString (message: string) = /// fixes given string by replacing all control chars with spaces. /// NOTE: newlines are recognized and replaced with stringThatIsAProxyForANewlineInFlatErrors (ASCII 29, the 'group separator'), /// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo -let NormalizeErrorString (text: string MaybeNull) = - let text = nullArgCheck "text" text +let NormalizeErrorString (text: string) = let text = text.Trim() let buf = System.Text.StringBuilder() diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index e5a4c8e7f8a..da7a6a66ca8 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -207,6 +207,7 @@ type DiagnosticsLogger = abstract ErrorCount: int /// Checks if ErrorCount > 0 + [] member CheckForErrors: unit -> bool abstract CheckForRealErrorsIgnoringWarnings: bool diff --git a/src/Compiler/Facilities/prim-parsing.fs b/src/Compiler/Facilities/prim-parsing.fs index 7fb0d7fca41..632832b8d85 100644 --- a/src/Compiler/Facilities/prim-parsing.fs +++ b/src/Compiler/Facilities/prim-parsing.fs @@ -5,6 +5,7 @@ namespace Internal.Utilities.Text.Parsing open Internal.Utilities.Text.Lexing +open Internal.Utilities.Library open System open System.Buffers @@ -28,7 +29,7 @@ type internal IParseState member _.ResultEndPosition = lhsPos[1] - member _.GetInput index = ruleValues[index - 1] + member _.GetInput index = !!ruleValues[index - 1] member _.ResultRange = (lhsPos[0], lhsPos[1]) @@ -572,7 +573,7 @@ module internal Implementation = else if Flags.debug then Console.WriteLine("ALARM!!! drop through case in parser") // OK, we're done - read off the overall generated value - valueStack.Peep().value + !!valueStack.Peep().value type internal Tables<'Token> with diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index c31f210022f..eaba5aa6582 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -77,7 +77,7 @@ open FSharp.Compiler.CheckExpressionsOps // For the FSI as a service methods... //---------------------------------------------------------------------------- -type FsiValue(reflectionValue: obj, reflectionType: Type, fsharpType: FSharpType) = +type FsiValue(reflectionValue: objnull, reflectionType: Type, fsharpType: FSharpType) = member _.ReflectionValue = reflectionValue member _.ReflectionType = reflectionType @@ -93,15 +93,15 @@ type FsiBoundValue(name: string, value: FsiValue) = [] module internal Utilities = type IAnyToLayoutCall = - abstract AnyToLayout: FormatOptions * obj * Type -> Layout - abstract FsiAnyToLayout: FormatOptions * obj * Type -> Layout + abstract AnyToLayout: FormatOptions * objnull * Type -> Layout + abstract FsiAnyToLayout: FormatOptions * objnull * Type -> Layout type private AnyToLayoutSpecialization<'T>() = interface IAnyToLayoutCall with - member _.AnyToLayout(options, o: obj, ty: Type) = + member _.AnyToLayout(options, o: objnull, ty: Type) = Display.any_to_layout options ((Unchecked.unbox o: 'T), ty) - member _.FsiAnyToLayout(options, o: obj, ty: Type) = + member _.FsiAnyToLayout(options, o: objnull, ty: Type) = Display.fsi_any_to_layout options ((Unchecked.unbox o: 'T), ty) let getAnyToLayoutCall (ty: Type) = @@ -112,13 +112,19 @@ module internal Utilities = |> NativeInterop.NativePtr.toNativeInt { new IAnyToLayoutCall with - member _.AnyToLayout(options, o: obj, ty: Type) = - let n = pointerToNativeInt o - Display.any_to_layout options (n, n.GetType()) - - member _.FsiAnyToLayout(options, o: obj, ty: Type) = - let n = pointerToNativeInt o - Display.any_to_layout options (n, n.GetType()) + member _.AnyToLayout(options, o: objnull, ty: Type) = + match o with + | null -> Display.any_to_layout options (o, ty) + | o -> + let n = pointerToNativeInt o + Display.any_to_layout options (n, n.GetType()) + + member _.FsiAnyToLayout(options, o: objnull, ty: Type) = + match o with + | null -> Display.any_to_layout options (o, ty) + | o -> + let n = pointerToNativeInt o + Display.any_to_layout options (n, n.GetType()) } else let specialized = typedefof>.MakeGenericType [| ty |] @@ -677,7 +683,7 @@ type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, outWriter: Te } /// Generate a layout for an actual F# value, where we know the value has the given static type. - member _.PrintValue(printMode, opts: FormatOptions, x: obj, ty: Type) = + member _.PrintValue(printMode, opts: FormatOptions, x: objnull, ty: Type) = // We do a dynamic invoke of any_to_layout with the right System.Type parameter for the static type of the saved value. // In principle this helps any_to_layout do the right thing as it descends through terms. In practice it means // it at least does the right thing for top level 'null' list and option values (but not for nested ones). @@ -2198,7 +2204,7 @@ type internal FsiDynamicCompiler lock tcLockObject (fun _ -> CheckClosedInputSet( ctok, - diagnosticsLogger.CheckForErrors, + (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings), tcConfig, tcImports, tcGlobals, @@ -5191,7 +5197,7 @@ module Settings = and set v = args <- v member _.AddPrinter(printer: 'T -> string) = - addedPrinters <- Choice1Of2(typeof<'T>, (fun (x: obj) -> printer (unbox x))) :: addedPrinters + addedPrinters <- Choice1Of2(typeof<'T>, (fun (x: objnull) -> printer (unbox x))) :: addedPrinters member _.EventLoop with get () = evLoop @@ -5199,8 +5205,8 @@ module Settings = evLoop.ScheduleRestart() evLoop <- x - member _.AddPrintTransformer(printer: 'T -> obj) = - addedPrinters <- Choice2Of2(typeof<'T>, (fun (x: obj) -> printer (unbox x))) :: addedPrinters + member _.AddPrintTransformer(printer: 'T -> objnull) = + addedPrinters <- Choice2Of2(typeof<'T>, (fun (x: objnull) -> printer (unbox x))) :: addedPrinters let fsi = InteractiveSettings() diff --git a/src/Compiler/Interactive/fsi.fsi b/src/Compiler/Interactive/fsi.fsi index c34a583cdb7..0e7415ca728 100644 --- a/src/Compiler/Interactive/fsi.fsi +++ b/src/Compiler/Interactive/fsi.fsi @@ -15,7 +15,7 @@ open Internal.Utilities.Library type FsiValue = /// The value, as an object - member ReflectionValue: obj + member ReflectionValue: objnull /// The type of the value, from the point of view of the .NET type system member ReflectionType: Type @@ -308,7 +308,7 @@ type FsiEvaluationSession = member ReportUnhandledException: exn: exn -> unit /// Event fires when a root-level value is bound to an identifier, e.g., via `let x = ...`. - member ValueBound: IEvent + member ValueBound: IEvent /// Gets the root-level values that are bound to an identifier member GetBoundValues: unit -> FsiBoundValue list @@ -395,7 +395,7 @@ module Settings = member AddPrinter: ('T -> string) -> unit /// Register a print transformer that controls the output of the interactive session. - member AddPrintTransformer: ('T -> obj) -> unit + member AddPrintTransformer: ('T -> objnull) -> unit member internal AddedPrinters: Choice string), Type * (objnull -> objnull)> list diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index 0d6e83a61c2..771ab536ff8 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -188,7 +188,7 @@ and FSharpProjectOptions = && options1.ReferencedProjects = options2.ReferencedProjects && options1.LoadTime = options2.LoadTime - member po.ProjectDirectory = Path.GetDirectoryName(po.ProjectFileName) + member po.ProjectDirectory = !! Path.GetDirectoryName(po.ProjectFileName) override this.ToString() = "FSharpProjectOptions(" + this.ProjectFileName + ")" diff --git a/src/Compiler/Service/QuickParse.fs b/src/Compiler/Service/QuickParse.fs index ddb7d13f126..e7361ce1634 100644 --- a/src/Compiler/Service/QuickParse.fs +++ b/src/Compiler/Service/QuickParse.fs @@ -200,7 +200,7 @@ module QuickParse = /// a call to `DeclItemsForNamesAtPosition` for intellisense. This will /// allow us to use find the correct qualified items rather than resorting /// to the more expensive and less accurate environment lookup. - let GetCompleteIdentifierIsland (tolerateJustAfter: bool) (lineStr: string) (index: int) : (string * int * bool) option = + let GetCompleteIdentifierIsland (tolerateJustAfter: bool) (lineStr: string MaybeNull) (index: int) : (string * int * bool) option = if String.IsNullOrEmpty lineStr then None else diff --git a/src/Compiler/Symbols/Exprs.fsi b/src/Compiler/Symbols/Exprs.fsi index fddc3d0ea4e..7962855a0e9 100644 --- a/src/Compiler/Symbols/Exprs.fsi +++ b/src/Compiler/Symbols/Exprs.fsi @@ -206,7 +206,7 @@ module public FSharpExprPatterns = /// Matches constant expressions, including signed and unsigned integers, strings, characters, booleans, arrays /// of bytes and arrays of unit16. - val (|Const|_|): FSharpExpr -> (obj * FSharpType) option + val (|Const|_|): FSharpExpr -> (objnull * FSharpType) option /// Matches expressions which take the address of a location val (|AddressOf|_|): FSharpExpr -> FSharpExpr option diff --git a/src/Compiler/Symbols/FSharpDiagnostic.fs b/src/Compiler/Symbols/FSharpDiagnostic.fs index 581b51ab8c7..66e077fba9c 100644 --- a/src/Compiler/Symbols/FSharpDiagnostic.fs +++ b/src/Compiler/Symbols/FSharpDiagnostic.fs @@ -200,10 +200,10 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str | FunctionValueUnexpected(_, actualType, _) -> Some(ExpressionIsAFunctionExtendedData(symbolEnv, actualType)) - | FieldNotContained(_, _, implEntity, sigEntity, impl, sign, _) -> + | FieldNotContained(_,_, _, implEntity, sigEntity, impl, sign, _) -> Some(FieldNotContainedDiagnosticExtendedData(symbolEnv, implEntity, sigEntity, sign, impl)) - | ValueNotContained(_, _, _, implValue, sigValue, _) -> + | ValueNotContained(_,_, _, _, implValue, sigValue, _) -> Some(ValueNotContainedDiagnosticExtendedData(symbolEnv, sigValue, implValue)) | ArgumentsInSigAndImplMismatch(sigArg, implArg) -> diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index f12e9de6321..48acdf03dae 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -2779,7 +2779,7 @@ type FSharpType(cenv, ty:TType) = type FSharpAttribute(cenv: SymbolEnv, attrib: AttribInfo) = - let rec resolveArgObj (arg: obj) = + let rec resolveArgObj (arg: objnull) = match arg with | :? TType as t -> box (FSharpType(cenv, t)) | :? (obj[]) as a -> a |> Array.map resolveArgObj |> box diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi index a3eda6ecd3a..701e9a8fe3c 100644 --- a/src/Compiler/Symbols/Symbols.fsi +++ b/src/Compiler/Symbols/Symbols.fsi @@ -575,7 +575,7 @@ type FSharpField = member Name: string /// Get the default initialization info, for static literals - member LiteralValue: obj option + member LiteralValue: objnull option /// Indicates if the declared visibility of the field, not taking signatures into account override Accessibility: FSharpAccessibility @@ -639,7 +639,7 @@ type FSharpStaticParameter = member Kind: FSharpType /// Get the default value for the static parameter - member DefaultValue: obj + member DefaultValue: objnull /// Indicates if the static parameter is optional member IsOptional: bool @@ -954,7 +954,7 @@ type FSharpMemberOrFunctionOrValue = member IsMemberThisValue: bool /// Indicates if this is a [] value, and if so what value? (may be null) - member LiteralValue: obj option + member LiteralValue: objnull option /// Get the accessibility information for the member, function or value override Accessibility: FSharpAccessibility @@ -1198,10 +1198,10 @@ type FSharpAttribute = member AttributeType: FSharpEntity /// The arguments to the constructor for the attribute - member ConstructorArguments: IList + member ConstructorArguments: IList /// The named arguments for the attribute - member NamedArguments: IList + member NamedArguments: IList /// Indicates if the attribute type is in an unresolved assembly member IsUnresolved: bool diff --git a/src/Compiler/SyntaxTree/PrettyNaming.fs b/src/Compiler/SyntaxTree/PrettyNaming.fs index 8ea10266de8..b0ef32edaf0 100755 --- a/src/Compiler/SyntaxTree/PrettyNaming.fs +++ b/src/Compiler/SyntaxTree/PrettyNaming.fs @@ -670,8 +670,8 @@ let IsLogicalPrefixOperator logicalName = if String.IsNullOrEmpty logicalName then false else - let displayName = ConvertValLogicalNameToDisplayNameCore !!logicalName - displayName <> !!logicalName && IsValidPrefixOperatorDefinitionName displayName + let displayName = ConvertValLogicalNameToDisplayNameCore logicalName + displayName <> logicalName && IsValidPrefixOperatorDefinitionName displayName let IsLogicalTernaryOperator logicalName = let displayName = ConvertValLogicalNameToDisplayNameCore logicalName diff --git a/src/Compiler/TypedTree/TypeProviders.fs b/src/Compiler/TypedTree/TypeProviders.fs index acef34047ca..42caa723619 100644 --- a/src/Compiler/TypedTree/TypeProviders.fs +++ b/src/Compiler/TypedTree/TypeProviders.fs @@ -22,6 +22,12 @@ open FSharp.Compiler.Text open FSharp.Compiler.Text.Range type TypeProviderDesignation = TypeProviderDesignation of string +type 'a ProvidedArray= ('a[]) MaybeNull +module ProvidedArray = + let map f (arr:_ ProvidedArray) : _ ProvidedArray = + match arr with + | null -> null + | notNull -> notNull |> Array.map f exception ProvidedTypeResolution of range * exn @@ -366,7 +372,7 @@ type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = member _.Namespace : string MaybeNull = x.Namespace - member _.FullName = x.FullName + member _.FullName : string MaybeNull = x.FullName member _.IsArray = x.IsArray @@ -403,7 +409,7 @@ type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = /// Type.BaseType can be null when Type is interface or object member _.BaseType = x.BaseType |> ProvidedType.Create ctxt - member _.GetStaticParameters(provider: ITypeProvider) : ProvidedParameterInfo[] MaybeNull = provider.GetStaticParameters x |> ProvidedParameterInfo.CreateArray ctxt + member _.GetStaticParameters(provider: ITypeProvider) : ProvidedParameterInfo ProvidedArray = provider.GetStaticParameters x |> ProvidedParameterInfo.CreateArray ctxt /// Type.GetElementType can be null if i.e. Type is not array\pointer\byref type member _.GetElementType() = x.GetElementType() |> ProvidedType.Create ctxt @@ -476,12 +482,10 @@ type ProvidedType (x: Type, ctxt: ProvidedTypeContext) = | null -> nullArg name | t -> ProvidedType (t, ctxt) - static member CreateArray ctxt (xs: Type[] MaybeNull) : ProvidedType[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedType.CreateNonNull ctxt) + static member CreateArray ctxt (xs:_ ProvidedArray) = + xs |> ProvidedArray.map (ProvidedType.CreateNonNull ctxt) - static member CreateNoContext (x:Type) = ProvidedType.Create ProvidedTypeContext.Empty x + static member CreateNoContext (x:Type) = ProvidedType.CreateNonNull ProvidedTypeContext.Empty x static member Void = ProvidedType.CreateNoContext typeof @@ -604,7 +608,7 @@ type ProvidedParameterInfo (x: ParameterInfo, ctxt) = member _.IsOptional = x.IsOptional - member _.RawDefaultValue = x.RawDefaultValue + member _.RawDefaultValue : objnull = x.RawDefaultValue member _.HasDefaultValue = x.Attributes.HasFlag(ParameterAttributes.HasDefault) @@ -618,15 +622,8 @@ type ProvidedParameterInfo (x: ParameterInfo, ctxt) = static member CreateNonNull ctxt x = ProvidedParameterInfo (x, ctxt) - static member CreateArray ctxt (xs: ParameterInfo[] MaybeNull) : ProvidedParameterInfo[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedParameterInfo.CreateNonNull ctxt) - - static member CreateArrayNonNull ctxt xs : ProvidedParameterInfo[] = - match box xs with - | Null -> [| |] - | _ -> xs |> Array.map (ProvidedParameterInfo.CreateNonNull ctxt) + static member CreateArray ctxt (xs: ParameterInfo ProvidedArray) : ProvidedParameterInfo ProvidedArray = + xs |> ProvidedArray.map (ProvidedParameterInfo.CreateNonNull ctxt) interface IProvidedCustomAttributeProvider with member _.GetHasTypeProviderEditorHideMethodsAttribute provider = @@ -712,7 +709,7 @@ type ProvidedMethodBase (x: MethodBase, ctxt) = static member TaintedEquals (pt1: Tainted, pt2: Tainted) = Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle)) - member _.GetStaticParametersForMethod(provider: ITypeProvider) : ProvidedParameterInfo[] = + member _.GetStaticParametersForMethod(provider: ITypeProvider) : ProvidedParameterInfo ProvidedArray = let bindingFlags = BindingFlags.Instance ||| BindingFlags.NonPublic ||| BindingFlags.Public let staticParams = @@ -731,7 +728,7 @@ type ProvidedMethodBase (x: MethodBase, ctxt) = with err -> raise (StripException (StripException err)) !!paramsAsObj :?> ParameterInfo[] - staticParams |> ProvidedParameterInfo.CreateArrayNonNull ctxt + staticParams |> ProvidedParameterInfo.CreateArray ctxt member _.ApplyStaticArgumentsForMethod(provider: ITypeProvider, fullNameAfterArguments: string, staticArgs: objnull[]) = let bindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.InvokeMethod @@ -778,10 +775,8 @@ type ProvidedFieldInfo (x: FieldInfo, ctxt) = | Null -> null | NonNull x -> ProvidedFieldInfo (x, ctxt) - static member CreateArray ctxt (xs: FieldInfo[] MaybeNull) : ProvidedFieldInfo[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedFieldInfo.CreateNonNull ctxt) + static member CreateArray ctxt (xs: FieldInfo ProvidedArray) : ProvidedFieldInfo ProvidedArray = + xs |> ProvidedArray.map (ProvidedFieldInfo.CreateNonNull ctxt) member _.IsInitOnly = x.IsInitOnly @@ -791,7 +786,7 @@ type ProvidedFieldInfo (x: FieldInfo, ctxt) = member _.IsLiteral = x.IsLiteral - member _.GetRawConstantValue() = x.GetRawConstantValue() + member _.GetRawConstantValue() : objnull = x.GetRawConstantValue() /// FieldInfo.FieldType cannot be null @@ -834,10 +829,8 @@ type ProvidedMethodInfo (x: MethodInfo, ctxt) = | NonNull x -> ProvidedMethodInfo (x, ctxt) - static member CreateArray ctxt (xs: MethodInfo[] MaybeNull) : ProvidedMethodInfo[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedMethodInfo.CreateNonNull ctxt) + static member CreateArray ctxt (xs: MethodInfo ProvidedArray) : ProvidedMethodInfo ProvidedArray = + xs |> ProvidedArray.map (ProvidedMethodInfo.CreateNonNull ctxt) member _.Handle = x @@ -874,10 +867,8 @@ type ProvidedPropertyInfo (x: PropertyInfo, ctxt) = | Null -> null | NonNull x -> ProvidedPropertyInfo (x, ctxt) - static member CreateArray ctxt (xs: PropertyInfo[] MaybeNull) : ProvidedPropertyInfo[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedPropertyInfo.CreateNonNull ctxt) + static member CreateArray ctxt (xs: PropertyInfo ProvidedArray) : ProvidedPropertyInfo ProvidedArray = + xs |> ProvidedArray.map (ProvidedPropertyInfo.CreateNonNull ctxt) member _.Handle = x @@ -914,10 +905,8 @@ type ProvidedEventInfo (x: EventInfo, ctxt) = | Null -> null | NonNull x -> ProvidedEventInfo (x, ctxt) - static member CreateArray ctxt (xs: EventInfo[] MaybeNull) : ProvidedEventInfo[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedEventInfo.CreateNonNull ctxt) + static member CreateArray ctxt (xs: EventInfo ProvidedArray) : ProvidedEventInfo ProvidedArray = + xs |> ProvidedArray.map (ProvidedEventInfo.CreateNonNull ctxt) member _.Handle = x @@ -947,10 +936,8 @@ type ProvidedConstructorInfo (x: ConstructorInfo, ctxt) = | Null -> null | NonNull x -> ProvidedConstructorInfo (x, ctxt) - static member CreateArray ctxt (xs: ConstructorInfo[] MaybeNull) : ProvidedConstructorInfo[] MaybeNull = - match xs with - | Null -> null - | NonNull xs -> xs |> Array.map (ProvidedConstructorInfo.CreateNonNull ctxt) + static member CreateArray ctxt (xs: ConstructorInfo ProvidedArray) : ProvidedConstructorInfo ProvidedArray = + xs |> ProvidedArray.map (ProvidedConstructorInfo.CreateNonNull ctxt) member _.Handle = x @@ -959,19 +946,19 @@ type ProvidedConstructorInfo (x: ConstructorInfo, ctxt) = override _.GetHashCode() = assert false; x.GetHashCode() type ProvidedExprType = - | ProvidedNewArrayExpr of ProvidedType * ProvidedExpr[] - | ProvidedNewObjectExpr of ProvidedConstructorInfo * ProvidedExpr[] + | ProvidedNewArrayExpr of ProvidedType * ProvidedExpr ProvidedArray + | ProvidedNewObjectExpr of ProvidedConstructorInfo * ProvidedExpr ProvidedArray | ProvidedWhileLoopExpr of ProvidedExpr * ProvidedExpr - | ProvidedNewDelegateExpr of ProvidedType * ProvidedVar[] * ProvidedExpr + | ProvidedNewDelegateExpr of ProvidedType * ProvidedVar ProvidedArray * ProvidedExpr | ProvidedForIntegerRangeLoopExpr of ProvidedVar * ProvidedExpr * ProvidedExpr * ProvidedExpr | ProvidedSequentialExpr of ProvidedExpr * ProvidedExpr | ProvidedTryWithExpr of ProvidedExpr * ProvidedVar * ProvidedExpr * ProvidedVar * ProvidedExpr | ProvidedTryFinallyExpr of ProvidedExpr * ProvidedExpr | ProvidedLambdaExpr of ProvidedVar * ProvidedExpr - | ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr[] + | ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr ProvidedArray | ProvidedConstantExpr of objnull * ProvidedType | ProvidedDefaultExpr of ProvidedType - | ProvidedNewTupleExpr of ProvidedExpr[] + | ProvidedNewTupleExpr of ProvidedExpr ProvidedArray | ProvidedTupleGetExpr of ProvidedExpr * int | ProvidedTypeAsExpr of ProvidedExpr * ProvidedType | ProvidedTypeTestExpr of ProvidedExpr * ProvidedType @@ -987,13 +974,13 @@ type ProvidedExprType = #endif type ProvidedExpr (x: Expr, ctxt) = - member _.Type = x.Type |> ProvidedType.Create ctxt + member _.Type = x.Type |> ProvidedType.CreateNonNull ctxt member _.Handle = x member _.Context = ctxt - member _.UnderlyingExpressionString = x.ToString() + member _.UnderlyingExpressionString = string (x.ToString()) member _.GetExprType() = match x with @@ -1062,7 +1049,7 @@ type ProvidedExpr (x: Expr, ctxt) = [] #endif type ProvidedVar (x: Var, ctxt) = - member _.Type = x.Type |> ProvidedType.Create ctxt + member _.Type = x.Type |> ProvidedType.CreateNonNull ctxt member _.Name = x.Name member _.IsMutable = x.IsMutable member _.Handle = x @@ -1171,7 +1158,7 @@ let ValidateProvidedTypeAfterStaticInstantiation(m, st: Tainted, e if String.IsNullOrEmpty memberName then errorR(Error(FSComp.SR.etNullOrEmptyMemberName fullName, m)) else - let miDeclaringType = TryMemberMember(mi, fullName, memberName, "DeclaringType", m, ProvidedType.CreateNoContext(typeof), fun mi -> mi.DeclaringType) + let miDeclaringType = TryMemberMember(mi, fullName, memberName, "DeclaringType", m, (ProvidedType.CreateNoContext(typeof) |> withNull), fun mi -> mi.DeclaringType) match miDeclaringType with // Generated nested types may have null DeclaringType | Tainted.Null when mi.OfType().IsSome -> () @@ -1261,7 +1248,7 @@ let ValidateProvidedTypeDefinition(m, st: Tainted, expectedPath: s | -1 -> () | n -> errorR(Error(FSComp.SR.etIllegalCharactersInTypeName(string expectedName[n], expectedName), m)) - let staticParameters : Tainted = st.PApplyWithProvider((fun (st, provider) -> st.GetStaticParameters provider), range=m) + let staticParameters = st.PApplyWithProvider((fun (st, provider) -> st.GetStaticParameters provider), range=m) if staticParameters.PUntaint((fun a -> (nonNull a).Length), m) = 0 then ValidateProvidedTypeAfterStaticInstantiation(m, st, expectedPath, expectedName) @@ -1280,7 +1267,7 @@ let ResolveProvidedType (resolver: Tainted, m, moduleOrNamespace: // Check if the provided namespace name is an exact match of the required namespace name if displayName = providedNamespaceName then - let resolvedType = providedNamespace.PApply((fun providedNamespace -> ProvidedType.CreateNoContext(providedNamespace.ResolveTypeName typeName)), range=m) + let resolvedType = providedNamespace.PApply((fun providedNamespace -> ProvidedType.Create ProvidedTypeContext.Empty (providedNamespace.ResolveTypeName typeName)), range=m) match resolvedType with | Tainted.Null -> None | Tainted.NonNull result -> @@ -1341,7 +1328,8 @@ let TryApplyProvidedMethod(methBeforeArgs: Tainted, staticAr else let mangledName = let nm = methBeforeArgs.PUntaint((fun x -> x.Name), m) - let staticParams = methBeforeArgs.PApplyWithProvider((fun (mb, resolver) -> mb.GetStaticParametersForMethod resolver), range=m) + let staticParams = + methBeforeArgs.PApplyWithProvider((fun (mb, resolver) -> mb.GetStaticParametersForMethod resolver |> nonNull), range=m) let mangledName = ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams, m) mangledName match methBeforeArgs.PApplyWithProvider((fun (mb, provider) -> mb.ApplyStaticArgumentsForMethod(provider, mangledName, staticArgs)), range=m) with @@ -1367,7 +1355,7 @@ let TryApplyProvidedType(typeBeforeArguments: Tainted, optGenerate // Otherwise, use the full path of the erased type, including mangled arguments let nm = typeBeforeArguments.PUntaint((fun x -> x.Name), m) let enc, _ = ILPathToProvidedType (typeBeforeArguments, m) - let staticParams : Tainted = typeBeforeArguments.PApplyWithProvider((fun (st, resolver) -> st.GetStaticParameters resolver |> nonNull), range=m) + let staticParams = typeBeforeArguments.PApplyWithProvider((fun (st, resolver) -> st.GetStaticParameters resolver |> nonNull), range=m) let mangledName = ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams, m) enc @ [ mangledName ] diff --git a/src/Compiler/TypedTree/TypeProviders.fsi b/src/Compiler/TypedTree/TypeProviders.fsi index c99f2ab3775..b8ec2158ea4 100755 --- a/src/Compiler/TypedTree/TypeProviders.fsi +++ b/src/Compiler/TypedTree/TypeProviders.fsi @@ -15,6 +15,7 @@ open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.Text type TypeProviderDesignation = TypeProviderDesignation of string +type 'a ProvidedArray= ('a[]) MaybeNull /// Raised when a type provider has thrown an exception. exception ProvidedTypeResolution of range * exn @@ -104,41 +105,41 @@ type ProvidedType = member IsGenericType: bool - member Namespace: string + member Namespace: string MaybeNull - member FullName: string + member FullName: string MaybeNull member IsArray: bool - member GetInterfaces: unit -> ProvidedType[] + member GetInterfaces: unit -> ProvidedType ProvidedArray - member Assembly: ProvidedAssembly + member Assembly: ProvidedAssembly MaybeNull member BaseType: ProvidedType MaybeNull - member GetNestedType: string -> ProvidedType + member GetNestedType: string -> ProvidedType MaybeNull - member GetNestedTypes: unit -> ProvidedType[] + member GetNestedTypes: unit -> ProvidedType ProvidedArray - member GetAllNestedTypes: unit -> ProvidedType[] + member GetAllNestedTypes: unit -> ProvidedType ProvidedArray - member GetMethods: unit -> ProvidedMethodInfo[] + member GetMethods: unit -> ProvidedMethodInfo ProvidedArray - member GetFields: unit -> ProvidedFieldInfo[] + member GetFields: unit -> ProvidedFieldInfo ProvidedArray - member GetField: string -> ProvidedFieldInfo + member GetField: string -> ProvidedFieldInfo MaybeNull - member GetProperties: unit -> ProvidedPropertyInfo[] + member GetProperties: unit -> ProvidedPropertyInfo ProvidedArray - member GetProperty: string -> ProvidedPropertyInfo + member GetProperty: string -> ProvidedPropertyInfo MaybeNull - member GetEvents: unit -> ProvidedEventInfo[] + member GetEvents: unit -> ProvidedEventInfo ProvidedArray - member GetEvent: string -> ProvidedEventInfo + member GetEvent: string -> ProvidedEventInfo MaybeNull - member GetConstructors: unit -> ProvidedConstructorInfo[] + member GetConstructors: unit -> ProvidedConstructorInfo ProvidedArray - member GetStaticParameters: ITypeProvider -> ProvidedParameterInfo[] + member GetStaticParameters: ITypeProvider -> ProvidedParameterInfo ProvidedArray member GetGenericTypeDefinition: unit -> ProvidedType @@ -170,9 +171,9 @@ type ProvidedType = member GenericParameterPosition: int - member GetElementType: unit -> ProvidedType + member GetElementType: unit -> ProvidedType MaybeNull - member GetGenericArguments: unit -> ProvidedType[] + member GetGenericArguments: unit -> ProvidedType ProvidedArray member GetArrayRank: unit -> int @@ -275,11 +276,11 @@ type ProvidedMethodBase = member IsConstructor: bool - member GetParameters: unit -> ProvidedParameterInfo[] + member GetParameters: unit -> ProvidedParameterInfo ProvidedArray - member GetGenericArguments: unit -> ProvidedType[] + member GetGenericArguments: unit -> ProvidedType ProvidedArray - member GetStaticParametersForMethod: ITypeProvider -> ProvidedParameterInfo[] + member GetStaticParametersForMethod: ITypeProvider -> ProvidedParameterInfo ProvidedArray static member TaintedGetHashCode: Tainted -> int @@ -335,7 +336,7 @@ type ProvidedFieldInfo = member IsLiteral: bool - member GetRawConstantValue: unit -> obj + member GetRawConstantValue: unit -> objnull member FieldType: ProvidedType @@ -359,11 +360,11 @@ type ProvidedPropertyInfo = inherit ProvidedMemberInfo - member GetGetMethod: unit -> ProvidedMethodInfo + member GetGetMethod: unit -> ProvidedMethodInfo MaybeNull - member GetSetMethod: unit -> ProvidedMethodInfo + member GetSetMethod: unit -> ProvidedMethodInfo MaybeNull - member GetIndexParameters: unit -> ProvidedParameterInfo[] + member GetIndexParameters: unit -> ProvidedParameterInfo ProvidedArray member CanRead: bool @@ -383,9 +384,9 @@ type ProvidedEventInfo = inherit ProvidedMemberInfo - member GetAddMethod: unit -> ProvidedMethodInfo + member GetAddMethod: unit -> ProvidedMethodInfo MaybeNull - member GetRemoveMethod: unit -> ProvidedMethodInfo + member GetRemoveMethod: unit -> ProvidedMethodInfo MaybeNull member EventHandlerType: ProvidedType @@ -402,13 +403,13 @@ type ProvidedConstructorInfo = type ProvidedExprType = - | ProvidedNewArrayExpr of ProvidedType * ProvidedExpr[] + | ProvidedNewArrayExpr of ProvidedType * ProvidedExpr ProvidedArray - | ProvidedNewObjectExpr of ProvidedConstructorInfo * ProvidedExpr[] + | ProvidedNewObjectExpr of ProvidedConstructorInfo * ProvidedExpr ProvidedArray | ProvidedWhileLoopExpr of ProvidedExpr * ProvidedExpr - | ProvidedNewDelegateExpr of ProvidedType * ProvidedVar[] * ProvidedExpr + | ProvidedNewDelegateExpr of ProvidedType * ProvidedVar ProvidedArray * ProvidedExpr | ProvidedForIntegerRangeLoopExpr of ProvidedVar * ProvidedExpr * ProvidedExpr * ProvidedExpr @@ -420,13 +421,13 @@ type ProvidedExprType = | ProvidedLambdaExpr of ProvidedVar * ProvidedExpr - | ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr[] + | ProvidedCallExpr of ProvidedExpr option * ProvidedMethodInfo * ProvidedExpr ProvidedArray - | ProvidedConstantExpr of obj * ProvidedType + | ProvidedConstantExpr of objnull * ProvidedType | ProvidedDefaultExpr of ProvidedType - | ProvidedNewTupleExpr of ProvidedExpr[] + | ProvidedNewTupleExpr of ProvidedExpr ProvidedArray | ProvidedTupleGetExpr of ProvidedExpr * int @@ -467,12 +468,10 @@ type ProvidedVar = member IsMutable: bool - override Equals: obj -> bool - override GetHashCode: unit -> int /// Get the provided expression for a particular use of a method. -val GetInvokerExpression: ITypeProvider * ProvidedMethodBase * ProvidedVar[] -> ProvidedExpr +val GetInvokerExpression: ITypeProvider * ProvidedMethodBase * ProvidedVar[] -> ProvidedExpr MaybeNull /// Validate that the given provided type meets some of the rules for F# provided types val ValidateProvidedTypeAfterStaticInstantiation: @@ -497,7 +496,7 @@ val TryLinkProvidedType: Tainted * string[] * typeLogicalName: string * range: range -> Tainted option /// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed. -val GetProvidedNamespaceAsPath: range * Tainted * string -> string list +val GetProvidedNamespaceAsPath: range * Tainted * string MaybeNull -> string list /// Decompose the enclosing name of a type (including any class nestings) into a list of parts. /// e.g. System.Object -> ["System"; "Object"] diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index 27e80d396be..817730ec6ea 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -5588,7 +5588,7 @@ type NamedDebugPointKey = override x.GetHashCode() = hash x.Name + hash x.Range - override x.Equals(yobj: obj) = + override x.Equals(yobj: objnull) = match yobj with | :? NamedDebugPointKey as y -> Range.equals x.Range y.Range && x.Name = y.Name | _ -> false diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index 82a0a8d84c4..28ef5776e5a 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -3149,7 +3149,7 @@ type TType = /// For now, used only as a discriminant in error message. /// See https://github.com/dotnet/fsharp/issues/2561 - member GetAssemblyName: unit -> string MaybeNull + member GetAssemblyName: unit -> string override ToString: unit -> string @@ -4050,8 +4050,6 @@ type NamedDebugPointKey = interface IComparable - override Equals: yobj: obj -> bool - override GetHashCode: unit -> int /// Represents a complete typechecked implementation file, including its inferred or explicit signature. diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index ebe42db34fe..f83e48a7c8f 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -979,15 +979,26 @@ let stripMeasuresFromTy g ty = [] type TypeEquivEnv = { EquivTypars: TyparMap - EquivTycons: TyconRefRemap} + EquivTycons: TyconRefRemap + NullnessMustEqual : bool} + +let private nullnessEqual anev (n1:Nullness) (n2:Nullness) = + if anev.NullnessMustEqual then + (n1.Evaluate() = NullnessInfo.WithNull) = (n2.Evaluate() = NullnessInfo.WithNull) + else + true // allocate a singleton -let typeEquivEnvEmpty = +let private typeEquivEnvEmpty = { EquivTypars = TyparMap.Empty - EquivTycons = emptyTyconRefRemap } + EquivTycons = emptyTyconRefRemap + NullnessMustEqual = false} + +let private typeEquivCheckNullness = {typeEquivEnvEmpty with NullnessMustEqual = true} type TypeEquivEnv with - static member Empty = typeEquivEnvEmpty + static member EmptyIgnoreNulls = typeEquivEnvEmpty + static member EmptyWithNullChecks (g:TcGlobals) = if g.checkNullness then typeEquivCheckNullness else typeEquivEnvEmpty member aenv.BindTyparsToTypes tps1 tys2 = { aenv with EquivTypars = (tps1, tys2, aenv.EquivTypars) |||> List.foldBack2 (fun tp ty tpmap -> tpmap.Add(tp, ty)) } @@ -995,12 +1006,15 @@ type TypeEquivEnv with member aenv.BindEquivTypars tps1 tps2 = aenv.BindTyparsToTypes tps1 (List.map mkTyparTy tps2) - static member FromTyparInst tpinst = + member aenv.FromTyparInst tpinst = let tps, tys = List.unzip tpinst - TypeEquivEnv.Empty.BindTyparsToTypes tps tys + aenv.BindTyparsToTypes tps tys + + member aenv.FromEquivTypars tps1 tps2 = + aenv.BindEquivTypars tps1 tps2 - static member FromEquivTypars tps1 tps2 = - TypeEquivEnv.Empty.BindEquivTypars tps1 tps2 + member anev.ResetEquiv = + if anev.NullnessMustEqual then typeEquivCheckNullness else typeEquivEnvEmpty let rec traitsAEquivAux erasureFlag g aenv traitInfo1 traitInfo2 = let (TTrait(tys1, nm, mf1, argTys, retTy, _, _)) = traitInfo1 @@ -1081,16 +1095,18 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | TType_forall(tps1, rty1), TType_forall(tps2, retTy2) -> typarsAEquivAux erasureFlag g aenv tps1 tps2 && typeAEquivAux erasureFlag g (aenv.BindEquivTypars tps1 tps2) rty1 retTy2 - | TType_var (tp1, _), TType_var (tp2, _) when typarEq tp1 tp2 -> // NOTE: nullness annotations are ignored for type equivalence - true + | TType_var (tp1, n1), TType_var (tp2, n2) when typarEq tp1 tp2 -> + nullnessEqual aenv n1 n2 - | TType_var (tp1, _), _ -> + | TType_var (tp1, n1), _ -> match aenv.EquivTypars.TryFind tp1 with - | Some tpTy1 -> typeEquivAux erasureFlag g tpTy1 ty2 + | Some tpTy1 -> + let tpTy1 = if (nullnessEqual aenv n1 g.knownWithoutNull) then tpTy1 else addNullnessToTy n1 tpTy1 + typeAEquivAux erasureFlag g aenv.ResetEquiv tpTy1 ty2 | None -> false - // NOTE: nullness annotations are ignored for type equivalence - | TType_app (tcref1, tinst1, _), TType_app (tcref2, tinst2, _) -> + | TType_app (tcref1, tinst1, n1), TType_app (tcref2, tinst2, n2) -> + nullnessEqual aenv n1 n2 && tcrefAEquiv g aenv tcref1 tcref2 && typesAEquivAux erasureFlag g aenv tinst1 tinst2 @@ -1102,8 +1118,8 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> structnessAEquiv tupInfo1 tupInfo2 && typesAEquivAux erasureFlag g aenv l1 l2 - // NOTE: nullness annotations are ignored for type equivalence - | TType_fun (domainTy1, rangeTy1, _), TType_fun (domainTy2, rangeTy2, _) -> + | TType_fun (domainTy1, rangeTy1, n1), TType_fun (domainTy2, rangeTy2, n2) -> + nullnessEqual aenv n1 n2 && typeAEquivAux erasureFlag g aenv domainTy1 domainTy2 && typeAEquivAux erasureFlag g aenv rangeTy1 rangeTy2 | TType_anon (anonInfo1, l1), TType_anon (anonInfo2, l2) -> @@ -1117,18 +1133,6 @@ and typeAEquivAux erasureFlag g aenv ty1 ty2 = | _ -> false -and nullnessSensitivetypeAEquivAux erasureFlag g aenv ty1 ty2 = - let ty1 = stripTyEqnsWrtErasure erasureFlag g ty1 - let ty2 = stripTyEqnsWrtErasure erasureFlag g ty2 - match ty1, ty2 with - | TType_var (_,n1), TType_var (_,n2) - | TType_app (_,_,n1), TType_app (_,_,n2) - | TType_fun (_,_,n1), TType_fun (_,_,n2) -> - n1 === n2 - | _ -> true - - && typeAEquivAux erasureFlag g aenv ty1 ty2 - and anonInfoEquiv (anonInfo1: AnonRecdTypeInfo) (anonInfo2: AnonRecdTypeInfo) = ccuEq anonInfo1.Assembly anonInfo2.Assembly && structnessAEquiv anonInfo1.TupInfo anonInfo2.TupInfo && @@ -1153,7 +1157,7 @@ and measureAEquiv g aenv un1 un2 = and typesAEquivAux erasureFlag g aenv l1 l2 = List.lengthsEqAndForall2 (typeAEquivAux erasureFlag g aenv) l1 l2 -and typeEquivAux erasureFlag g ty1 ty2 = typeAEquivAux erasureFlag g TypeEquivEnv.Empty ty1 ty2 +and typeEquivAux erasureFlag g ty1 ty2 = typeAEquivAux erasureFlag g TypeEquivEnv.EmptyIgnoreNulls ty1 ty2 let typeAEquiv g aenv ty1 ty2 = typeAEquivAux EraseNone g aenv ty1 ty2 @@ -1169,7 +1173,7 @@ let typarsAEquiv g aenv d1 d2 = typarsAEquivAux EraseNone g aenv d1 d2 let returnTypesAEquiv g aenv t1 t2 = returnTypesAEquivAux EraseNone g aenv t1 t2 -let measureEquiv g m1 m2 = measureAEquiv g TypeEquivEnv.Empty m1 m2 +let measureEquiv g m1 m2 = measureAEquiv g TypeEquivEnv.EmptyIgnoreNulls m1 m2 // Get measure of type, float<_> or float32<_> or decimal<_> but not float=float<1> or float32=float32<1> or decimal=decimal<1> let getMeasureOfType g ty = @@ -2735,7 +2739,7 @@ let GetTraitConstraintInfosOfTypars g (tps: Typars) = match cx with | TyparConstraint.MayResolveMember(traitInfo, _) -> traitInfo | _ -> () ] - |> ListSet.setify (traitsAEquiv g TypeEquivEnv.Empty) + |> ListSet.setify (traitsAEquiv g TypeEquivEnv.EmptyIgnoreNulls) |> List.sortBy (fun traitInfo -> traitInfo.MemberLogicalName, traitInfo.GetCompiledArgumentTypes().Length) /// Get information about the runtime witnesses needed for a set of generalized typars @@ -4862,7 +4866,7 @@ type SignatureRepackageInfo = { RepackagedVals: (ValRef * ValRef) list RepackagedEntities: (TyconRef * TyconRef) list } - member remapInfo.ImplToSigMapping = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } + member remapInfo.ImplToSigMapping g = { TypeEquivEnv.EmptyWithNullChecks g with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities } static member Empty = { RepackagedVals = []; RepackagedEntities= [] } type SignatureHidingInfo = @@ -4988,7 +4992,7 @@ let rec accValRemapFromModuleOrNamespaceType g aenv (mty: ModuleOrNamespaceType) let ComputeRemappingFromInferredSignatureToExplicitSignature g mty msigty = let mrpi, _ as entityRemap = accEntityRemapFromModuleOrNamespaceType mty msigty (SignatureRepackageInfo.Empty, SignatureHidingInfo.Empty) - let aenv = mrpi.ImplToSigMapping + let aenv = mrpi.ImplToSigMapping g let valAndEntityRemap = accValRemapFromModuleOrNamespaceType g aenv mty msigty entityRemap valAndEntityRemap @@ -5051,7 +5055,7 @@ and accValRemapFromModuleOrNamespaceDefs g aenv msigty mdefs acc = List.foldBack let ComputeRemappingFromImplementationToSignature g mdef msigty = let mrpi, _ as entityRemap = accEntityRemapFromModuleOrNamespace msigty mdef (SignatureRepackageInfo.Empty, SignatureHidingInfo.Empty) - let aenv = mrpi.ImplToSigMapping + let aenv = mrpi.ImplToSigMapping g let valAndEntityRemap = accValRemapFromModuleOrNamespace g aenv msigty mdef entityRemap valAndEntityRemap @@ -11436,7 +11440,7 @@ type TraitWitnessInfoHashMap<'T> = ImmutableDictionary let EmptyTraitWitnessInfoHashMap g : TraitWitnessInfoHashMap<'T> = ImmutableDictionary.Create( { new IEqualityComparer<_> with - member _.Equals(a, b) = nullSafeEquality a b (fun a b -> traitKeysAEquiv g TypeEquivEnv.Empty a b) + member _.Equals(a, b) = nullSafeEquality a b (fun a b -> traitKeysAEquiv g TypeEquivEnv.EmptyIgnoreNulls a b) member _.GetHashCode(a) = hash a.MemberName }) diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index 3a4a1ca4c0a..932e465b0e9 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -881,15 +881,17 @@ val stripMeasuresFromTy: TcGlobals -> TType -> TType [] type TypeEquivEnv = { EquivTypars: TyparMap - EquivTycons: TyconRefRemap } + EquivTycons: TyconRefRemap + NullnessMustEqual: bool } - static member Empty: TypeEquivEnv + static member EmptyIgnoreNulls: TypeEquivEnv + static member EmptyWithNullChecks: TcGlobals -> TypeEquivEnv member BindEquivTypars: Typars -> Typars -> TypeEquivEnv - static member FromTyparInst: TyparInstantiation -> TypeEquivEnv + member FromTyparInst: TyparInstantiation -> TypeEquivEnv - static member FromEquivTypars: Typars -> Typars -> TypeEquivEnv + member FromEquivTypars: Typars -> Typars -> TypeEquivEnv val traitsAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TraitConstraintInfo -> TraitConstraintInfo -> bool @@ -907,8 +909,6 @@ val typarsAEquiv: TcGlobals -> TypeEquivEnv -> Typars -> Typars -> bool val typeAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool -val nullnessSensitivetypeAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType -> TType -> bool - val typeAEquiv: TcGlobals -> TypeEquivEnv -> TType -> TType -> bool val returnTypesAEquivAux: Erasure -> TcGlobals -> TypeEquivEnv -> TType option -> TType option -> bool diff --git a/src/Compiler/TypedTree/tainted.fs b/src/Compiler/TypedTree/tainted.fs index d23b5183a53..76a0ba131e4 100644 --- a/src/Compiler/TypedTree/tainted.fs +++ b/src/Compiler/TypedTree/tainted.fs @@ -138,6 +138,12 @@ type internal Tainted<'T> (context: TaintedContext, value: 'T) = | Null -> raise <| TypeProviderError(FSComp.SR.etProviderReturnedNull(methodName), this.TypeProviderDesignation, range) | NonNull a -> a |> Array.map (fun u -> Tainted(context,u)) + member this.PApplyFilteredArray(factory, filter, methodName, range:range) = + let a : 'U[] MaybeNull = this.Protect factory range + match a with + | Null -> raise <| TypeProviderError(FSComp.SR.etProviderReturnedNull(methodName), this.TypeProviderDesignation, range) + | NonNull a -> a |> Array.filter filter |> Array.map (fun u -> Tainted(context,u)) + member this.PApplyOption(f, range: range) = let a = this.Protect f range match a with diff --git a/src/Compiler/TypedTree/tainted.fsi b/src/Compiler/TypedTree/tainted.fsi index 61392794b5f..d066eefd3b2 100644 --- a/src/Compiler/TypedTree/tainted.fsi +++ b/src/Compiler/TypedTree/tainted.fsi @@ -80,6 +80,9 @@ type internal Tainted<'T> = /// Apply an operation that returns an array. Unwrap array. Any exception will be attributed to the type provider with an error located at the given range. String is method name of thing-returning-array, to diagnostically attribute if it is null member PApplyArray: ('T -> 'U[] MaybeNull) * string * range: range -> Tainted<'U>[] + /// Apply an operation that returns an array. Filter the array. Unwrap array. Any exception will be attributed to the type provider with an error located at the given range. String is method name of thing-returning-array, to diagnostically attribute if it is null + member PApplyFilteredArray: ('T -> 'U[] MaybeNull) * ('U -> bool) *string * range: range -> Tainted<'U>[] + /// Apply an operation that returns an option. Unwrap option. Any exception will be attributed to the type provider with an error located at the given range member PApplyOption: ('T -> 'U option) * range: range -> Tainted<'U> option diff --git a/src/Compiler/Utilities/FileSystem.fs b/src/Compiler/Utilities/FileSystem.fs index a541234199e..81d6113cc18 100644 --- a/src/Compiler/Utilities/FileSystem.fs +++ b/src/Compiler/Utilities/FileSystem.fs @@ -431,16 +431,16 @@ module internal FileSystemUtils = let fileNameOfPath path = checkPathForIllegalChars path - Path.GetFileName(path) + !! Path.GetFileName(path) let fileNameWithoutExtensionWithValidate (validate: bool) path = if validate then checkPathForIllegalChars path - Path.GetFileNameWithoutExtension(path) + !! Path.GetFileNameWithoutExtension(path) let fileNameWithoutExtension path = - fileNameWithoutExtensionWithValidate true path + !! fileNameWithoutExtensionWithValidate true path let trimQuotes (path: string) = path.Trim([| ' '; '\"' |]) diff --git a/src/Compiler/Utilities/NullnessShims.fs b/src/Compiler/Utilities/NullnessShims.fs index 785a6c6a3b8..ee801610255 100644 --- a/src/Compiler/Utilities/NullnessShims.fs +++ b/src/Compiler/Utilities/NullnessShims.fs @@ -63,6 +63,14 @@ module internal NullnessShims = #endif +#if NET5_0_OR_GREATER + // Argument type for overriding System.Object.Equals(arg) + // Desktop frameworks as well as netstandard need plain 'obj' and are not annotated, NET5 and higher can use (obj|null) + type objEqualsArg = objnull +#else + type objEqualsArg = obj +#endif + [] let inline (|NonEmptyString|_|) (x: string MaybeNull) = diff --git a/src/Compiler/Utilities/TaggedCollections.fs b/src/Compiler/Utilities/TaggedCollections.fs index 253b38a196d..cb6add28b10 100644 --- a/src/Compiler/Utilities/TaggedCollections.fs +++ b/src/Compiler/Utilities/TaggedCollections.fs @@ -883,7 +883,7 @@ module MapTree = let k3, v3, l' = spliceOutSuccessor mn.Left in k3, v3, mk l' mn.Key mn.Value mn.Right | _ -> m.Key, m.Value, empty - let rec remove (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = + let rec remove (comparer: IComparer<'Key>) (k: 'Key) (m: MapTree<'Key, 'Value>) = if isEmpty m then empty else @@ -905,7 +905,7 @@ module MapTree = rebalance mn.Left mn.Key mn.Value (remove comparer k mn.Right) | _ -> if c = 0 then empty else m - let rec mem (comparer: IComparer<'Key>) k (m: MapTree<'Key, 'Value>) = + let rec mem (comparer: IComparer<'Key>) (k: 'Key) (m: MapTree<'Key, 'Value>) = if isEmpty m then false else @@ -1017,7 +1017,14 @@ module MapTree = let foldBack f m x = foldBackOpt (OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt f) m x - let foldSectionOpt (comparer: IComparer<'Key>) lo hi (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = + let foldSectionOpt + (comparer: IComparer<'Key>) + (lo: 'Key) + (hi: 'Key) + (f: OptimizedClosures.FSharpFunc<_, _, _, _>) + (m: MapTree<'Key, 'Value>) + x + = let rec foldFromTo (f: OptimizedClosures.FSharpFunc<_, _, _, _>) (m: MapTree<'Key, 'Value>) x = if isEmpty m then x diff --git a/src/Compiler/Utilities/TaggedCollections.fsi b/src/Compiler/Utilities/TaggedCollections.fsi index 25552d0d92c..e826f2719b3 100644 --- a/src/Compiler/Utilities/TaggedCollections.fsi +++ b/src/Compiler/Utilities/TaggedCollections.fsi @@ -5,6 +5,7 @@ namespace Internal.Utilities.Collections.Tagged open System open System.Collections.Generic + open Internal.Utilities.Library /// Immutable sets based on binary trees, default tag @@ -114,7 +115,7 @@ namespace Internal.Utilities.Collections.Tagged interface IComparable - override Equals : obj -> bool + override Equals : objEqualsArg -> bool type internal Set<'T> = Set<'T, IComparer<'T>> @@ -218,7 +219,7 @@ namespace Internal.Utilities.Collections.Tagged interface IComparable - override Equals : obj -> bool + override Equals : objEqualsArg -> bool type internal Map<'Key,'Value> = Map<'Key, 'Value, IComparer<'Key>> diff --git a/src/Compiler/Utilities/illib.fs b/src/Compiler/Utilities/illib.fs index 9ed400f3ab8..0f68d92a429 100644 --- a/src/Compiler/Utilities/illib.fs +++ b/src/Compiler/Utilities/illib.fs @@ -206,12 +206,12 @@ module Order = member _.Compare(x, xx) = compare (p !!x) (p !!xx) } - let orderOn p (pxOrder: IComparer<'U>) = + let orderOn (p:'T->'U) (pxOrder: IComparer<'U>) = { new IComparer<'T> with - member _.Compare(x, xx) = pxOrder.Compare(p x, p xx) + member _.Compare(x, xx) = pxOrder.Compare(p !!x, p !!xx) } - let toFunction (pxOrder: IComparer<'U>) x y = pxOrder.Compare(x, y) + let toFunction (pxOrder: IComparer<'U>) (x:'U) (y:'U) = pxOrder.Compare(x, y) //------------------------------------------------------------------------- // Library: arrays, lists, options, resizearrays @@ -796,10 +796,10 @@ module String = elif (!!value).StartsWithOrdinal pattern then Some() else None - let (|Contains|_|) (pattern:string) value = + let (|Contains|_|) (pattern:string) (value:string|null) = match value with - | value when String.IsNullOrWhiteSpace value -> None | null -> None + | value when String.IsNullOrWhiteSpace value -> None | value -> if value.Contains pattern then Some() else None @@ -811,7 +811,7 @@ module String = let mutable line = reader.ReadLine() while not (isNull line) do - yield line + yield (line |> Unchecked.nonNull) line <- reader.ReadLine() if str.EndsWithOrdinal("\n") then diff --git a/src/Compiler/Utilities/illib.fsi b/src/Compiler/Utilities/illib.fsi index 2b23de7de2e..bd9d330cfe4 100644 --- a/src/Compiler/Utilities/illib.fsi +++ b/src/Compiler/Utilities/illib.fsi @@ -94,6 +94,10 @@ module internal Order = #endif val orderOn: p: ('T -> 'U) -> pxOrder: IComparer<'U> -> IComparer<'T> +#if !NO_CHECKNULLS + when 'T:not null + and 'T:not struct +#endif val toFunction: pxOrder: IComparer<'U> -> x: 'U -> y: 'U -> int @@ -280,7 +284,7 @@ module internal String = val (|StartsWith|_|): pattern: string -> value: string -> unit option - val (|Contains|_|): pattern: string -> value: string -> unit option + val (|Contains|_|): pattern: string -> value: string|null -> unit option val getLines: str: string -> string[] diff --git a/src/Compiler/Utilities/lib.fsi b/src/Compiler/Utilities/lib.fsi index cbdb893c5b8..08b834d17c6 100644 --- a/src/Compiler/Utilities/lib.fsi +++ b/src/Compiler/Utilities/lib.fsi @@ -19,7 +19,7 @@ val isEnvVarSet: s: string -> bool val GetEnvInteger: e: string -> dflt: int -> int -val dispose: x: System.IDisposable -> unit +val dispose: x: (System.IDisposable MaybeNull) -> unit module Bits = /// Get the least significant byte of a 32-bit integer diff --git a/src/Compiler/Utilities/range.fs b/src/Compiler/Utilities/range.fs index f9940461a32..5e13752df0b 100755 --- a/src/Compiler/Utilities/range.fs +++ b/src/Compiler/Utilities/range.fs @@ -448,10 +448,22 @@ module Range = let mkFileIndexRange fileIndex startPos endPos = range (fileIndex, startPos, endPos) let posOrder = - Order.orderOn (fun (p: pos) -> p.Line, p.Column) (Pair.order (Int32.order, Int32.order)) + let pairOrder = Pair.order (Int32.order, Int32.order) + let lineAndColumn = fun (p: pos) -> p.Line, p.Column + + { new IComparer with + member _.Compare(x, xx) = + pairOrder.Compare(lineAndColumn x, lineAndColumn xx) + } let rangeOrder = - Order.orderOn (fun (r: range) -> r.FileName, (r.Start, r.End)) (Pair.order (String.order, Pair.order (posOrder, posOrder))) + let tripleOrder = Pair.order (String.order, Pair.order (posOrder, posOrder)) + let fileLineColumn = fun (r: range) -> r.FileName, (r.Start, r.End) + + { new IComparer with + member _.Compare(x, xx) = + tripleOrder.Compare(fileLineColumn x, fileLineColumn xx) + } let outputRange (os: TextWriter) (m: range) = fprintf os "%s%a-%a" m.FileName outputPos m.Start outputPos m.End diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 94d0739a8ce..30a20d94b26 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. Interpolovaný řetězec obsahuje netypové identifikátory. Doporučuje se přidat specifikátory zadaného formátu. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index b24a332b3cb..99eb6f814b6 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. Die interpolierte Zeichenfolge enthält nicht typisierte Bezeichner. Das Hinzufügen typisierter Formatbezeichner wird empfohlen. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 40dbae13a65..5a841603175 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. La cadena interpolada contiene identificadores sin tipo. Se recomienda agregar especificadores de formato con tipo. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 6ee0c6f3dd1..3e98a558168 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. La chaîne interpolée contient des identifiants non typés. L'ajout de spécificateurs de format typés est recommandé. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 95d709d785e..b982714a140 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. La stringa interpolata contiene identificatori non tipizzati. È consigliabile aggiungere identificatori di formato tipizzato. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 8d7e59c2726..3a23712a963 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. 挿入文字列には、型指定されていない識別子が含まれています。型指定された書式指定子を追加することをお勧めします。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index d63fbeba99c..41ad2ce40ab 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. 보간된 문자열은 형식화되지 않은 식별자를 포함합니다. 형식화된 형식 지정자를 추가하는 것이 좋습니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index b34ec2ab246..f7cf199c4f5 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. Ciąg interpolowany zawiera identyfikatory bez typu. Rekomendowane jest dodanie specyfikatorów formatu pisanego. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 04ae53e1fa8..4813c278467 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. A cadeia de caracteres interpolada contém identificadores sem tipo. É recomendável adicionar especificadores de formato com tipo. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 66c68dbe5e0..b1aad1198d9 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. Интерполированная строка содержит нетипизированные идентификаторы. Рекомендуется добавить типизированные описатели формата. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index b6979546951..050ccf6ea95 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. İlişkilendirilmiş dize, türü belirsiz tanımlayıcılar içeriyor. Türü belirtilen biçim belirticiler eklenmesi önerilir. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 2101acb475e..085668fbc09 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. 内插字符串包含非类型化标识符。建议添加类型化格式说明符。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 0a02ec6669c..48f36e86118 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -2,6 +2,16 @@ + + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + Nullness warning: The module contains the field\n {0} \nbut its signature specifies\n {1} \nThe types differ in their nullness annotations + + + + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + Nullness warning: Module '{0}' contains\n {1} \nbut its signature specifies\n {2} \nThe types differ in their nullness annotations + + Interpolated string contains untyped identifiers. Adding typed format specifiers is recommended. 差補字串包含不具類型的識別項。建議新增具類型的格式規範。 diff --git a/src/FSharp.Build/FSharpEmbedResourceText.fs b/src/FSharp.Build/FSharpEmbedResourceText.fs index 061715184de..9af5eaf4d72 100644 --- a/src/FSharp.Build/FSharpEmbedResourceText.fs +++ b/src/FSharp.Build/FSharpEmbedResourceText.fs @@ -288,10 +288,10 @@ open Printf if isNull s then System.Diagnostics.Debug.Assert(false, sprintf ""**RESOURCE ERROR**: Resource token %s does not exist!"" name) #endif - #if BUILDING_WITH_LKG || NO_NULLCHECKING_LIB_SUPPORT - s - #else + #if NULLABLE Unchecked.nonNull s + #else + s #endif @@ -374,7 +374,7 @@ open Printf messageString <- postProcessString messageString createMessageString messageString fmt - static member GetTextOpt(key:string) = GetString(key) |> Option.ofObj + static member GetTextOpt(key:string) : string option = GetString(key) |> Option.ofObj /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines). static member SwallowResourceText with get () = swallowResourceText diff --git a/src/FSharp.Core/fslib-extra-pervasives.fs b/src/FSharp.Core/fslib-extra-pervasives.fs index 8ce025606eb..c0b0bc05a04 100644 --- a/src/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/FSharp.Core/fslib-extra-pervasives.fs @@ -473,7 +473,7 @@ type IProvidedNamespace = abstract GetTypes: unit -> Type array - abstract ResolveTypeName: typeName: string -> Type + abstract ResolveTypeName: typeName: string -> (Type|null) type ITypeProvider = inherit System.IDisposable diff --git a/src/FSharp.Core/fslib-extra-pervasives.fsi b/src/FSharp.Core/fslib-extra-pervasives.fsi index aff5d162b0a..898cb94eb55 100644 --- a/src/FSharp.Core/fslib-extra-pervasives.fsi +++ b/src/FSharp.Core/fslib-extra-pervasives.fsi @@ -509,7 +509,7 @@ namespace Microsoft.FSharp.Core.CompilerServices /// Resolver should return a type called name in namespace NamespaceName or null if the type is unknown. /// /// - abstract ResolveTypeName : typeName: string -> Type + abstract ResolveTypeName : typeName: string -> (Type|null) /// /// Represents an instantiation of a type provider component. diff --git a/src/FSharp.Core/map.fsi b/src/FSharp.Core/map.fsi index 5b982141a34..2fdabdbb29f 100644 --- a/src/FSharp.Core/map.fsi +++ b/src/FSharp.Core/map.fsi @@ -215,7 +215,6 @@ type Map<[] 'Key, [> interface IReadOnlyDictionary<'Key, 'Value> - override Equals: objnull -> bool /// Contains operations for working with values of type . [] diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index 15326559354..17f5a6418b0 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -3587,16 +3587,16 @@ namespace Microsoft.FSharp.Core [] val inline nonNullV : value:Nullable<'T> -> 'T - /// Asserts that the value is non-null. - /// The value to check. - /// True when value is null, false otherwise. + /// Re-types a value into a nullable reference type (|null) + /// The non-nullable value. + /// The same value re-typed as a nullable reference type. [] val inline withNull : value:'T -> 'T | null when 'T : not null and 'T : not struct - /// Asserts that the value is non-null. + /// Wraps a value type into System.Nullable /// In a future revision of nullness support this may be unified with 'withNull'. - /// The value to check. - /// True when value is null, false otherwise. + /// The value to wrap. + /// System.Nullable wrapper of the input argument. [] val inline withNullV : value:'T -> Nullable<'T> #endif diff --git a/src/FSharp.Core/quotations.fsi b/src/FSharp.Core/quotations.fsi index ebb3d1021ef..a01ee58b914 100644 --- a/src/FSharp.Core/quotations.fsi +++ b/src/FSharp.Core/quotations.fsi @@ -187,8 +187,6 @@ type Expr = /// member CustomAttributes: Expr list - override Equals: obj: objnull -> bool - /// Builds an expression that represents getting the address of a value. /// /// The target expression. diff --git a/src/FSharp.Core/set.fsi b/src/FSharp.Core/set.fsi index 1be1ad557df..d60432fcd0b 100644 --- a/src/FSharp.Core/set.fsi +++ b/src/FSharp.Core/set.fsi @@ -234,7 +234,6 @@ type Set<[] 'T when 'T: comparison> = interface System.IComparable interface System.Collections.IStructuralEquatable interface IReadOnlyCollection<'T> - override Equals: objnull -> bool #if NETSTANDARD2_1_OR_GREATER /// Contains methods for compiler use related to sets. diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/HasSignatureWithMissingOverride.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/HasSignatureWithMissingOverride.fs new file mode 100644 index 00000000000..fd383440611 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/HasSignatureWithMissingOverride.fs @@ -0,0 +1,10 @@ +module SignatureWithMissingOverride + +type MyCollection(count:int) = + member _.Count =count + // This changes nullable annotation from nullable to non-nullable + override _.ToString() : string = "MyCollection" + // This does not change anything + override _.GetHashCode() = 0 + // This must keep the inferred argument as nullable obj! + override _.Equals(obj) = false \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/HasSignatureWithMissingOverride.fsi b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/HasSignatureWithMissingOverride.fsi new file mode 100644 index 00000000000..f633d1de875 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/HasSignatureWithMissingOverride.fsi @@ -0,0 +1,5 @@ +module SignatureWithMissingOverride +[] +type MyCollection = + member Count : int + override ToString: unit -> string \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs index bc2bcbf9154..e517c97f507 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/NullnessMetadata.fs @@ -9,14 +9,18 @@ open FSharp.Test.Compiler module NullnessMetadata = type Optimize = Optimize | DoNotOptimize - let verifyCompilation (o:Optimize) compilation = + let addOptions (o:Optimize) compilation = compilation |> withOptions ["--checknulls"] |> (match o with | Optimize -> withOptimize | DoNotOptimize -> withNoOptimize) |> withNoDebug |> withNoInterfaceData |> withNoOptimizationData - |> asLibrary + |> asLibrary + + let verifyCompilation (o:Optimize) compilation = + compilation + |> addOptions o |> verifyILBaseline [] @@ -123,6 +127,20 @@ module NullnessMetadata = |> withNoWarn 52 |> verifyCompilation DoNotOptimize + [] + let ``Override missing in signature`` () = + FsFromPath (__SOURCE_DIRECTORY__ ++ "HasSignatureWithMissingOverride.fsi") + |> withAdditionalSourceFile (SourceFromPath (__SOURCE_DIRECTORY__ ++ "HasSignatureWithMissingOverride.fs")) + |> withNoWarn 52 + |> addOptions DoNotOptimize + |> compile + |> withILContains + [".method public hidebysig virtual instance string ToString() cil managed" + ".method public hidebysig virtual instance int32 GetHashCode() cil managed" + "hidebysig virtual instance bool Equals(object obj) cil managed" + ] + |> shouldSucceed + [] let ``Downcasting and typetests`` compilation = compilation diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs index e6398675a01..9bf4730e404 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableRegressionTests.fs @@ -28,6 +28,46 @@ let ``Micro compilation`` langVersion checknulls = |> compile |> shouldSucceed +[] +[] +let ``Signature conformance`` langVersion checknulls = + + FsFromPath (__SOURCE_DIRECTORY__ ++ "signatures.fsi") + |> withAdditionalSourceFile (SourceFromPath (__SOURCE_DIRECTORY__ ++ "signatures.fs")) + |> withLangVersion langVersion + |> fun x -> + if checknulls then + x |> withCheckNulls |> withDefines ["CHECKNULLS"] + else x + |> compile + |> shouldFail + |> withDiagnostics + [(Warning 3261, Line 4, Col 5, Line 4, Col 10, "Nullness warning: Module 'M' contains + val test2: x: string | null -> unit + but its signature specifies + val test2: string -> unit + The types differ in their nullness annotations"); + (Warning 3261, Line 3, Col 5, Line 3, Col 10, "Nullness warning: Module 'M' contains + val test1: x: string -> unit + but its signature specifies + val test1: string | null -> unit + The types differ in their nullness annotations"); + (Warning 3261, Line 6, Col 5, Line 6, Col 17, "Nullness warning: Module 'M' contains + val iRejectNulls: x: string | null -> string + but its signature specifies + val iRejectNulls: string -> string + The types differ in their nullness annotations"); + (Warning 3261, Line 14, Col 14, Line 14, Col 21, "Nullness warning: Module 'M' contains + member GenericContainer.GetNull: unit -> 'T + but its signature specifies + member GenericContainer.GetNull: unit -> 'T | null + The types differ in their nullness annotations"); + (Warning 3261, Line 15, Col 14, Line 15, Col 24, "Nullness warning: Module 'M' contains + member GenericContainer.GetNotNull: unit -> 'T | null + but its signature specifies + member GenericContainer.GetNotNull: unit -> 'T + The types differ in their nullness annotations")] + [] let ``Existing positive v8 disabled`` compilation = compilation diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs index a0027c2d0a9..191d1d0f274 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fs @@ -10,4 +10,4 @@ let isNotNull (value: 'T) = let s: System.String | null = null #else let s: System.String = null -#endif \ No newline at end of file +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi index 25271ae6d7e..a397a9fb162 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/micro.fsi @@ -1,3 +1,3 @@ module M -val isNotNull: value: 'T -> bool when 'T : null \ No newline at end of file +val isNotNull: value: 'T -> bool when 'T : null diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/signatures.fs b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/signatures.fs new file mode 100644 index 00000000000..ebff7bf03f8 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/signatures.fs @@ -0,0 +1,18 @@ +module M + +let test1 (x: string) = () +let test2 (x: string | null) = () + +let iRejectNulls (x:_|null) = + match x with + | null -> "null" + | s -> String.length s |> string + +type GenericContainer<'T when 'T:not null and 'T:not struct>(x:'T) = + let innerVal = x + + member _.GetNull() : ('T) = x + member _.GetNotNull() : ('T|null) = null + +let private GetString(key:string) : string = key + "" +let GetTextOpt(key:string) = GetString(key) |> Option.ofObj \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/Nullness/signatures.fsi b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/signatures.fsi new file mode 100644 index 00000000000..42247ec7115 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/Nullness/signatures.fsi @@ -0,0 +1,15 @@ +module M + +val test1: string | null -> unit +val test2: string -> unit + + +val iRejectNulls: string -> string + +[] +type GenericContainer<'T when 'T:not null and 'T:not struct> = + + member GetNull : unit -> ('T|null) + member GetNotNull: unit -> 'T + +val GetTextOpt: key:string -> string option diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 1c9fca26592..c6346cb30f2 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1300,7 +1300,8 @@ Actual: | Some p -> match ILChecker.verifyILAndReturnActual [] p expected with | true, _, _ -> result - | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput {Outcome = NoExitCode; StdOut = errorMsg; StdErr = "" })} ) + | false, errorMsg, _actualIL -> + CompilationResult.Failure( {s with Output = Some (ExecutionOutput {Outcome = NoExitCode; StdOut = errorMsg; StdErr = ""})} ) | CompilationResult.Failure f -> printfn "Failure:" printfn $"{f}" @@ -1584,11 +1585,15 @@ Actual: if not (List.exists (fun (el: ErrorInfo) -> (getErrorNumber el.Error) = exp) source) then failwith (sprintf "Mismatch in ErrorNumber, expected '%A' was not found during compilation.\nAll errors:\n%A" exp (List.map getErrorInfo source)) + let consequtiveWhiteSpaceTrimmer = new Regex(@"(\r\n|\n|\ |\t)(\ )+") + let trimExtraSpaces s = consequtiveWhiteSpaceTrimmer.Replace(s,"$1") + let private assertErrors (what: string) libAdjust (source: ErrorInfo list) (expected: ErrorInfo list) : unit = // (Error 67, Line 14, Col 3, Line 14, Col 24, "This type test or downcast will always hold") let errorMessage error = let { Error = err; Range = range; Message = message } = error + let message = trimExtraSpaces message let errorType = match err with | ErrorType.Error n -> $"Error {n}" diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl index 60c5f6e4b5f..c2263a4f259 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl @@ -21,14 +21,14 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-788::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-789::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::getCompilerOption([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)][offset 0x000000E6][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::AddPathMapping([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string)][offset 0x0000000B][found Char] Unexpected type on the stack. @@ -59,7 +59,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index 1e0df962a05..18045d70b31 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -28,18 +28,18 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-788::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-789::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack. [IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@110::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x00000059][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000DA][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-6::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000605][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Symbols+fullName@2495-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000011][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. @@ -81,10 +81,10 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL+parseNamed@5291::Invoke([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>, int32, int32)][offset 0x00000087][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.Collections.Utils::shortPath(string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@321::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment+probePathForDotnetHost@322::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000028][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+Pipe #6 input at line 68@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>>)][offset 0x0000034D][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000CD][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000037][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000043][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl index bc7e03d8154..b01f7e04acb 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl @@ -21,13 +21,13 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-832::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-833::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. @@ -85,7 +85,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index 88e5b423f24..e093fab1d7d 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -28,17 +28,17 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000032][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3510-832::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3516-833::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001C7][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x00000024][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2205::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000BB][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1423-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000620][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Symbols+fullName@2495-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack. @@ -108,10 +108,10 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseNamed@5290(uint8[], [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1>, int32, int32)][offset 0x0000007E][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.Collections.Utils::shortPath(string)][offset 0x00000016][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@320([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : Internal.Utilities.FSharpEnvironment::probePathForDotnetHost@321([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x0000002A][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.SimulatedMSBuildReferenceResolver+SimulatedMSBuildResolver@68::FSharp.Compiler.CodeAnalysis.ILegacyReferenceResolver.Resolve([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyResolutionEnvironment, [S.P.CoreLib]System.Tuple`2[], string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, string, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, string, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>>)][offset 0x000002F5][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.DiagnosticsLogger::.cctor()][offset 0x000000B6][found Char] Unexpected type on the stack. -[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@546::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. +[IL]: Error [CallVirtOnValueType]: : FSharp.Compiler.Text.RangeModule+comparer@558::System.Collections.Generic.IEqualityComparer.GetHashCode([FSharp.Compiler.Service]FSharp.Compiler.Text.Range)][offset 0x00000002] Callvirt on a value type method. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000035][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : Internal.Utilities.PathMapModule::applyDir([FSharp.Compiler.Service]Internal.Utilities.PathMap, string)][offset 0x00000041][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$Internal.Utilities.XmlAdapters::.cctor()][offset 0x0000000A][found Char] Unexpected type on the stack.