diff --git a/README.md b/README.md index 9d478e9758d..b2e95905087 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ For F# 4.1 development - [Windows 7 SDK](http://www.microsoft.com/en-us/download/details.aspx?id=8279) - [Windows 8 SDK](http://msdn.microsoft.com/en-us/windows/desktop/hh852363.aspx) - [Windows 8.1 SDK](http://msdn.microsoft.com/en-us/library/windows/desktop/bg162891.aspx) +- [Windows 10 SDK](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk) ####Contributing diff --git a/build-everything.proj b/build-everything.proj index 7818834e7ed..3210dc49ed6 100644 --- a/build-everything.proj +++ b/build-everything.proj @@ -42,32 +42,32 @@ - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + diff --git a/build.cmd b/build.cmd index 8499758dce8..2dc565d3eb2 100644 --- a/build.cmd +++ b/build.cmd @@ -403,8 +403,8 @@ if '%BUILD_PROTO%' == '1' ( @if ERRORLEVEL 1 echo Error: NGen of proto failed && goto :failure ) -%_msbuildexe% %msbuildflags% build-everything.proj /p:Configuration=%BUILD_CONFIG% %BUILD_DIAG% /p:SIGNTYPE=%BUILD_PUBLICSIGN% -@if ERRORLEVEL 1 echo Error: '%_msbuildexe% %msbuildflags% build-everything.proj /p:Configuration=%BUILD_CONFIG% %BUILD_DIAG% /p:SIGNTYPE=%BUILD_PUBLICSIGN%' failed && goto :failure +%_msbuildexe% %msbuildflags% build-everything.proj /p:Configuration=%BUILD_CONFIG% %BUILD_DIAG% /p:BUILD_PUBLICSIGN=%BUILD_PUBLICSIGN% +@if ERRORLEVEL 1 echo Error: '%_msbuildexe% %msbuildflags% build-everything.proj /p:Configuration=%BUILD_CONFIG% %BUILD_DIAG% /p:BUILD_PUBLICSIGN=%BUILD_PUBLICSIGN%' failed && goto :failure @echo on call src\update.cmd %BUILD_CONFIG_LOWERCASE% -ngen diff --git a/packages.config b/packages.config index 17afb4be70c..15a7bc4a304 100644 --- a/packages.config +++ b/packages.config @@ -18,4 +18,6 @@ + + diff --git a/setup/FSharp.SDK/FSharp.SDK.wixproj b/setup/FSharp.SDK/FSharp.SDK.wixproj index 3814288bc8c..04e76713f4e 100644 --- a/setup/FSharp.SDK/FSharp.SDK.wixproj +++ b/setup/FSharp.SDK/FSharp.SDK.wixproj @@ -5,10 +5,10 @@ $(MSBuildProjectDirectory)\..\.. $(FSharpTreeRoot)\setup - + - + Microsoft.FSharp.SDK da0da41f-0e00-4598-8eee-b29d31b0ca04 @@ -19,7 +19,7 @@ true false - + $(DefineConstants);LocaleCode=$(LocaleCode) $(DefineConstants);LocaleId=$(LocaleId) @@ -30,7 +30,7 @@ $(DefineConstants);FSharpTreeRoot=$(FSharpTreeRoot) $(DefineConstants);NugetPackagesDir=$(NugetPackagesDir) - + WixNetFxExtension @@ -40,28 +40,28 @@ $(BinariesDir)\setup\FSharp.Wix.Extensions.dll - + - + - + - + Microsoft400 - + - + diff --git a/setup/FSharp.SDK/FSharp.SDK.wxs b/setup/FSharp.SDK/FSharp.SDK.wxs index ca798e15ff6..5422fc0db36 100644 --- a/setup/FSharp.SDK/FSharp.SDK.wxs +++ b/setup/FSharp.SDK/FSharp.SDK.wxs @@ -2,40 +2,40 @@ - - - - - + + + + + - + - - - + + + - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/FSharp.SDK/component-groups/Compiler_LangPack.wxs b/setup/FSharp.SDK/component-groups/Compiler_LangPack.wxs index 82e467a8dc4..7c6d57a461c 100644 --- a/setup/FSharp.SDK/component-groups/Compiler_LangPack.wxs +++ b/setup/FSharp.SDK/component-groups/Compiler_LangPack.wxs @@ -2,44 +2,40 @@ - - + + + + + + + + + - - - - - - - - + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/FSharp.SDK/component-groups/Compiler_Redist.wxs b/setup/FSharp.SDK/component-groups/Compiler_Redist.wxs index df3f51a355d..bb933585b38 100644 --- a/setup/FSharp.SDK/component-groups/Compiler_Redist.wxs +++ b/setup/FSharp.SDK/component-groups/Compiler_Redist.wxs @@ -2,160 +2,161 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/FSharp.SDK/component-groups/Runtime_LangPack.wxs b/setup/FSharp.SDK/component-groups/Runtime_LangPack.wxs index 8dc3c0d6bc9..acd7f104fc9 100644 --- a/setup/FSharp.SDK/component-groups/Runtime_LangPack.wxs +++ b/setup/FSharp.SDK/component-groups/Runtime_LangPack.wxs @@ -2,165 +2,164 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/FSharp.SDK/component-groups/Runtime_Redist.wxs b/setup/FSharp.SDK/component-groups/Runtime_Redist.wxs index 89d5a7fdc8f..ad3d364088b 100644 --- a/setup/FSharp.SDK/component-groups/Runtime_Redist.wxs +++ b/setup/FSharp.SDK/component-groups/Runtime_Redist.wxs @@ -2,182 +2,182 @@ - - + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/Swix/Microsoft.FSharp.Dependencies/Files.swr b/setup/Swix/Microsoft.FSharp.Dependencies/Files.swr index 3e3c55b7d0e..bd0094ee811 100644 --- a/setup/Swix/Microsoft.FSharp.Dependencies/Files.swr +++ b/setup/Swix/Microsoft.FSharp.Dependencies/Files.swr @@ -28,4 +28,13 @@ folder "InstallDir:Common7\IDE\CommonExtensions\Microsoft\FSharp" file source="$(PackagesFolder)\Microsoft.VisualFSharp.Msbuild.15.0.1.0.1\lib\net45\Microsoft.Build.Engine.dll" file source="$(PackagesFolder)\Microsoft.VisualFSharp.Msbuild.15.0.1.0.1\lib\net45\Microsoft.Build.Framework.dll" file source="$(PackagesFolder)\Microsoft.VisualFSharp.Msbuild.15.0.1.0.1\lib\net45\Microsoft.Build.Tasks.Core.dll" - file source="$(PackagesFolder)\Microsoft.VisualFSharp.Msbuild.15.0.1.0.1\lib\net45\Microsoft.Build.Utilities.Core.dll" \ No newline at end of file + file source="$(PackagesFolder)\Microsoft.VisualFSharp.Msbuild.15.0.1.0.1\lib\net45\Microsoft.Build.Utilities.Core.dll" + +folder "InstallDir:Common7\IDE\NewScriptItems" + file source="$(BinariesFolder)\setup\resources\NewFileDialog\Script\NewFSharpScriptItems.vsdir" + file source="$(BinariesFolder)\setup\resources\NewFileDialog\Script\Script.fsx" + +folder "InstallDir:Common7\IDE\NewFileItems" + file source="$(BinariesFolder)\setup\resources\NewFileDialog\General\NewFSharpFileItems.vsdir" + file source="$(BinariesFolder)\setup\resources\NewFileDialog\General\File.fs" + file source="$(BinariesFolder)\setup\resources\NewFileDialog\General\Script.fsx" diff --git a/setup/resources/NewFileDialog/General/File.fs b/setup/resources/NewFileDialog/General/File.fs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/setup/resources/NewFileDialog/General/NewFSharpFileItems.vsdir b/setup/resources/NewFileDialog/General/NewFSharpFileItems.vsdir new file mode 100644 index 00000000000..aa817232e40 --- /dev/null +++ b/setup/resources/NewFileDialog/General/NewFSharpFileItems.vsdir @@ -0,0 +1,2 @@ +Script.fsx|{91A04A73-4F2C-4E7C-AD38-C1A68E7DA05C}|#5001|150|#5002|0|#4006|0|Script.fsx +File.fs|{91A04A73-4F2C-4E7C-AD38-C1A68E7DA05C}|#5011|151|#5012|0|#4005|0|File.fs diff --git a/setup/resources/NewFileDialog/General/Script.fsx b/setup/resources/NewFileDialog/General/Script.fsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/setup/resources/NewFileDialog/Script/NewFSharpScriptItems.vsdir b/setup/resources/NewFileDialog/Script/NewFSharpScriptItems.vsdir new file mode 100644 index 00000000000..93acaee2753 --- /dev/null +++ b/setup/resources/NewFileDialog/Script/NewFSharpScriptItems.vsdir @@ -0,0 +1 @@ +Script.fsx|{91A04A73-4F2C-4E7C-AD38-C1A68E7DA05C}|#5001|150|#5002|0|#4006|0|Script.fsx diff --git a/setup/resources/NewFileDialog/Script/Script.fsx b/setup/resources/NewFileDialog/Script/Script.fsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index abddcb1a6ff..f9f6c3b8657 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -25,7 +25,8 @@ - portable + full + portable false prompt $(OtherFlags) --no-jit-optimize diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets index 12be192a518..aaa2e141077 100644 --- a/src/FSharpSource.targets +++ b/src/FSharpSource.targets @@ -24,8 +24,8 @@ true - $(OtherFlags) --delaysign+ - $(OtherFlags) --publicsign+ + $(OtherFlags) --delaysign+ + $(OtherFlags) --publicsign+ $(OtherFlags) --keyfile:"$(FSharpSourcesRoot)\fsharp\msft.pubkey" STRONG_NAME_AND_DELAY_SIGN_FSHARP_COMPILER_WITH_MSFT_KEY;$(DefineConstants) true @@ -35,8 +35,8 @@ - $(OtherFlags) --delaysign+ - $(OtherFlags) --publicsign+ + $(OtherFlags) --delaysign+ + $(OtherFlags) --publicsign+ $(OtherFlags) --keyfile:"$(FSharpSourcesRoot)\fsharp\msft.pubkey" STRONG_NAME_AND_DELAY_SIGN_FSHARP_COMPILER_WITH_MSFT_KEY;$(DefineConstants) true @@ -55,8 +55,8 @@ - $(OtherFlags) --delaysign+ - $(OtherFlags) --publicsign+ + $(OtherFlags) --delaysign+ + $(OtherFlags) --publicsign+ $(OtherFlags) --keyfile:"$(FSharpSourcesRoot)\fsharp\msft.pubkey" STRONG_NAME_AND_DELAY_SIGN_FSHARP_COMPILER_WITH_MSFT_KEY;$(DefineConstants) true diff --git a/src/absil/il.fs b/src/absil/il.fs index f097080bae9..3d8f458ad8f 100755 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -38,8 +38,6 @@ let runningOnMono = let _ = if logging then dprintn "* warning: Il.logging is on" -let isNil x = match x with [] -> true | _ -> false -let nonNil x = match x with [] -> false | _ -> true let int_order = LanguagePrimitives.FastGenericComparer let notlazy v = Lazy.CreateFromValue v @@ -2639,7 +2637,7 @@ let rec rescopeILTypeSpecQuick scoref (tspec:ILTypeSpec) = let tref = tspec.TypeRef let tinst = tspec.GenericArgs let qtref = qrescope_tref scoref tref - if ILList.isEmpty tinst && isNone qtref then + if ILList.isEmpty tinst && Option.isNone qtref then None (* avoid reallocation in the common case *) else match qtref with @@ -4267,14 +4265,14 @@ let resolveILMethodRefWithRescope r td (mref:ILMethodRef) = let nargs = args.Length let nm = mref.Name let possibles = td.Methods.FindByNameAndArity (nm,nargs) - if isNil possibles then failwith ("no method named "+nm+" found in type "+td.Name); + if List.isEmpty possibles then failwith ("no method named " + nm + " found in type " + td.Name) match possibles |> List.filter (fun md -> mref.CallingConv = md.CallingConv && // REVIEW: this uses equality on ILType. For CMOD_OPTIONAL this is not going to be correct - (md.Parameters,mref.ArgTypes) ||> ILList.lengthsEqAndForall2 (fun p1 p2 -> r p1.Type = p2) && + (md.Parameters,mref.ArgTypes) ||> ILList.lengthsEqAndForall2 (fun p1 p2 -> r p1.Type = p2) && // REVIEW: this uses equality on ILType. For CMOD_OPTIONAL this is not going to be correct - r md.Return.Type = mref.ReturnType) with + r md.Return.Type = mref.ReturnType) with | [] -> failwith ("no method named "+nm+" with appropriate argument types found in type "+td.Name) | [mdef] -> mdef | _ -> failwith ("multiple methods named "+nm+" appear with identical argument types in type "+td.Name) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index e25067f7030..abb1c3090ad 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -21,13 +21,8 @@ let (>>>&) (x:int32) (n:int32) = int32 (uint32 x >>> n) let notlazy v = Lazy<_>.CreateFromValue v -let isSome x = match x with None -> false | _ -> true -let isNone x = match x with None -> true | _ -> false -let isNil x = match x with [] -> true | _ -> false -let nonNil x = match x with [] -> false | _ -> true -let isNull (x : 'T) = match (x :> obj) with null -> true | _ -> false -let isNonNull (x : 'T) = match (x :> obj) with null -> false | _ -> true -let nonNull msg x = if isNonNull x then x else failwith ("null: " ^ msg) +let inline isNonNull x = not (isNull x) +let inline nonNull msg x = if isNull x then failwith ("null: " ^ msg) else x let (===) x y = LanguagePrimitives.PhysicalEquality x y //--------------------------------------------------------------------- @@ -438,7 +433,7 @@ module String = else None - let hasPrefix s t = isSome (tryDropPrefix s t) + let hasPrefix s t = Option.isSome (tryDropPrefix s t) let dropPrefix s t = match (tryDropPrefix s t) with Some(res) -> res | None -> failwith "dropPrefix" let dropSuffix s t = match (tryDropSuffix s t) with Some(res) -> res | None -> failwith "dropSuffix" @@ -716,8 +711,8 @@ type LazyWithContext<'T,'ctxt> = funcOrException = box f; findOriginalException = findOriginalException } static member NotLazy(x:'T) : LazyWithContext<'T,'ctxt> = - { value = x; - funcOrException = null; + { value = x + funcOrException = null findOriginalException = id } member x.IsDelayed = (match x.funcOrException with null -> false | :? LazyWithContextFailure -> false | _ -> true) member x.IsForced = (match x.funcOrException with null -> true | _ -> false) diff --git a/src/absil/ilprint.fs b/src/absil/ilprint.fs index b8289f30b0f..6bdbf62c44d 100644 --- a/src/absil/ilprint.fs +++ b/src/absil/ilprint.fs @@ -285,7 +285,7 @@ and goutput_gparam env os (gf: ILGenericParameterDef) = output_parens (output_seq "," (goutput_typ env)) os gf.Constraints and goutput_gparams env os b = - if nonNil b then + if not (List.isEmpty b) then output_string os "<"; output_seq "," (goutput_gparam env) os b; output_string os ">"; () and output_bcc os bcc = diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index 353b3b114d2..2a856e622a9 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -153,9 +153,6 @@ module MemoryMapping = let OPEN_EXISTING = 0x0003 let OPEN_ALWAYS = 0x0004 -let derefByte (p:nativeint) = - NativePtr.read (NativePtr.ofNativeInt p) - type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = inherit BinaryFile() @@ -182,7 +179,7 @@ type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = start + nativeint i override m.ReadByte i = - derefByte (m.Addr i) + Marshal.ReadByte(m.Addr i) override m.ReadBytes i len = let res = Bytes.zeroCreate len @@ -190,29 +187,30 @@ type MemoryMappedFile(hMap: MemoryMapping.HANDLE, start:nativeint) = res override m.ReadInt32 i = - NativePtr.read (NativePtr.ofNativeInt (m.Addr i)) + Marshal.ReadInt32(m.Addr i) override m.ReadUInt16 i = - NativePtr.read (NativePtr.ofNativeInt (m.Addr i)) + uint16(Marshal.ReadInt16(m.Addr i)) member m.Close() = ignore(MemoryMapping.UnmapViewOfFile start) ignore(MemoryMapping.CloseHandle hMap) override m.CountUtf8String i = - let start = m.Addr i + let start = m.Addr i let mutable p = start - while derefByte p <> 0uy do + while Marshal.ReadByte(p) <> 0uy do p <- p + 1n int (p - start) override m.ReadUTF8String i = let n = m.CountUtf8String i -#if FX_RESHAPED_REFLECTION - System.Text.Encoding.UTF8.GetString(NativePtr.ofNativeInt (m.Addr i), n) -#else - new System.String(NativePtr.ofNativeInt (m.Addr i), 0, n, System.Text.Encoding.UTF8) -#endif + System.Runtime.InteropServices.Marshal.PtrToStringAnsi((m.Addr i), n) +//#if FX_RESHAPED_REFLECTION +// System.Text.Encoding.UTF8.GetString(NativePtr.ofNativeInt (m.Addr i), n) +//#else +// new System.String(NativePtr.ofNativeInt (m.Addr i), 0, n, System.Text.Encoding.UTF8) +//#endif //--------------------------------------------------------------------- @@ -1486,7 +1484,7 @@ let dataEndPoints ctxtH = let rva = ctxt.resourcesAddr + offset res := ("manifest resource", rva) :: !res !res - if isNil dataStartPoints then [] + if List.isEmpty dataStartPoints then [] else let methodRVAs = let res = ref [] @@ -2184,7 +2182,7 @@ and seekReadMemberRefAsMethodDataUncached ctxtH (MemberRefAsMspecIdx (numtypars, and seekReadMemberRefAsMethDataNoVarArgs ctxt numtypars idx : MethodData = let (VarArgMethodData(enclTyp, cc, nm, argtys,varargs, retty,minst)) = seekReadMemberRefAsMethodData ctxt numtypars idx - if isSome varargs then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" + if Option.isSome varargs then dprintf "ignoring sentinel and varargs in ILMethodDef token signature" (MethodData(enclTyp, cc, nm, argtys, retty,minst)) and seekReadMethodSpecAsMethodData ctxt numtypars idx = @@ -3987,7 +3985,7 @@ let OpenILModuleReaderAfterReadingAllBytes infile opts = { modul = modul ilAssemblyRefs = ilAssemblyRefs dispose = (fun () -> ClosePdbReader pdb) } - if isNone pdb && succeeded then + if Option.isNone pdb && succeeded then ilModuleReaderCache.Put(key, ilModuleReader) ilModuleReader diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs index ce080f66b52..8f6686f8168 100644 --- a/src/absil/ilreflect.fs +++ b/src/absil/ilreflect.fs @@ -1493,7 +1493,7 @@ let rec buildMethodPass3 cenv tref modB (typB:TypeBuilder) emEnv (mdef : ILMetho | ".cctor" | ".ctor" -> let consB = envGetConsB emEnv mref // Constructors can not have generic parameters - assert isNil mdef.GenericParams + assert List.isEmpty mdef.GenericParams // Value parameters let defineParameter (i,attr,name) = consB.DefineParameterAndLog(i+1,attr,name) mdef.Parameters |> ILList.iteri (emitParameter cenv emEnv defineParameter); diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index 993b78959b7..ffde7e90234 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -772,7 +772,7 @@ and GetTypeDescAsTypeRefIdx cenv (scoref,enc,n) = GetTypeRefAsTypeRefIdx cenv (mkILNestedTyRef (scoref,enc,n)) and GetResolutionScopeAsElem cenv (scoref,enc) = - if isNil enc then + if List.isEmpty enc then match scoref with | ILScopeRef.Local -> (rs_Module, 1) | ILScopeRef.Assembly aref -> (rs_AssemblyRef, GetAssemblyRefAsIdx cenv aref) @@ -1205,16 +1205,16 @@ and GenTypeDefPass2 pidx enc cenv (td:ILTypeDef) = // Add entries to auxiliary mapping tables, e.g. Nested, PropertyMap etc. // Note Nested is organised differntly to the others... - if nonNil enc then + if not (List.isEmpty enc) then AddUnsharedRow cenv TableNames.Nested (UnsharedRow [| SimpleIndex (TableNames.TypeDef, tidx) SimpleIndex (TableNames.TypeDef, pidx) |]) |> ignore let props = td.Properties.AsList - if nonNil props then + if not (List.isEmpty props) then AddUnsharedRow cenv TableNames.PropertyMap (GetTypeDefAsPropertyMapRow cenv tidx) |> ignore let events = td.Events.AsList - if nonNil events then + if not (List.isEmpty events) then AddUnsharedRow cenv TableNames.EventMap (GetTypeDefAsEventMapRow cenv tidx) |> ignore // Now generate or assign index numbers for tables referenced by the maps. @@ -1308,7 +1308,7 @@ let GetMethodRefInfoAsMemberRefIdx cenv env ((_,typ,_,_,_,_,_) as minfo) = FindOrAddSharedRow cenv TableNames.MemberRef (MethodRefInfoAsMemberRefRow cenv env fenv minfo) let GetMethodRefInfoAsMethodRefOrDef isAlwaysMethodDef cenv env ((nm,typ:ILType,cc,args,ret,varargs,genarity) as minfo) = - if isNone varargs && (isAlwaysMethodDef || isTypeLocal typ) then + if Option.isNone varargs && (isAlwaysMethodDef || isTypeLocal typ) then if not typ.IsNominal then failwith "GetMethodRefInfoAsMethodRefOrDef: unexpected local tref-typ" try (mdor_MethodDef, GetMethodRefAsMethodDefIdx cenv (mkILMethRefRaw(typ.TypeRef, cc, nm, genarity, args,ret))) with MethodDefNotFound -> (mdor_MemberRef, GetMethodRefInfoAsMemberRefIdx cenv env minfo) @@ -1623,7 +1623,7 @@ module Codebuf = let adjustments = ref [] while (!remainingReqdFixups <> [] || not !doneLast) do - let doingLast = isNil !remainingReqdFixups + let doingLast = List.isEmpty !remainingReqdFixups let origStartOfNoBranchBlock = !origWhere let newStartOfNoBranchBlock = !newWhere @@ -2076,7 +2076,7 @@ module Codebuf = let mkScopeNode cenv (localSigs: _[]) (startOffset,endOffset,ls: ILLocalDebugMapping list,childScopes) = - if (isNil ls || not cenv.generatePdb) then childScopes + if List.isEmpty ls || not cenv.generatePdb then childScopes else [ { Children= Array.ofList childScopes StartOffset=startOffset @@ -2253,7 +2253,7 @@ let GenILMethodBody mname cenv env (il: ILMethodBody) = let codeSize = code.Length let methbuf = ByteBuffer.Create (codeSize * 3) // Do we use the tiny format? - if ILList.isEmpty il.Locals && il.MaxStack <= 8 && isNil seh && codeSize < 64 then + if ILList.isEmpty il.Locals && il.MaxStack <= 8 && List.isEmpty seh && codeSize < 64 then // Use Tiny format let alignedCodeSize = align 4 (codeSize + 1) let codePadding = (alignedCodeSize - (codeSize + 1)) @@ -2285,7 +2285,7 @@ let GenILMethodBody mname cenv env (il: ILMethodBody) = methbuf.EmitBytes code methbuf.EmitPadding codePadding - if nonNil seh then + if not (List.isEmpty seh) then // Can we use the small exception handling table format? let smallSize = (seh.Length * 12 + 4) let canUseSmall = @@ -2463,7 +2463,7 @@ let rec GetParamAsParamRow cenv _env seq (param: ILParameter) = StringE (GetStringHeapIdxOption cenv param.Name) |] and GenParamPass3 cenv env seq (param: ILParameter) = - if param.IsIn=false && param.IsOut=false && param.IsOptional=false && isNone param.Default && isNone param.Name && isNone param.Marshal + if not param.IsIn && not param.IsOut && not param.IsOptional && Option.isNone param.Default && Option.isNone param.Name && Option.isNone param.Marshal then () else let pidx = AddUnsharedRow cenv TableNames.Param (GetParamAsParamRow cenv env seq param) @@ -2483,7 +2483,7 @@ let GenReturnAsParamRow (returnv : ILReturn) = StringE 0 |] let GenReturnPass3 cenv (returnv: ILReturn) = - if isSome returnv.Marshal || nonNil returnv.CustomAttrs.AsList then + if Option.isSome returnv.Marshal || not (List.isEmpty returnv.CustomAttrs.AsList) then let pidx = AddUnsharedRow cenv TableNames.Param (GenReturnAsParamRow returnv) GenCustomAttrsPass3Or4 cenv (hca_ParamDef,pidx) returnv.CustomAttrs match returnv.Marshal with @@ -2770,7 +2770,7 @@ let rec GenTypeDefPass3 enc cenv (td:ILTypeDef) = match td.Layout with | ILTypeDefLayout.Auto -> () | ILTypeDefLayout.Sequential layout | ILTypeDefLayout.Explicit layout -> - if isSome layout.Pack || isSome layout.Size then + if Option.isSome layout.Pack || Option.isSome layout.Size then AddUnsharedRow cenv TableNames.ClassLayout (UnsharedRow [| UShort (match layout.Pack with None -> uint16 0x0 | Some p -> p) diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index c0cb29b7766..88fa20b8f58 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -205,10 +205,9 @@ let writePortablePdbInfo (fixupSPs:bool) showTimes fpdb (info:PdbData) = let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods let externalRowCounts = getRowCounts info.TableRowCounts let docs = - if info.Documents = null then - Array.empty - else - info.Documents + match info.Documents with + | null -> Array.empty + | _ -> info.Documents let metadata = MetadataBuilder() let serializeDocumentName (name:string) = @@ -251,9 +250,9 @@ let writePortablePdbInfo (fixupSPs:bool) showTimes fpdb (info:PdbData) = info.Methods |> Array.iteri (fun _i minfo -> let docHandle, sequencePointBlob = let sps = - if minfo.SequencePoints = null then - Array.empty - else + match minfo.SequencePoints with + | null -> Array.empty + | _ -> match minfo.Range with | None -> Array.empty | Some (_,_) -> minfo.SequencePoints @@ -266,7 +265,7 @@ let writePortablePdbInfo (fixupSPs:bool) showTimes fpdb (info:PdbData) = | false, _ -> Unchecked.defaultof | true, f -> f - // Return a document that the entire method body is declared within. + // Return a document that the entire method body is declared within. // If part of the method body is in another document returns nil handle. let tryGetSingleDocumentIndex = let mutable singleDocumentIndex = 0 diff --git a/src/fsharp/AttributeChecking.fs b/src/fsharp/AttributeChecking.fs index 661b5ede03d..82c36d3f8fa 100644 --- a/src/fsharp/AttributeChecking.fs +++ b/src/fsharp/AttributeChecking.fs @@ -271,7 +271,7 @@ let private CheckILAttributes g cattrs m = /// Check F# attributes for 'ObsoleteAttribute', 'CompilerMessageAttribute' and 'ExperimentalAttribute', /// returning errors and warnings as data let CheckFSharpAttributes g attribs m = - if isNil attribs then CompleteD + if List.isEmpty attribs then CompleteD else (match TryFindFSharpAttribute g g.attrib_SystemObsolete attribs with | Some(Attrib(_,_,[ AttribStringArg s ],_,_,_,_)) -> @@ -338,12 +338,12 @@ let private CheckProvidedAttributes g m (provAttribs: Tainted @@ -354,13 +354,13 @@ let CheckFSharpAttributesForHidden g attribs = /// Indicate if a list of F# attributes contains 'ObsoleteAttribute'. Used to suppress the item in intellisense. let CheckFSharpAttributesForObsolete g attribs = - nonNil attribs && (HasFSharpAttribute g g.attrib_SystemObsolete attribs) + not (List.isEmpty attribs) && (HasFSharpAttribute g g.attrib_SystemObsolete attribs) /// Indicate if a list of F# attributes contains 'ObsoleteAttribute'. Used to suppress the item in intellisense. /// Also check the attributes for CompilerMessageAttribute, which has an IsHidden argument that allows /// items to be suppressed from intellisense. let CheckFSharpAttributesForUnseen g attribs _m = - nonNil attribs && + not (List.isEmpty attribs) && (CheckFSharpAttributesForObsolete g attribs || CheckFSharpAttributesForHidden g attribs) @@ -402,7 +402,7 @@ let CheckMethInfoAttributes g m tyargsOpt minfo = (fun fsAttribs -> let res = CheckFSharpAttributes g fsAttribs m ++ (fun () -> - if isNone tyargsOpt && HasFSharpAttribute g g.attrib_RequiresExplicitTypeArgumentsAttribute fsAttribs then + if Option.isNone tyargsOpt && HasFSharpAttribute g g.attrib_RequiresExplicitTypeArgumentsAttribute fsAttribs then ErrorD(Error(FSComp.SR.tcFunctionRequiresExplicitTypeArguments(minfo.LogicalName),m)) else CompleteD) diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs index 73a548039ca..088f761ac70 100644 --- a/src/fsharp/AugmentWithHashCompare.fs +++ b/src/fsharp/AugmentWithHashCompare.fs @@ -353,7 +353,7 @@ let mkUnionCompare g tcref (tycon:Tycon) = let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range let rfields = ucase.RecdFields - if isNil rfields then None else + if List.isEmpty rfields then None else let mkTest thise thataddre j (argty:RecdField) = mkCallGenericComparisonWithComparerOuter g m argty.FormalType compe @@ -370,10 +370,10 @@ let mkUnionCompare g tcref (tycon:Tycon) = (mkCompareTestConjuncts g m (List.mapi (mkTest thisucve thatucve) rfields))) Some (mkCase(Test.UnionCase(cref,tinst),mbuilder.AddResultTarget(test,SuppressSequencePointAtTarget))) - let nullary,nonNullary = List.partition isNone (List.map mkCase ucases) - if isNil nonNullary then mkZero g m else + let nullary,nonNullary = List.partition Option.isNone (List.map mkCase ucases) + if List.isEmpty nonNullary then mkZero g m else let cases = nonNullary |> List.map (function (Some c) -> c | None -> failwith "mkUnionCompare") - let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkZero g m,SuppressSequencePointAtTarget)) + let dflt = if List.isEmpty nullary then None else Some (mbuilder.AddResultTarget(mkZero g m,SuppressSequencePointAtTarget)) let dtree = TDSwitch(thise, cases, dflt,m) mbuilder.Close(dtree,m,g.int_ty) @@ -410,7 +410,7 @@ let mkUnionCompareWithComparer g tcref (tycon:Tycon) (_thisv,thise) (_thatobjv,t let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range let rfields = ucase.RecdFields - if isNil rfields then None else + if List.isEmpty rfields then None else let mkTest thise thataddre j (argty:RecdField) = mkCallGenericComparisonWithComparerOuter g m argty.FormalType @@ -430,10 +430,10 @@ let mkUnionCompareWithComparer g tcref (tycon:Tycon) (_thisv,thise) (_thatobjv,t Some (mkCase(Test.UnionCase(cref,tinst),mbuilder.AddResultTarget(test,SuppressSequencePointAtTarget))) - let nullary,nonNullary = List.partition isNone (List.map mkCase ucases) - if isNil nonNullary then mkZero g m else + let nullary,nonNullary = List.partition Option.isNone (List.map mkCase ucases) + if List.isEmpty nonNullary then mkZero g m else let cases = nonNullary |> List.map (function (Some c) -> c | None -> failwith "mkUnionCompare") - let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkZero g m,SuppressSequencePointAtTarget)) + let dflt = if List.isEmpty nullary then None else Some (mbuilder.AddResultTarget(mkZero g m,SuppressSequencePointAtTarget)) let dtree = TDSwitch(thise, cases, dflt,m) mbuilder.Close(dtree,m,g.int_ty) @@ -471,7 +471,7 @@ let mkUnionEquality g tcref (tycon:Tycon) = let cref = tcref.MakeNestedUnionCaseRef ucase let m = cref.Range let rfields = ucase.RecdFields - if isNil rfields then None else + if List.isEmpty rfields then None else let mkTest thise thataddre j (argty:RecdField) = mkCallGenericEqualityEROuter g m argty.FormalType @@ -490,10 +490,10 @@ let mkUnionEquality g tcref (tycon:Tycon) = Some (mkCase(Test.UnionCase(cref,tinst), mbuilder.AddResultTarget(test, SuppressSequencePointAtTarget))) - let nullary,nonNullary = List.partition isNone (List.map mkCase ucases) - if isNil nonNullary then mkTrue g m else + let nullary,nonNullary = List.partition Option.isNone (List.map mkCase ucases) + if List.isEmpty nonNullary then mkTrue g m else let cases = List.map (function (Some c) -> c | None -> failwith "mkUnionEquality") nonNullary - let dflt = (if isNil nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m,SuppressSequencePointAtTarget))) + let dflt = (if List.isEmpty nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m,SuppressSequencePointAtTarget))) let dtree = TDSwitch(thise, cases, dflt, m) mbuilder.Close(dtree,m,g.bool_ty) @@ -532,7 +532,7 @@ let mkUnionEqualityWithComparer g tcref (tycon:Tycon) (_thisv,thise) thatobje (t let m = cref.Range let rfields = ucase.RecdFields - if isNil rfields then None else + if List.isEmpty rfields then None else let mkTest thise thataddre j (argty:RecdField) = mkCallGenericEqualityWithComparerOuter g m argty.FormalType @@ -553,10 +553,10 @@ let mkUnionEqualityWithComparer g tcref (tycon:Tycon) (_thisv,thise) thatobje (t Some (mkCase(Test.UnionCase(cref,tinst), mbuilder.AddResultTarget (test, SuppressSequencePointAtTarget))) - let nullary,nonNullary = List.partition isNone (List.map mkCase ucases) - if isNil nonNullary then mkTrue g m else + let nullary,nonNullary = List.partition Option.isNone (List.map mkCase ucases) + if List.isEmpty nonNullary then mkTrue g m else let cases = List.map (function (Some c) -> c | None -> failwith "mkUnionEquality") nonNullary - let dflt = if isNil nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m,SuppressSequencePointAtTarget)) + let dflt = if List.isEmpty nullary then None else Some (mbuilder.AddResultTarget(mkTrue g m,SuppressSequencePointAtTarget)) let dtree = TDSwitch(thise, cases, dflt, m) mbuilder.Close(dtree,m,g.bool_ty) @@ -938,7 +938,7 @@ let MakeBindingsForCompareAugmentation g (tycon:Tycon) = if isUnitTy g ty then mkZero g m else let thate = mkCoerceExpr (thatobje, ty, m, g.obj_ty) - mkApps g ((exprForValRef m vref2,vref2.Type), (if isNil tinst then [] else [tinst]), [thise;thate], m) + mkApps g ((exprForValRef m vref2,vref2.Type), (if List.isEmpty tinst then [] else [tinst]), [thise;thate], m) mkLambdas m tps [thisv;thatobjv] (comparee,g.int_ty) let rhs2 = @@ -1012,7 +1012,7 @@ let MakeBindingsForEqualityWithComparerAugmentation g (tycon:Tycon) = if isUnitTy g ty then mkZero g m else let compe = mkILCallGetEqualityComparer g m - mkApps g ((exprForValRef m withcGetHashCodeVal,withcGetHashCodeVal.Type), (if isNil tinst then [] else [tinst]), [thise; compe], m) + mkApps g ((exprForValRef m withcGetHashCodeVal,withcGetHashCodeVal.Type), (if List.isEmpty tinst then [] else [tinst]), [thise; compe], m) mkLambdas m tps [thisv; unitv] (hashe,g.int_ty) @@ -1048,7 +1048,7 @@ let MakeBindingsForEqualsAugmentation g (tycon:Tycon) = let thatv,thate = mkCompGenLocal m "that" ty mkIsInstConditional g m ty thatobje thatv - (mkApps g ((exprForValRef m nocEqualsVal,nocEqualsVal.Type), (if isNil tinst then [] else [tinst]), [thise;thate], m)) + (mkApps g ((exprForValRef m nocEqualsVal,nocEqualsVal.Type), (if List.isEmpty tinst then [] else [tinst]), [thise;thate], m)) (mkFalse g m) mkLambdas m tps [thisv;thatobjv] (equalse,g.bool_ty) @@ -1077,6 +1077,6 @@ let rec TypeDefinitelyHasEquality g ty = isAppTy g ty && let tcref,tinst = destAppTy g ty // Give a good error for structural types excluded from the equality relation because of their fields - not (TyconIsCandidateForAugmentationWithEquals g tcref.Deref && isNone tcref.GeneratedHashAndEqualsWithComparerValues) && + not (TyconIsCandidateForAugmentationWithEquals g tcref.Deref && Option.isNone tcref.GeneratedHashAndEqualsWithComparerValues) && // Check the (possibly inferred) structural dependencies (tinst, tcref.TyparsNoRange) ||> List.lengthsEqAndForall2 (fun ty tp -> not tp.EqualityConditionalOn || TypeDefinitelyHasEquality g ty) diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 99966e12aaf..879ccf0f2c4 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -524,6 +524,7 @@ let TypeTestUnnecessaryE() = DeclareResourceString("TypeTestUnnecessary","") let OverrideDoesntOverride1E() = DeclareResourceString("OverrideDoesntOverride1","%s") let OverrideDoesntOverride2E() = DeclareResourceString("OverrideDoesntOverride2","%s") let OverrideDoesntOverride3E() = DeclareResourceString("OverrideDoesntOverride3","%s") +let OverrideDoesntOverride4E() = DeclareResourceString("OverrideDoesntOverride4","%s") let UnionCaseWrongArgumentsE() = DeclareResourceString("UnionCaseWrongArguments","%d%d") let UnionPatternsBindDifferentNamesE() = DeclareResourceString("UnionPatternsBindDifferentNames","") let RequiredButNotSpecifiedE() = DeclareResourceString("RequiredButNotSpecified","%s%s%s") @@ -1144,15 +1145,32 @@ let OutputPhasedErrorR (os:System.Text.StringBuilder) (err:PhasedError) = Printf.bprintf os "%s" msg | OverrideDoesntOverride(denv,impl,minfoVirtOpt,g,amap,m) -> let sig1 = DispatchSlotChecking.FormatOverride denv impl - begin match minfoVirtOpt with + match minfoVirtOpt with | None -> os.Append(OverrideDoesntOverride1E().Format sig1) |> ignore - | Some minfoVirt -> - os.Append(OverrideDoesntOverride2E().Format sig1) |> ignore - let sig2 = DispatchSlotChecking.FormatMethInfoSig g amap m denv minfoVirt - if sig1 <> sig2 then - os.Append(OverrideDoesntOverride3E().Format sig2) |> ignore - end + | Some minfoVirt -> + // https://github.com/Microsoft/visualfsharp/issues/35 + // Improve error message when attempting to override generic return type with unit: + // we need to check if unit was used as a type argument + let rec hasUnitTType_app (types: TType list) = + match types with + | TType_app (maybeUnit, []) :: ts -> + match maybeUnit.TypeAbbrev with + | Some ttype when Tastops.isUnitTy g ttype -> true + | _ -> hasUnitTType_app ts + | _ :: ts -> hasUnitTType_app ts + | [] -> false + + match minfoVirt.EnclosingType with + | TType_app (t, types) when t.IsFSharpInterfaceTycon && hasUnitTType_app types -> + // match abstract member with 'unit' passed as generic argument + os.Append(OverrideDoesntOverride4E().Format sig1) |> ignore + | _ -> + os.Append(OverrideDoesntOverride2E().Format sig1) |> ignore + let sig2 = DispatchSlotChecking.FormatMethInfoSig g amap m denv minfoVirt + if sig1 <> sig2 then + os.Append(OverrideDoesntOverride3E().Format sig2) |> ignore + | UnionCaseWrongArguments (_,n1,n2,_) -> os.Append(UnionCaseWrongArgumentsE().Format n2 n1) |> ignore | UnionPatternsBindDifferentNames _ -> @@ -2565,8 +2583,8 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = clrRoot, (int v1, sprintf "v%d.%d" v1 v2), (v1=5us && v2=0us && v3=5us) // SL5 mscorlib is 5.0.5.0 | _ -> failwith (FSComp.SR.buildCouldNotReadVersionInfoFromMscorlib()) - with _ -> - error(Error(FSComp.SR.buildCannotReadAssembly(filename),rangeStartup)) + with e -> + error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), rangeStartup)) | _ -> #if !ENABLE_MONO_SUPPORT // TODO: we have to get msbuild out of this @@ -2626,8 +2644,8 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = checkFSharpBinaryCompatWithMscorlib filename ilReader.ILAssemblyRefs ilReader.ILModuleDef.ManifestOfAssembly.Version rangeStartup; let fslibRoot = Path.GetDirectoryName(FileSystem.GetFullPathShim(filename)) fslibRoot (* , sprintf "v%d.%d" v1 v2 *) - with _ -> - error(Error(FSComp.SR.buildCannotReadAssembly(filename),rangeStartup)) + with e -> + error(Error(FSComp.SR.buildErrorOpeningBinaryFile(filename, e.Message), rangeStartup)) | _ -> data.defaultFSharpBinariesDir @@ -3252,7 +3270,7 @@ let PostParseModuleImpl (_i,defaultNamespace,isLastCompiland,filename,impl) = | SynModuleDecl.NestedModule(_) :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(),trimRangeToLine m)) | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(),trimRangeToLine m)) - let modname = ComputeAnonModuleName (nonNil defs) defaultNamespace filename (trimRangeToLine m) + let modname = ComputeAnonModuleName (not (List.isEmpty defs)) defaultNamespace filename (trimRangeToLine m) SynModuleOrNamespace(modname,false,true,defs,PreXmlDoc.Empty,[],None,m) | ParsedImplFileFragment.NamespaceFragment (lid,a,b,c,d,e,m)-> @@ -3280,7 +3298,7 @@ let PostParseModuleSpec (_i,defaultNamespace,isLastCompiland,filename,intf) = | SynModuleSigDecl.NestedModule(_) :: _ -> errorR(Error(FSComp.SR.noEqualSignAfterModule(),m)) | _ -> errorR(Error(FSComp.SR.buildMultiFileRequiresNamespaceOrModule(),m)) - let modname = ComputeAnonModuleName (nonNil defs) defaultNamespace filename (trimRangeToLine m) + let modname = ComputeAnonModuleName (not (List.isEmpty defs)) defaultNamespace filename (trimRangeToLine m) SynModuleOrNamespaceSig(modname,false,true,defs,PreXmlDoc.Empty,[],None,m) | ParsedSigFileFragment.NamespaceFragment (lid,a,b,c,d,e,m)-> @@ -4969,7 +4987,7 @@ module private ScriptPreprocessClosure = // Mark the last file as isLastCompiland. let closureFiles = - if isNil closureFiles then + if List.isEmpty closureFiles then closureFiles else match List.frontAndBack closureFiles with @@ -5232,7 +5250,7 @@ let TypeCheckOneInputEventually // Check if we've got an interface for this fragment let rootSigOpt = rootSigs.TryFind(qualNameOfFile) - if verbose then dprintf "ParsedInput.ImplFile, nm = %s, qualNameOfFile = %s, ?rootSigOpt = %b\n" filename qualNameOfFile.Text (isSome rootSigOpt) + if verbose then dprintf "ParsedInput.ImplFile, nm = %s, qualNameOfFile = %s, ?rootSigOpt = %b\n" filename qualNameOfFile.Text (Option.isSome rootSigOpt) // Check if we've already seen an implementation for this fragment if Zset.contains qualNameOfFile rootImpls then @@ -5244,7 +5262,7 @@ let TypeCheckOneInputEventually let! topAttrs,implFile,tcEnvAtEnd = TypeCheckOneImplFile (tcGlobals,tcState.tcsNiceNameGen,amap,tcState.tcsCcu,checkForErrors,tcConfig.conditionalCompilationDefines,tcSink) tcImplEnv rootSigOpt file - let hadSig = isSome rootSigOpt + let hadSig = Option.isSome rootSigOpt let implFileSigType = SigTypeOfImplFile implFile if verbose then dprintf "done TypeCheckOneImplFile...\n" diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index c6a91ea4aad..c1867acbb52 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -137,7 +137,7 @@ let PrintCompilerOption (CompilerOption(_s,_tag,_spec,_,help) as compilerOption) printfn "" (* newline *) let PrintPublicOptions (heading,opts) = - if nonNil opts then + if not (List.isEmpty opts) then printfn "" printfn "" printfn "\t\t%s" heading diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 21129b89106..f51bb3a8538 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -977,7 +977,7 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) permitWeakResolution ndeep // - Neither type contributes any methods OR // - We have the special case "decimal<_> * decimal". In this case we have some // possibly-relevant methods from "decimal" but we ignore them in this case. - (isNil minfos || (isSome (GetMeasureOfType g argty1) && isDecimalTy g argty2)) in + (List.isEmpty minfos || (Option.isSome (GetMeasureOfType g argty1) && isDecimalTy g argty2)) in checkRuleAppliesInPreferenceToMethods argty1 argty2 || checkRuleAppliesInPreferenceToMethods argty2 argty1) -> @@ -1268,7 +1268,7 @@ and SolveMemberConstraint (csenv:ConstraintSolverEnv) permitWeakResolution ndeep let frees = GetFreeTyparsOfMemberConstraint csenv traitInfo // If there's nothing left to learn then raise the errors - (if (permitWeakResolution && isNil support) || isNil frees then errors + (if (permitWeakResolution && List.isEmpty support) || List.isEmpty frees then errors // Otherwise re-record the trait waiting for canonicalization else AddMemberConstraint csenv ndeep m2 trace traitInfo support frees) ++ (fun () -> ResultD TTraitUnsolved) ) @@ -1355,7 +1355,7 @@ and TransactMemberConstraintSolution traitInfo trace sln = /// That is, don't perform resolution if more nominal information may influence the set of available overloads and GetRelevantMethodsForTrait (csenv:ConstraintSolverEnv) permitWeakResolution nm (TTrait(tys,_,memFlags,argtys,rty,soln) as traitInfo) : MethInfo list = let results = - if permitWeakResolution || isNil (GetSupportOfMemberConstraint csenv traitInfo) then + if permitWeakResolution || List.isEmpty (GetSupportOfMemberConstraint csenv traitInfo) then let m = csenv.m let minfos = match memFlags.MemberKind with @@ -1408,11 +1408,11 @@ and SolveRelevantMemberConstraintsForTypar (csenv:ConstraintSolverEnv) ndeep per let cxst = csenv.SolverState.ExtraCxs let tpn = tp.Stamp let cxs = cxst.FindAll tpn - if isNil cxs then ResultD false else + if List.isEmpty cxs then ResultD false else cxs |> List.iter (fun _ -> cxst.Remove tpn); - assert (isNil (cxst.FindAll tpn)); + assert (List.isEmpty (cxst.FindAll tpn)) match trace with | NoTrace -> () @@ -1674,7 +1674,7 @@ and SolveTypeSupportsComparison (csenv:ConstraintSolverEnv) ndeep m2 trace ty = elif (isAppTy g ty && let tcref = tcrefOfAppTy g ty AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare g tcref.Deref && - isNone tcref.GeneratedCompareToWithComparerValues) then + Option.isNone tcref.GeneratedCompareToWithComparerValues) then ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportComparison3(NicePrint.minimalStringOfType denv ty),m,m2)) @@ -1702,7 +1702,7 @@ and SolveTypSupportsEquality (csenv:ConstraintSolverEnv) ndeep m2 trace ty = // Give a good error for structural types excluded from the equality relation because of their fields if (AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tcref.Deref && - isNone tcref.GeneratedHashAndEqualsWithComparerValues) then + Option.isNone tcref.GeneratedHashAndEqualsWithComparerValues) then ErrorD (ConstraintSolverError(FSComp.SR.csTypeDoesNotSupportEquality3(NicePrint.minimalStringOfType denv ty),m,m2)) @@ -1855,7 +1855,7 @@ and CanMemberSigsMatchUpToCheck Iterate2D unifyTypes minst uminst ++ (fun () -> - if not (permitOptArgs || isNil(unnamedCalledOptArgs)) then ErrorD(Error(FSComp.SR.csOptionalArgumentNotPermittedHere(),m)) else + if not (permitOptArgs || List.isEmpty unnamedCalledOptArgs) then ErrorD(Error(FSComp.SR.csOptionalArgumentNotPermittedHere(),m)) else let calledObjArgTys = minfo.GetObjArgTypes(amap, m, minst) @@ -1909,10 +1909,10 @@ and CanMemberSigsMatchUpToCheck match reqdRetTyOpt with | None -> CompleteD | Some _ when minfo.IsConstructor -> CompleteD - | Some _ when not alwaysCheckReturn && isNil unnamedCalledOutArgs -> CompleteD + | Some _ when not alwaysCheckReturn && List.isEmpty unnamedCalledOutArgs -> CompleteD | Some reqdRetTy -> let methodRetTy = - if isNil unnamedCalledOutArgs then + if List.isEmpty unnamedCalledOutArgs then methodRetTy else let outArgTys = unnamedCalledOutArgs |> List.map (fun calledArg -> destByrefTy g calledArg.CalledArgumentType) @@ -1995,10 +1995,10 @@ and ReportNoCandidatesError (csenv:ConstraintSolverEnv) (nUnnamedCallerArgs,nNam // No version accessible | ([],others),_,_,_,_ -> - if nonNil others then - ErrorD (Error (FSComp.SR.csMemberIsNotAccessible2(methodName, (ShowAccessDomain ad)), m)) - else + if List.isEmpty others then ErrorD (Error (FSComp.SR.csMemberIsNotAccessible(methodName, (ShowAccessDomain ad)), m)) + else + ErrorD (Error (FSComp.SR.csMemberIsNotAccessible2(methodName, (ShowAccessDomain ad)), m)) | _,([],(cmeth::_)),_,_,_ -> // Check all the argument types. @@ -2415,7 +2415,6 @@ let EliminateConstraintsForGeneralizedTypars csenv trace (generalizedTypars: Typ let tpn = tp.Stamp let cxst = csenv.SolverState.ExtraCxs let cxs = cxst.FindAll tpn - if isNil cxs then () else cxs |> List.iter (fun cx -> cxst.Remove tpn match trace with diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs index 8b96ebb196d..d680760d040 100644 --- a/src/fsharp/DetupleArgs.fs +++ b/src/fsharp/DetupleArgs.fs @@ -406,7 +406,7 @@ type CallPattern = TupleStructure list let callPatternOrder = (compare : CallPattern -> CallPattern -> int) let argsCP exprs = List.map exprTS exprs let noArgsCP = [] -let isTrivialCP xs = (isNil xs) +let inline isTrivialCP xs = List.isEmpty xs let rec minimalCallPattern callPattern = match callPattern with diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs index 620c9d9b115..f6335c1e06b 100755 --- a/src/fsharp/ErrorLogger.fs +++ b/src/fsharp/ErrorLogger.fs @@ -270,11 +270,17 @@ type internal CompileThreadStatic = static member BuildPhaseUnchecked with get() = CompileThreadStatic.buildPhase (* This can be a null value *) static member BuildPhase - with get() = if box CompileThreadStatic.buildPhase <> null then CompileThreadStatic.buildPhase else (assert false; BuildPhase.DefaultPhase) + with get() = + match box CompileThreadStatic.buildPhase with + | null -> assert false; BuildPhase.DefaultPhase + | _ -> CompileThreadStatic.buildPhase and set v = CompileThreadStatic.buildPhase <- v static member ErrorLogger - with get() = if box CompileThreadStatic.errorLogger <> null then CompileThreadStatic.errorLogger else !uninitializedErrorLoggerFallback + with get() = + match box CompileThreadStatic.errorLogger with + | null -> !uninitializedErrorLoggerFallback + | _ -> CompileThreadStatic.errorLogger and set v = CompileThreadStatic.errorLogger <- v @@ -512,7 +518,7 @@ let NewlineifyErrorString (message:string) = message.Replace(stringThatIsAProxyF /// 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) = - if text = null then nullArg "text" + if isNull text then nullArg "text" let text = text.Trim() let buf = System.Text.StringBuilder() diff --git a/src/fsharp/ExtensionTyping.fs b/src/fsharp/ExtensionTyping.fs index fa2a3e773f7..c7739e18c9a 100755 --- a/src/fsharp/ExtensionTyping.fs +++ b/src/fsharp/ExtensionTyping.fs @@ -1251,6 +1251,6 @@ module internal ExtensionTyping = /// Check if this is a direct reference to a non-embedded generated type. This is not permitted at any name resolution. /// We check by seeing if the type is absent from the remapping context. let IsGeneratedTypeDirectReference (st: Tainted, m) = - st.PUntaint((fun st -> st.TryGetTyconRef() |> isNone), m) + st.PUntaint((fun st -> st.TryGetTyconRef() |> Option.isNone), m) #endif diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index a70f430620d..cefdff8663e 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -80,7 +80,7 @@ tastTypeHasAssemblyCodeRepresentation,"The type '%s' has an inline assembly code 255,tastUnexpectedByRef,"Unexpected use of a byref-typed variable" 256,tastValueMustBeLocalAndMutable,"A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'" 257,tastInvalidMutationOfConstant,"Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'." -tastValueHasBeenCopied,"The value has been copied to ensure the original is not mutated by this operation" +tastValueHasBeenCopied,"The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed" 259,tastRecursiveValuesMayNotBeInConstructionOfTuple,"Recursively defined values cannot appear directly as part of the construction of a tuple value within a recursive binding" 260,tastRecursiveValuesMayNotAppearInConstructionOfType,"Recursive values cannot appear directly as a construction of the type '%s' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead." 261,tastRecursiveValuesMayNotBeAssignedToNonMutableField,"Recursive values cannot be directly assigned to the non-mutable field '%s' of the type '%s' within a recursive binding. Consider using a mutable field instead." @@ -1319,3 +1319,4 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc 3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'" 3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression." 3209,chkNoByrefReturnOfLocal,"The address of the variable '%s' cannot be used at this point. A method or function may not return the address of this local value." +3210,tcNamedActivePattern,"%s is an active pattern and cannot be treated as a discriminated union case with named fields." \ No newline at end of file diff --git a/src/fsharp/FSStrings.resx b/src/fsharp/FSStrings.resx index f028e00b6f8..04bce992367 100644 --- a/src/fsharp/FSStrings.resx +++ b/src/fsharp/FSStrings.resx @@ -867,6 +867,9 @@ The required signature is '{0}'. + + The member '{0}' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type. + This constructor is applied to {0} argument(s) but expects {1} diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs index 1763cb82454..acf752ff8cd 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs @@ -8,11 +8,17 @@ open NUnit.Framework open FsCheck open Utils +/// helper function that creates labeled FsCheck properties for equality comparisons +let consistency name sqs ls arr = + (sqs = arr) |@ (sprintf "Seq.%s = '%A', Array.%s = '%A'" name sqs name arr) .&. + (ls = arr) |@ (sprintf "List.%s = '%A', Array.%s = '%A'" name ls name arr) + + let allPairs<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) = - let s = xs |> Seq.allPairs xs2 - let l = xs |> List.allPairs xs2 - let a = xs |> Seq.toArray |> Array.allPairs (Seq.toArray xs2) - Seq.toArray s = a && List.toArray l = a + let s = xs |> Seq.allPairs xs2 |> Seq.toArray + let l = xs |> List.allPairs xs2 |> List.toArray + let a = xs |> List.toArray |> Array.allPairs (List.toArray xs2) + consistency "allPairs" s l a [] let ``allPairs is consistent`` () = @@ -21,10 +27,11 @@ let ``allPairs is consistent`` () = Check.QuickThrowOnFailure allPairs let append<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) = - let s = xs |> Seq.append xs2 - let l = xs |> List.append xs2 - let a = xs |> Seq.toArray |> Array.append (Seq.toArray xs2) - Seq.toArray s = a && List.toArray l = a + let s = xs |> Seq.append xs2 |> Seq.toArray + let l = xs |> List.append xs2 |> List.toArray + let a = xs |> List.toArray |> Array.append (List.toArray xs2) + consistency "append" s l a + [] let ``append is consistent`` () = @@ -36,8 +43,8 @@ let averageFloat (xs : NormalFloat []) = let xs = xs |> Array.map float let s = runAndCheckErrorType (fun () -> xs |> Seq.average) let l = runAndCheckErrorType (fun () -> xs |> List.ofArray |> List.average) - let a = runAndCheckErrorType (fun () -> xs |> Array.average) - s = a && l = a + let a = runAndCheckErrorType (fun () -> xs |> Array.average) + consistency "average" s l a [] let ``average is consistent`` () = @@ -49,7 +56,8 @@ let averageBy (xs : float []) f = let s = runAndCheckErrorType (fun () -> xs |> Seq.averageBy f) let l = runAndCheckErrorType (fun () -> xs |> List.ofArray |> List.averageBy f) let a = runAndCheckErrorType (fun () -> xs |> Array.averageBy f) - s = a && l = a + consistency "averageBy" s l a + [] let ``averageBy is consistent`` () = @@ -59,7 +67,8 @@ let contains<'a when 'a : equality> (xs : 'a []) x = let s = xs |> Seq.contains x let l = xs |> List.ofArray |> List.contains x let a = xs |> Array.contains x - s = a && l = a + consistency "contains" s l a + [] let ``contains is consistent`` () = @@ -68,10 +77,10 @@ let ``contains is consistent`` () = Check.QuickThrowOnFailure contains let choose<'a when 'a : equality> (xs : 'a []) f = - let s = xs |> Seq.choose f - let l = xs |> List.ofArray |> List.choose f + let s = xs |> Seq.choose f |> Seq.toArray + let l = xs |> List.ofArray |> List.choose f |> List.toArray let a = xs |> Array.choose f - Seq.toArray s = a && List.toArray l = a + consistency "contains" s l a [] let ``choose is consistent`` () = @@ -80,10 +89,17 @@ let ``choose is consistent`` () = Check.QuickThrowOnFailure choose let chunkBySize<'a when 'a : equality> (xs : 'a []) size = - let s = run (fun () -> xs |> Seq.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray) - let l = run (fun () -> xs |> List.ofArray |> List.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray) - let a = run (fun () -> xs |> Array.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray) - s = a && l = a + let ls = List.ofArray xs + if size <= 0 then + Prop.throws (lazy Seq.chunkBySize size xs) .&. + Prop.throws (lazy Array.chunkBySize size xs) .&. + Prop.throws (lazy List.chunkBySize size ls) + else + let s = xs |> Seq.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray + let l = ls |> List.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray + let a = xs |> Array.chunkBySize size |> Seq.map Seq.toArray |> Seq.toArray + consistency "chunkBySize" s l a + [] let ``chunkBySize is consistent`` () = @@ -92,10 +108,12 @@ let ``chunkBySize is consistent`` () = Check.QuickThrowOnFailure chunkBySize let collect<'a> (xs : 'a []) f = - let s = xs |> Seq.collect f - let l = xs |> List.ofArray |> List.collect (fun x -> f x |> List.ofArray) + let s = xs |> Seq.collect f |> Seq.toArray + let l = xs |> List.ofArray |> List.collect (fun x -> f x |> List.ofArray) |> List.toArray let a = xs |> Array.collect f - Seq.toArray s = a && List.toArray l = a + consistency "collect" s l a + + [] let ``collect is consistent`` () = @@ -107,7 +125,9 @@ let compareWith<'a>(xs : 'a []) (xs2 : 'a []) f = let s = (xs, xs2) ||> Seq.compareWith f let l = (List.ofArray xs, List.ofArray xs2) ||> List.compareWith f let a = (xs, xs2) ||> Array.compareWith f - s = a && l = a + consistency "compareWith" s l a + + [] let ``compareWith is consistent`` () = @@ -116,10 +136,10 @@ let ``compareWith is consistent`` () = Check.QuickThrowOnFailure compareWith let concat<'a when 'a : equality> (xs : 'a [][]) = - let s = xs |> Seq.concat - let l = xs |> List.ofArray |> List.map List.ofArray |> List.concat + let s = xs |> Seq.concat |> Seq.toArray + let l = xs |> List.ofArray |> List.map List.ofArray |> List.concat |> List.toArray let a = xs |> Array.concat - Seq.toArray s = a && List.toArray l = a + consistency "concat" s l a [] let ``concat is consistent`` () = @@ -128,10 +148,10 @@ let ``concat is consistent`` () = Check.QuickThrowOnFailure concat let countBy<'a> (xs : 'a []) f = - let s = xs |> Seq.countBy f - let l = xs |> List.ofArray |> List.countBy f + let s = xs |> Seq.countBy f |> Seq.toArray + let l = xs |> List.ofArray |> List.countBy f |> List.toArray let a = xs |> Array.countBy f - Seq.toArray s = a && List.toArray l = a + consistency "countBy" s l a [] let ``countBy is consistent`` () = @@ -140,10 +160,10 @@ let ``countBy is consistent`` () = Check.QuickThrowOnFailure countBy let distinct<'a when 'a : comparison> (xs : 'a []) = - let s = xs |> Seq.distinct - let l = xs |> List.ofArray |> List.distinct - let a = xs |> Array.distinct - Seq.toArray s = a && List.toArray l = a + let s = xs |> Seq.distinct |> Seq.toArray + let l = xs |> List.ofArray |> List.distinct |> List.toArray + let a = xs |> Array.distinct + consistency "distinct" s l a [] let ``distinct is consistent`` () = @@ -152,10 +172,10 @@ let ``distinct is consistent`` () = Check.QuickThrowOnFailure distinct let distinctBy<'a when 'a : equality> (xs : 'a []) f = - let s = xs |> Seq.distinctBy f - let l = xs |> List.ofArray |> List.distinctBy f - let a = xs |> Array.distinctBy f - Seq.toArray s = a && List.toArray l = a + let s = xs |> Seq.distinctBy f |> Seq.toArray + let l = xs |> List.ofArray |> List.distinctBy f |> List.toArray + let a = xs |> Array.distinctBy f + consistency "distinctBy" s l a [] let ``distinctBy is consistent`` () = @@ -167,7 +187,7 @@ let exactlyOne<'a when 'a : comparison> (xs : 'a []) = let s = runAndCheckErrorType (fun () -> xs |> Seq.exactlyOne) let l = runAndCheckErrorType (fun () -> xs |> List.ofArray |> List.exactlyOne) let a = runAndCheckErrorType (fun () -> xs |> Array.exactlyOne) - s = a && l = a + consistency "exactlyOne" s l a [] let ``exactlyOne is consistent`` () = @@ -176,10 +196,10 @@ let ``exactlyOne is consistent`` () = Check.QuickThrowOnFailure exactlyOne let except<'a when 'a : equality> (xs : 'a []) (itemsToExclude: 'a []) = - let s = xs |> Seq.except itemsToExclude - let l = xs |> List.ofArray |> List.except itemsToExclude + let s = xs |> Seq.except itemsToExclude |> Seq.toArray + let l = xs |> List.ofArray |> List.except itemsToExclude |> List.toArray let a = xs |> Array.except itemsToExclude - Seq.toArray s = a && List.toArray l = a + consistency "except" s l a [] let ``except is consistent`` () = @@ -191,7 +211,7 @@ let exists<'a when 'a : equality> (xs : 'a []) f = let s = xs |> Seq.exists f let l = xs |> List.ofArray |> List.exists f let a = xs |> Array.exists f - s = a && l = a + consistency "exists" s l a [] let ``exists is consistent`` () = @@ -205,7 +225,7 @@ let exists2<'a when 'a : equality> (xs':('a*'a) []) f = let s = runAndCheckErrorType (fun () -> Seq.exists2 f xs xs2) let l = runAndCheckErrorType (fun () -> List.exists2 f (List.ofSeq xs) (List.ofSeq xs2)) let a = runAndCheckErrorType (fun () -> Array.exists2 f (Array.ofSeq xs) (Array.ofSeq xs2)) - s = a && l = a + consistency "exists2" s l a [] let ``exists2 is consistent for collections with equal length`` () = @@ -229,7 +249,7 @@ let find<'a when 'a : equality> (xs : 'a []) predicate = let s = run (fun () -> xs |> Seq.find predicate) let l = run (fun () -> xs |> List.ofArray |> List.find predicate) let a = run (fun () -> xs |> Array.find predicate) - s = a && l = a + consistency "find" s l a [] let ``find is consistent`` () = @@ -241,7 +261,7 @@ let findBack<'a when 'a : equality> (xs : 'a []) predicate = let s = run (fun () -> xs |> Seq.findBack predicate) let l = run (fun () -> xs |> List.ofArray |> List.findBack predicate) let a = run (fun () -> xs |> Array.findBack predicate) - s = a && l = a + consistency "findBack" s l a [] let ``findBack is consistent`` () = @@ -253,7 +273,7 @@ let findIndex<'a when 'a : equality> (xs : 'a []) predicate = let s = run (fun () -> xs |> Seq.findIndex predicate) let l = run (fun () -> xs |> List.ofArray |> List.findIndex predicate) let a = run (fun () -> xs |> Array.findIndex predicate) - s = a && l = a + consistency "findIndex" s l a [] let ``findIndex is consistent`` () = @@ -265,7 +285,7 @@ let findIndexBack<'a when 'a : equality> (xs : 'a []) predicate = let s = run (fun () -> xs |> Seq.findIndexBack predicate) let l = run (fun () -> xs |> List.ofArray |> List.findIndexBack predicate) let a = run (fun () -> xs |> Array.findIndexBack predicate) - s = a && l = a + consistency "findIndexBack" s l a [] let ``findIndexBack is consistent`` () = @@ -277,7 +297,7 @@ let fold<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let s = run (fun () -> xs |> Seq.fold f start) let l = run (fun () -> xs |> List.ofArray |> List.fold f start) let a = run (fun () -> xs |> Array.fold f start) - s = a && l = a + consistency "fold" s l a [] let ``fold is consistent`` () = @@ -292,7 +312,7 @@ let fold2<'a,'b,'c when 'c : equality> (xs': ('a*'b)[]) f (start:'c) = let s = run (fun () -> Seq.fold2 f start xs xs2) let l = run (fun () -> List.fold2 f start (List.ofArray xs) (List.ofArray xs2)) let a = run (fun () -> Array.fold2 f start xs xs2) - s = a && l = a + consistency "fold2" s l a [] let ``fold2 is consistent`` () = @@ -307,7 +327,7 @@ let foldBack<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let s = run (fun () -> Seq.foldBack f xs start) let l = run (fun () -> List.foldBack f (xs |> List.ofArray) start) let a = run (fun () -> Array.foldBack f xs start) - s = a && l = a + consistency "foldBack" s l a [] let ``foldBack is consistent`` () = @@ -322,7 +342,7 @@ let foldBack2<'a,'b,'c when 'c : equality> (xs': ('a*'b)[]) f (start:'c) = let s = run (fun () -> Seq.foldBack2 f xs xs2 start) let l = run (fun () -> List.foldBack2 f (List.ofArray xs) (List.ofArray xs2) start) let a = run (fun () -> Array.foldBack2 f xs xs2 start) - s = a && l = a + consistency "foldBack2" s l a [] let ``foldBack2 is consistent`` () = @@ -337,7 +357,7 @@ let forall<'a when 'a : equality> (xs : 'a []) f = let s = xs |> Seq.forall f let l = xs |> List.ofArray |> List.forall f let a = xs |> Array.forall f - s = a && l = a + consistency "forall" s l a [] let ``forall is consistent`` () = @@ -351,7 +371,7 @@ let forall2<'a when 'a : equality> (xs':('a*'a) []) f = let s = runAndCheckErrorType (fun () -> Seq.forall2 f xs xs2) let l = runAndCheckErrorType (fun () -> List.forall2 f (List.ofSeq xs) (List.ofSeq xs2)) let a = runAndCheckErrorType (fun () -> Array.forall2 f (Array.ofSeq xs) (Array.ofSeq xs2)) - s = a && l = a + consistency "forall2" s l a [] let ``forall2 is consistent for collections with equal length`` () = @@ -363,7 +383,7 @@ let groupBy<'a when 'a : equality> (xs : 'a []) f = let s = run (fun () -> xs |> Seq.groupBy f |> Seq.toArray |> Array.map (fun (x,xs) -> x,xs |> Seq.toArray)) let l = run (fun () -> xs |> List.ofArray |> List.groupBy f |> Seq.toArray |> Array.map (fun (x,xs) -> x,xs |> Seq.toArray)) let a = run (fun () -> xs |> Array.groupBy f |> Array.map (fun (x,xs) -> x,xs |> Seq.toArray)) - s = a && l = a + consistency "groupBy" s l a [] let ``groupBy is consistent`` () = @@ -375,7 +395,7 @@ let head<'a when 'a : equality> (xs : 'a []) = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.head) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.head) let a = runAndCheckIfAnyError (fun () -> xs |> Array.head) - s = a && l = a + consistency "head" s l a [] let ``head is consistent`` () = @@ -384,10 +404,10 @@ let ``head is consistent`` () = Check.QuickThrowOnFailure head let indexed<'a when 'a : equality> (xs : 'a []) = - let s = xs |> Seq.indexed - let l = xs |> List.ofArray |> List.indexed + let s = xs |> Seq.indexed |> Seq.toArray + let l = xs |> List.ofArray |> List.indexed |> List.toArray let a = xs |> Array.indexed - Seq.toArray s = a && List.toArray l = a + consistency "indexed" s l a [] let ``indexed is consistent`` () = @@ -399,7 +419,7 @@ let init<'a when 'a : equality> count f = let s = run (fun () -> Seq.init count f |> Seq.toArray) let l = run (fun () -> List.init count f |> Seq.toArray) let a = run (fun () -> Array.init count f) - s = a && l = a + consistency "init" s l a [] let ``init is consistent`` () = @@ -411,7 +431,7 @@ let isEmpty<'a when 'a : equality> (xs : 'a []) = let s = xs |> Seq.isEmpty let l = xs |> List.ofArray |> List.isEmpty let a = xs |> Array.isEmpty - s = a && l = a + consistency "isEmpty" s l a [] let ``isEmpty is consistent`` () = @@ -423,7 +443,7 @@ let item<'a when 'a : equality> (xs : 'a []) index = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.item index) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.item index) let a = runAndCheckIfAnyError (fun () -> xs |> Array.item index) - s = a && l = a + consistency "item" s l a [] let ``item is consistent`` () = @@ -521,7 +541,7 @@ let last<'a when 'a : equality> (xs : 'a []) = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.last) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.last) let a = runAndCheckIfAnyError (fun () -> xs |> Array.last) - s = a && l = a + consistency "last" s l a [] let ``last is consistent`` () = @@ -533,7 +553,7 @@ let length<'a when 'a : equality> (xs : 'a []) = let s = xs |> Seq.length let l = xs |> List.ofArray |> List.length let a = xs |> Array.length - s = a && l = a + consistency "length" s l a [] let ``length is consistent`` () = @@ -542,10 +562,10 @@ let ``length is consistent`` () = Check.QuickThrowOnFailure length let map<'a when 'a : equality> (xs : 'a []) f = - let s = xs |> Seq.map f - let l = xs |> List.ofArray |> List.map f + let s = xs |> Seq.map f |> Seq.toArray + let l = xs |> List.ofArray |> List.map f |> List.toArray let a = xs |> Array.map f - Seq.toArray s = a && List.toArray l = a + consistency "map" s l a [] let ``map is consistent`` () = @@ -665,7 +685,7 @@ let max<'a when 'a : comparison> (xs : 'a []) = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.max) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.max) let a = runAndCheckIfAnyError (fun () -> xs |> Array.max) - s = a && l = a + consistency "max" s l a [] let ``max is consistent`` () = @@ -677,7 +697,7 @@ let maxBy<'a when 'a : comparison> (xs : 'a []) f = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.maxBy f) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.maxBy f) let a = runAndCheckIfAnyError (fun () -> xs |> Array.maxBy f) - s = a && l = a + consistency "maxBy" s l a [] let ``maxBy is consistent`` () = @@ -689,7 +709,7 @@ let min<'a when 'a : comparison> (xs : 'a []) = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.min) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.min) let a = runAndCheckIfAnyError (fun () -> xs |> Array.min) - s = a && l = a + consistency "min" s l a [] let ``min is consistent`` () = @@ -701,7 +721,7 @@ let minBy<'a when 'a : comparison> (xs : 'a []) f = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.minBy f) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.minBy f) let a = runAndCheckIfAnyError (fun () -> xs |> Array.minBy f) - s = a && l = a + consistency "minBy" s l a [] let ``minBy is consistent`` () = @@ -713,7 +733,7 @@ let pairwise<'a when 'a : comparison> (xs : 'a []) = let s = run (fun () -> xs |> Seq.pairwise |> Seq.toArray) let l = run (fun () -> xs |> List.ofArray |> List.pairwise |> List.toArray) let a = run (fun () -> xs |> Array.pairwise) - s = a && l = a + consistency "pairwise" s l a [] let ``pairwise is consistent`` () = @@ -750,7 +770,7 @@ let permute<'a when 'a : comparison> (xs' : list) = let s = run (fun () -> xs |> Seq.permute permutation |> Seq.toArray) let l = run (fun () -> xs |> List.permute permutation |> List.toArray) let a = run (fun () -> xs |> Array.ofSeq |> Array.permute permutation) - s = a && l = a + consistency "partition" s l a [] let ``permute is consistent`` () = @@ -762,7 +782,7 @@ let pick<'a when 'a : comparison> (xs : 'a []) f = let s = run (fun () -> xs |> Seq.pick f) let l = run (fun () -> xs |> List.ofArray |> List.pick f) let a = run (fun () -> xs |> Array.pick f) - s = a && l = a + consistency "pick" s l a [] let ``pick is consistent`` () = @@ -774,7 +794,7 @@ let reduce<'a when 'a : equality> (xs : 'a []) f = let s = runAndCheckErrorType (fun () -> xs |> Seq.reduce f) let l = runAndCheckErrorType (fun () -> xs |> List.ofArray |> List.reduce f) let a = runAndCheckErrorType (fun () -> xs |> Array.reduce f) - s = a && l = a + consistency "reduce" s l a [] let ``reduce is consistent`` () = @@ -786,7 +806,7 @@ let reduceBack<'a when 'a : equality> (xs : 'a []) f = let s = runAndCheckErrorType (fun () -> xs |> Seq.reduceBack f) let l = runAndCheckErrorType (fun () -> xs |> List.ofArray |> List.reduceBack f) let a = runAndCheckErrorType (fun () -> xs |> Array.reduceBack f) - s = a && l = a + consistency "reduceBack" s l a [] let ``reduceBack is consistent`` () = @@ -798,7 +818,7 @@ let replicate<'a when 'a : equality> x count = let s = runAndCheckIfAnyError (fun () -> Seq.replicate count x |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> List.replicate count x |> List.toArray) let a = runAndCheckIfAnyError (fun () -> Array.replicate count x) - s = a && l = a + consistency "replicate" s l a [] let ``replicate is consistent`` () = @@ -810,7 +830,7 @@ let rev<'a when 'a : equality> (xs : 'a []) = let s = Seq.rev xs |> Seq.toArray let l = xs |> List.ofArray |> List.rev |> List.toArray let a = Array.rev xs - s = a && l = a + consistency "rev" s l a [] let ``rev is consistent`` () = @@ -822,7 +842,7 @@ let scan<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let s = run (fun () -> xs |> Seq.scan f start |> Seq.toArray) let l = run (fun () -> xs |> List.ofArray |> List.scan f start |> Seq.toArray) let a = run (fun () -> xs |> Array.scan f start) - s = a && l = a + consistency "scan" s l a [] let ``scan is consistent`` () = @@ -835,7 +855,7 @@ let scanBack<'a,'b when 'b : equality> (xs : 'a []) f (start:'b) = let s = run (fun () -> Seq.scanBack f xs start |> Seq.toArray) let l = run (fun () -> List.scanBack f (xs |> List.ofArray) start |> Seq.toArray) let a = run (fun () -> Array.scanBack f xs start) - s = a && l = a + consistency "scanback" s l a [] let ``scanBack is consistent`` () = @@ -848,7 +868,7 @@ let singleton<'a when 'a : equality> (x : 'a) = let s = Seq.singleton x |> Seq.toArray let l = List.singleton x |> List.toArray let a = Array.singleton x - s = a && l = a + consistency "singleton" s l a [] let ``singleton is consistent`` () = @@ -860,7 +880,7 @@ let skip<'a when 'a : equality> (xs : 'a []) count = let s = runAndCheckIfAnyError (fun () -> Seq.skip count xs |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> List.skip count (Seq.toList xs) |> List.toArray) let a = runAndCheckIfAnyError (fun () -> Array.skip count xs) - s = a && l = a + consistency "skip" s l a [] let ``skip is consistent`` () = @@ -872,7 +892,7 @@ let skipWhile<'a when 'a : equality> (xs : 'a []) f = let s = runAndCheckIfAnyError (fun () -> Seq.skipWhile f xs |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> List.skipWhile f (Seq.toList xs) |> List.toArray) let a = runAndCheckIfAnyError (fun () -> Array.skipWhile f xs) - s = a && l = a + consistency "skipWhile" s l a [] let ``skipWhile is consistent`` () = @@ -881,10 +901,10 @@ let ``skipWhile is consistent`` () = Check.QuickThrowOnFailure skipWhile let sort<'a when 'a : comparison> (xs : 'a []) = - let s = xs |> Seq.sort - let l = xs |> List.ofArray |> List.sort + let s = xs |> Seq.sort |> Seq.toArray + let l = xs |> List.ofArray |> List.sort |> List.toArray let a = xs |> Array.sort - Seq.toArray s = a && List.toArray l = a + consistency "sort" s l a [] let ``sort is consistent`` () = @@ -934,10 +954,10 @@ let ``sortWith actually sorts (but is inconsistent in regards of stability)`` () Check.QuickThrowOnFailure sortWith let sortDescending<'a when 'a : comparison> (xs : 'a []) = - let s = xs |> Seq.sortDescending - let l = xs |> List.ofArray |> List.sortDescending + let s = xs |> Seq.sortDescending |> Seq.toArray + let l = xs |> List.ofArray |> List.sortDescending |> List.toArray let a = xs |> Array.sortDescending - Seq.toArray s = a && List.toArray l = a + consistency "sortDescending" s l a [] let ``sortDescending is consistent`` () = @@ -965,7 +985,7 @@ let sum (xs : int []) = let s = run (fun () -> xs |> Seq.sum) let l = run (fun () -> xs |> Array.toList |> List.sum) let a = run (fun () -> xs |> Array.sum) - s = a && l = a + consistency "sum" s l a [] let ``sum is consistent`` () = @@ -975,7 +995,7 @@ let sumBy<'a> (xs : 'a []) (f:'a -> int) = let s = run (fun () -> xs |> Seq.sumBy f) let l = run (fun () -> xs |> Array.toList |> List.sumBy f) let a = run (fun () -> xs |> Array.sumBy f) - s = a && l = a + consistency "sumBy" s l a [] let ``sumBy is consistent`` () = @@ -984,10 +1004,18 @@ let ``sumBy is consistent`` () = Check.QuickThrowOnFailure sumBy let splitAt<'a when 'a : equality> (xs : 'a []) index = - // no seq version - let l = run (fun () -> xs |> List.ofArray |> List.splitAt index |> fun (a,b) -> List.toArray a,List.toArray b) - let a = run (fun () -> xs |> Array.splitAt index) - l = a + let ls = List.ofArray xs + if index < 0 then + Prop.throws (lazy List.splitAt index ls) .&. + Prop.throws (lazy Array.splitAt index xs) + elif index > xs.Length then + Prop.throws (lazy List.splitAt index ls) .&. + Prop.throws (lazy Array.splitAt index xs) + else + // no seq version + let l = run (fun () -> ls |> List.splitAt index |> fun (a,b) -> List.toArray a,List.toArray b) + let a = run (fun () -> xs |> Array.splitAt index) + (l = a) |@ "splitAt" [] let ``splitAt is consistent`` () = @@ -996,10 +1024,16 @@ let ``splitAt is consistent`` () = Check.QuickThrowOnFailure splitAt let splitInto<'a when 'a : equality> (xs : 'a []) count = - let s = run (fun () -> xs |> Seq.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) - let l = run (fun () -> xs |> List.ofArray |> List.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) - let a = run (fun () -> xs |> Array.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) - s = a && l = a + let ls = List.ofArray xs + if count < 1 then + Prop.throws (lazy List.splitInto count ls) .&. + Prop.throws (lazy Array.splitInto count xs) .&. + Prop.throws (lazy Seq.splitInto count xs) + else + let s = run (fun () -> xs |> Seq.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) + let l = run (fun () -> ls |> List.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) + let a = run (fun () -> xs |> Array.splitInto count |> Seq.map Seq.toArray |> Seq.toArray) + consistency "splitInto" s l a [] let ``splitInto is consistent`` () = @@ -1011,7 +1045,7 @@ let tail<'a when 'a : equality> (xs : 'a []) = let s = runAndCheckIfAnyError (fun () -> xs |> Seq.tail |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> xs |> List.ofArray |> List.tail |> Seq.toArray) let a = runAndCheckIfAnyError (fun () -> xs |> Array.tail) - s = a && l = a + consistency "tail" s l a [] let ``tail is consistent`` () = @@ -1023,7 +1057,7 @@ let take<'a when 'a : equality> (xs : 'a []) count = let s = runAndCheckIfAnyError (fun () -> Seq.take count xs |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> List.take count (Seq.toList xs) |> List.toArray) let a = runAndCheckIfAnyError (fun () -> Array.take count xs) - s = a && l = a + consistency "take" s l a [] let ``take is consistent`` () = @@ -1035,7 +1069,7 @@ let takeWhile<'a when 'a : equality> (xs : 'a []) f = let s = runAndCheckIfAnyError (fun () -> Seq.takeWhile f xs |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> List.takeWhile f (Seq.toList xs) |> List.toArray) let a = runAndCheckIfAnyError (fun () -> Array.takeWhile f xs) - s = a && l = a + consistency "takeWhile" s l a [] let ``takeWhile is consistent`` () = @@ -1047,7 +1081,7 @@ let truncate<'a when 'a : equality> (xs : 'a []) count = let s = runAndCheckIfAnyError (fun () -> Seq.truncate count xs |> Seq.toArray) let l = runAndCheckIfAnyError (fun () -> List.truncate count (Seq.toList xs) |> List.toArray) let a = runAndCheckIfAnyError (fun () -> Array.truncate count xs) - s = a && l = a + consistency "truncate" s l a [] let ``truncate is consistent`` () = @@ -1059,7 +1093,7 @@ let tryFind<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.tryFind predicate let l = xs |> List.ofArray |> List.tryFind predicate let a = xs |> Array.tryFind predicate - s = a && l = a + consistency "tryFind" s l a [] let ``tryFind is consistent`` () = @@ -1071,7 +1105,7 @@ let tryFindBack<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.tryFindBack predicate let l = xs |> List.ofArray |> List.tryFindBack predicate let a = xs |> Array.tryFindBack predicate - s = a && l = a + consistency "tryFindBack" s l a [] let ``tryFindBack is consistent`` () = @@ -1083,7 +1117,7 @@ let tryFindIndex<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.tryFindIndex predicate let l = xs |> List.ofArray |> List.tryFindIndex predicate let a = xs |> Array.tryFindIndex predicate - s = a && l = a + consistency "tryFindIndex" s l a [] let ``tryFindIndex is consistent`` () = @@ -1095,7 +1129,7 @@ let tryFindIndexBack<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.tryFindIndexBack predicate let l = xs |> List.ofArray |> List.tryFindIndexBack predicate let a = xs |> Array.tryFindIndexBack predicate - s = a && l = a + consistency "tryFindIndexBack" s l a [] let ``tryFindIndexBack is consistent`` () = @@ -1107,7 +1141,7 @@ let tryHead<'a when 'a : equality> (xs : 'a []) = let s = xs |> Seq.tryHead let l = xs |> List.ofArray |> List.tryHead let a = xs |> Array.tryHead - s = a && l = a + consistency "tryHead" s l a [] let ``tryHead is consistent`` () = @@ -1119,7 +1153,7 @@ let tryItem<'a when 'a : equality> (xs : 'a []) index = let s = xs |> Seq.tryItem index let l = xs |> List.ofArray |> List.tryItem index let a = xs |> Array.tryItem index - s = a && l = a + consistency "tryItem" s l a [] let ``tryItem is consistent`` () = @@ -1131,7 +1165,7 @@ let tryLast<'a when 'a : equality> (xs : 'a []) = let s = xs |> Seq.tryLast let l = xs |> List.ofArray |> List.tryLast let a = xs |> Array.tryLast - s = a && l = a + consistency "tryLast" s l a [] let ``tryLast is consistent`` () = @@ -1143,7 +1177,7 @@ let tryPick<'a when 'a : comparison> (xs : 'a []) f = let s = xs |> Seq.tryPick f let l = xs |> List.ofArray |> List.tryPick f let a = xs |> Array.tryPick f - s = a && l = a + consistency "tryPick" s l a [] let ``tryPick is consistent`` () = @@ -1158,12 +1192,10 @@ let unfold<'a,'b when 'b : equality> f (start:'a) = if !c > 100 then None else // prevent infinity seqs c := !c + 1 f x - - let s : 'b [] = Seq.unfold (f()) start |> Seq.toArray let l = List.unfold (f()) start |> List.toArray let a = Array.unfold (f()) start - s = a && l = a + consistency "unfold" s l a [] @@ -1202,10 +1234,10 @@ let ``unzip3 is consistent`` () = Check.QuickThrowOnFailure unzip3 let where<'a when 'a : equality> (xs : 'a []) predicate = - let s = xs |> Seq.where predicate - let l = xs |> List.ofArray |> List.where predicate + let s = xs |> Seq.where predicate |> Seq.toArray + let l = xs |> List.ofArray |> List.where predicate |> List.toArray let a = xs |> Array.where predicate - Seq.toArray s = a && List.toArray l = a + consistency "where" s l a [] let ``where is consistent`` () = @@ -1214,10 +1246,16 @@ let ``where is consistent`` () = Check.QuickThrowOnFailure where let windowed<'a when 'a : equality> (xs : 'a []) windowSize = - let s = run (fun () -> xs |> Seq.windowed windowSize |> Seq.toArray |> Array.map Seq.toArray) - let l = run (fun () -> xs |> List.ofArray |> List.windowed windowSize |> List.toArray |> Array.map Seq.toArray) - let a = run (fun () -> xs |> Array.windowed windowSize) - s = a && l = a + let ls = List.ofArray xs + if windowSize < 1 then + Prop.throws (lazy Seq.windowed windowSize xs) .&. + Prop.throws (lazy Array.windowed windowSize xs) .&. + Prop.throws (lazy List.windowed windowSize ls) + else + let s = run (fun () -> xs |> Seq.windowed windowSize |> Seq.toArray |> Array.map Seq.toArray) + let l = run (fun () -> ls |> List.windowed windowSize |> List.toArray |> Array.map Seq.toArray) + let a = run (fun () -> xs |> Array.windowed windowSize) + consistency "windowed" s l a [] let ``windowed is consistent`` () = @@ -1231,7 +1269,7 @@ let zip<'a when 'a : equality> (xs':('a*'a) []) = let s = runAndCheckErrorType (fun () -> Seq.zip xs xs2 |> Seq.toArray) let l = runAndCheckErrorType (fun () -> List.zip (List.ofSeq xs) (List.ofSeq xs2) |> List.toArray) let a = runAndCheckErrorType (fun () -> Array.zip (Array.ofSeq xs) (Array.ofSeq xs2)) - s = a && l = a + consistency "zip" s l a [] let ``zip is consistent for collections with equal length`` () = @@ -1246,7 +1284,7 @@ let zip3<'a when 'a : equality> (xs':('a*'a*'a) []) = let s = runAndCheckErrorType (fun () -> Seq.zip3 xs xs2 xs3 |> Seq.toArray) let l = runAndCheckErrorType (fun () -> List.zip3 (List.ofSeq xs) (List.ofSeq xs2) (List.ofSeq xs3) |> List.toArray) let a = runAndCheckErrorType (fun () -> Array.zip3 (Array.ofSeq xs) (Array.ofSeq xs2) (Array.ofSeq xs3)) - s = a && l = a + consistency "zip3" s l a [] let ``zip3 is consistent for collections with equal length`` () = diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs index ea2be48ea48..064cc457643 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs @@ -777,7 +777,7 @@ type ListModule() = let group_byEmpty = List.groupBy funcInt emptyList let expectedEmptyList = [] - Assert.AreEqual(expectedEmptyList, emptyList) + Assert.AreEqual(expectedEmptyList, group_byEmpty) () diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs index b1e725aaee4..75dc5cd8662 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs @@ -259,7 +259,20 @@ type AsyncType() = with :? System.OperationCanceledException -> return true } - Async.RunSynchronously(test()) |> Assert.IsTrue + Async.RunSynchronously(test()) |> Assert.IsTrue + + [] + member this.AwaitTaskCancellationUntyped () = + let test() = async { + let tcs = new System.Threading.Tasks.TaskCompletionSource() + tcs.SetCanceled() + try + do! Async.AwaitTask (tcs.Task :> Task) + return false + with :? System.OperationCanceledException -> return true + } + + Async.RunSynchronously(test()) |> Assert.IsTrue [] member this.TaskAsyncValueException () = diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs index 61eb5529685..10c4389cb95 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.coreclr.fs @@ -2546,6 +2546,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs index d11d57cc752..37c48c87ae4 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net20.fs @@ -2412,6 +2412,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs index ac3f56789f3..c452c3f31c4 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.net40.fs @@ -2576,6 +2576,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs index 49d61b4e4df..8e5337ef4a8 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable259.fs @@ -2551,6 +2551,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs index b4273af515b..531eebf0e8f 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable47.fs @@ -2553,6 +2553,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs index ca4c5b16765..7d320ad8483 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable7.fs @@ -2564,6 +2564,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs index 2edaa153891..f731fcdbcc0 100644 --- a/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs +++ b/src/fsharp/FSharp.Core.Unittests/SurfaceArea.portable78.fs @@ -2551,6 +2551,7 @@ Microsoft.FSharp.Core.Operators+Unchecked: System.Type GetType() Microsoft.FSharp.Core.Operators+Unchecked: T DefaultOf[T]() Microsoft.FSharp.Core.Operators+Unchecked: T Unbox[T](System.Object) Microsoft.FSharp.Core.Operators: Boolean Equals(System.Object) +Microsoft.FSharp.Core.Operators: Boolean IsNotNull[T](T) Microsoft.FSharp.Core.Operators: Boolean IsNull[T](T) Microsoft.FSharp.Core.Operators: Boolean Not(Boolean) Microsoft.FSharp.Core.Operators: Boolean op_Equality[T](T, T) diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs index 97bb22506e9..d935f78b935 100644 --- a/src/fsharp/FSharp.Core/array.fs +++ b/src/fsharp/FSharp.Core/array.fs @@ -46,18 +46,18 @@ namespace Microsoft.FSharp.Collections else Some array.[array.Length-1] [] - let inline init count f = Array.init count f + let inline init count f = Array.init count f [] let zeroCreate count = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count Array.zeroCreateUnchecked count [] let create (count:int) (x:'T) = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count let array: 'T[] = Array.zeroCreateUnchecked count - for i = 0 to Operators.Checked.(-) count 1 do // use checked arithmetic here to satisfy FxCop + for i = 0 to Operators.Checked.(-) array.Length 1 do // use checked arithmetic here to satisfy FxCop array.[i] <- x array @@ -75,9 +75,8 @@ namespace Microsoft.FSharp.Collections [] let tail (array : 'T[]) = checkNonNull "array" array - if array.Length = 0 then invalidArg "array" (SR.GetString(SR.notEnoughElements)) - let len = array.Length - 1 - Array.subUnchecked 1 len array + if array.Length = 0 then invalidArg "array" (SR.GetString(SR.notEnoughElements)) + Array.subUnchecked 1 (array.Length - 1) array [] let empty<'T> : 'T [] = [| |] @@ -86,22 +85,21 @@ namespace Microsoft.FSharp.Collections [] let inline blit (source : 'T[]) (sourceIndex:int) (target: 'T[]) (targetIndex:int) (count:int) = Array.Copy(source, sourceIndex, target, targetIndex, count) - - let rec concatAddLengths (arrs:'T[][]) i acc = - if i >= arrs.Length then acc - else concatAddLengths arrs (i+1) (acc + arrs.[i].Length) - - let rec concatBlit (arrs:'T[][]) i j (tgt:'T[]) = - if i < arrs.Length then - let h = arrs.[i] - let len = h.Length - Array.Copy(h, 0, tgt, j, len) - concatBlit arrs (i+1) (j+len) tgt + + let concatArrays (arrs : 'T[][]) : 'T[] = + let mutable acc = 0 + for h in arrs do + acc <- acc + h.Length - let concatArrays (arrs : 'T[][]) = - let res = Array.zeroCreateUnchecked (concatAddLengths arrs 0 0) - concatBlit arrs 0 0 res - res + let res = Array.zeroCreateUnchecked acc + + let mutable j = 0 + for i = 0 to arrs.Length-1 do + let h = arrs.[i] + let len = h.Length + Array.Copy(h,0,res,j,len) + j <- j + len + res [] let concat (arrays: seq<'T[]>) = @@ -112,9 +110,9 @@ namespace Microsoft.FSharp.Collections [] let replicate count x = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count let arr : 'T array = Array.zeroCreateUnchecked count - for i = 0 to count - 1 do + for i = 0 to arr.Length-1 do arr.[i] <- x arr @@ -123,14 +121,14 @@ namespace Microsoft.FSharp.Collections checkNonNull "array" array let len = array.Length let result = Array.zeroCreateUnchecked<'U[]> len - for i = 0 to len - 1 do + for i = 0 to result.Length-1 do result.[i] <- f array.[i] concatArrays result [] let splitAt index (array:'T[]) = checkNonNull "array" array - if index < 0 then invalidArg "index" (SR.GetString(SR.inputMustBeNonNegative)) + if index < 0 then invalidArgInputMustBeNonNegative "index" index if array.Length < index then raise <| InvalidOperationException (SR.GetString(SR.notEnoughElements)) if index = 0 then let right = Array.subUnchecked 0 array.Length array @@ -147,7 +145,7 @@ namespace Microsoft.FSharp.Collections [] let take count (array : 'T[]) = checkNonNull "array" array - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count if count = 0 then empty else @@ -239,18 +237,16 @@ namespace Microsoft.FSharp.Collections [] let indexed (array: 'T[]) = - checkNonNull "array" array - let len = array.Length - let res = Array.zeroCreateUnchecked len - for i = 0 to len - 1 do + checkNonNull "array" array + let res = Array.zeroCreateUnchecked array.Length + for i = 0 to res.Length-1 do res.[i] <- (i,array.[i]) res [] let inline iter f (array: 'T[]) = - checkNonNull "array" array - let len = array.Length - for i = 0 to len - 1 do + checkNonNull "array" array + for i = 0 to array.Length-1 do f array.[i] [] @@ -269,10 +265,9 @@ namespace Microsoft.FSharp.Collections [] let inline map (f: 'T -> 'U) (array:'T[]) = - checkNonNull "array" array - let len = array.Length - let res : 'U[] = Array.zeroCreateUnchecked len - for i = 0 to len - 1 do + checkNonNull "array" array + let res : 'U[] = Array.zeroCreateUnchecked array.Length + for i = 0 to res.Length-1 do res.[i] <- f array.[i] res @@ -281,9 +276,8 @@ namespace Microsoft.FSharp.Collections checkNonNull "array1" array1 checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)); - for i = 0 to len1 - 1 do + if array1.Length <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + for i = 0 to array1.Length-1 do f.Invoke(array1.[i], array2.[i]) [] @@ -304,10 +298,9 @@ namespace Microsoft.FSharp.Collections checkNonNull "array1" array1 checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)); - let res = Array.zeroCreateUnchecked len1 - for i = 0 to len1 - 1 do + if array1.Length <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + let res = Array.zeroCreateUnchecked array1.Length + for i = 0 to res.Length-1 do res.[i] <- f.Invoke(array1.[i], array2.[i]) res @@ -318,10 +311,10 @@ namespace Microsoft.FSharp.Collections checkNonNull "array3" array3 let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) let len1 = array1.Length - if not (len1 = array2.Length && len1 = array3.Length) then invalidArg "" (SR.GetString(SR.arraysHadDifferentLengths)) + if len1 <> array2.Length || len1 <> array3.Length then invalidArg3ArraysDifferent "array1" "array2" "array3" len1 array2.Length array3.Length let res = Array.zeroCreateUnchecked len1 - for i = 0 to len1 - 1 do + for i = 0 to res.Length-1 do res.[i] <- f.Invoke(array1.[i], array2.[i], array3.[i]) res @@ -330,19 +323,17 @@ namespace Microsoft.FSharp.Collections checkNonNull "array1" array1 checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)); - let res = Array.zeroCreateUnchecked len1 - for i = 0 to len1 - 1 do + if array1.Length <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + let res = Array.zeroCreateUnchecked array1.Length + for i = 0 to res.Length-1 do res.[i] <- f.Invoke(i,array1.[i], array2.[i]) res [] let iteri f (array:'T[]) = checkNonNull "array" array - let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let len = array.Length - for i = 0 to len - 1 do + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) + for i = 0 to array.Length-1 do f.Invoke(i, array.[i]) [] @@ -350,18 +341,16 @@ namespace Microsoft.FSharp.Collections checkNonNull "array1" array1 checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)); - for i = 0 to len1 - 1 do + if array1.Length <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + for i = 0 to array1.Length-1 do f.Invoke(i,array1.[i], array2.[i]) [] let mapi (f : int -> 'T -> 'U) (array: 'T[]) = checkNonNull "array" array - let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let len = array.Length - let res = Array.zeroCreateUnchecked len - for i = 0 to len - 1 do + let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) + let res = Array.zeroCreateUnchecked array.Length + for i = 0 to array.Length-1 do res.[i] <- f.Invoke(i,array.[i]) res @@ -398,7 +387,7 @@ namespace Microsoft.FSharp.Collections checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)) + if len1 <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length let rec loop i = i < len1 && (f.Invoke(array1.[i], array2.[i]) || loop (i+1)) loop 0 @@ -415,7 +404,7 @@ namespace Microsoft.FSharp.Collections checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)) + if len1 <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length let rec loop i = i >= len1 || (f.Invoke(array1.[i], array2.[i]) && loop (i+1)) loop 0 @@ -483,30 +472,91 @@ namespace Microsoft.FSharp.Collections loop 0 [] - let choose f (array: _[]) = - checkNonNull "array" array - let res = Array.zeroCreateUnchecked array.Length - let mutable count = 0 - for x in array do - match f x with - | None -> () - | Some b -> res.[count] <- b - count <- count + 1 - Array.subUnchecked 0 count res - + let choose (f: 'T -> 'U Option) (array: 'T[]) = + checkNonNull "array" array + + let mutable i = 0 + let mutable first = Unchecked.defaultof<'U> + let mutable found = false + while i < array.Length && not found do + let element = array.[i] + match f element with + | None -> i <- i + 1 + | Some b -> first <- b; found <- true + + if i <> array.Length then + + let chunk1 : 'U[] = Array.zeroCreateUnchecked ((array.Length >>> 2) + 1) + chunk1.[0] <- first + let mutable count = 1 + i <- i + 1 + while count < chunk1.Length && i < array.Length do + let element = array.[i] + match f element with + | None -> () + | Some b -> chunk1.[count] <- b + count <- count + 1 + i <- i + 1 + + if i < array.Length then + let chunk2 : 'U[] = Array.zeroCreateUnchecked (array.Length-i) + count <- 0 + while i < array.Length do + let element = array.[i] + match f element with + | None -> () + | Some b -> chunk2.[count] <- b + count <- count + 1 + i <- i + 1 + + let res : 'U[] = Array.zeroCreateUnchecked (chunk1.Length + count) + Array.Copy(chunk1,res,chunk1.Length) + Array.Copy(chunk2,0,res,chunk1.Length,count) + res + else + Array.subUnchecked 0 count chunk1 + else + empty [] - let filter f (array: _[]) = - checkNonNull "array" array - let res = Array.zeroCreateUnchecked array.Length - let mutable count = 0 - for x in array do - if f x then - res.[count] <- x - count <- count + 1 - Array.subUnchecked 0 count res - + let filter f (array: _[]) = + checkNonNull "array" array + let mutable i = 0 + while i < array.Length && not (f array.[i]) do + i <- i + 1 + + if i <> array.Length then + let mutable element = array.[i] + let chunk1 : 'T[] = Array.zeroCreateUnchecked (((array.Length-i) >>> 2) + 1) + let mutable count = 1 + chunk1.[0] <- element + i <- i + 1 + while count < chunk1.Length && i < array.Length do + element <- array.[i] + if f element then + chunk1.[count] <- element + count <- count + 1 + i <- i + 1 + + if i < array.Length then + let chunk2 = Array.zeroCreateUnchecked (array.Length-i) + count <- 0 + while i < array.Length do + element <- array.[i] + if f element then + chunk2.[count] <- element + count <- count + 1 + i <- i + 1 + + let res : 'T[] = Array.zeroCreateUnchecked (chunk1.Length + count) + Array.Copy(chunk1,res,chunk1.Length) + Array.Copy(chunk2,0,res,chunk1.Length,count) + res + else + Array.subUnchecked 0 count chunk1 + else empty + [] let where f (array: _[]) = filter f array @@ -564,7 +614,7 @@ namespace Microsoft.FSharp.Collections [] let skip count (array:'T[]) = checkNonNull "array" array - if count > array.Length then invalidArg "count" (SR.GetString(SR.outOfRange)) + if count > array.Length then invalidArgOutOfRange "count" count "array.Length" array.Length if count = array.Length then empty else @@ -572,13 +622,12 @@ namespace Microsoft.FSharp.Collections Array.subUnchecked count (array.Length - count) array [] - let skipWhile p (array: 'T[]) = + let skipWhile p (array: 'T[]) = checkNonNull "array" array - let mutable i = 0 - let len = array.Length - while i < len && p array.[i] do i <- i + 1 + let mutable i = 0 + while i < array.Length && p array.[i] do i <- i + 1 - match len - i with + match array.Length - i with | 0 -> empty | resLen -> Array.subUnchecked i resLen array @@ -605,7 +654,7 @@ namespace Microsoft.FSharp.Collections [] let windowed windowSize (array:'T[]) = checkNonNull "array" array - if windowSize <= 0 then invalidArg "windowSize" (SR.GetString(SR.inputMustBePositive)) + if windowSize <= 0 then invalidArgInputMustBePositive "windowSize" windowSize let len = array.Length if windowSize > len then empty @@ -618,7 +667,7 @@ namespace Microsoft.FSharp.Collections [] let chunkBySize chunkSize (array:'T[]) = checkNonNull "array" array - if chunkSize <= 0 then invalidArg "chunkSize" (SR.GetString(SR.inputMustBePositive)) + if chunkSize <= 0 then invalidArgInputMustBePositive "chunkSize" chunkSize let len = array.Length if len = 0 then empty @@ -636,7 +685,7 @@ namespace Microsoft.FSharp.Collections [] let splitInto count (array:_[]) = checkNonNull "array" array - if count <= 0 then invalidArg "count" (SR.GetString(SR.inputMustBePositive)) + if count <= 0 then invalidArgInputMustBePositive "count" count Array.splitInto count array [] @@ -644,9 +693,9 @@ namespace Microsoft.FSharp.Collections checkNonNull "array1" array1 checkNonNull "array2" array2 let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)) + if len1 <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length let res = Array.zeroCreateUnchecked len1 - for i = 0 to len1 - 1 do + for i = 0 to res.Length-1 do res.[i] <- (array1.[i],array2.[i]) res @@ -656,10 +705,9 @@ namespace Microsoft.FSharp.Collections checkNonNull "array2" array2 checkNonNull "array3" array3 let len1 = array1.Length - if len1 <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)) - if len1 <> array3.Length then invalidArg "array3" (SR.GetString(SR.arraysHadDifferentLengths)) + if len1 <> array2.Length || len1 <> array3.Length then invalidArg3ArraysDifferent "array1" "array2" "array3" len1 array2.Length array3.Length let res = Array.zeroCreateUnchecked len1 - for i = 0 to len1 - 1 do + for i = 0 to res.Length-1 do res.[i] <- (array1.[i],array2.[i],array3.[i]) res @@ -670,8 +718,8 @@ namespace Microsoft.FSharp.Collections let len1 = array1.Length let len2 = array2.Length let res = Array.zeroCreateUnchecked (len1 * len2) - for i = 0 to len1 - 1 do - for j = 0 to len2 - 1 do + for i = 0 to array1.Length-1 do + for j = 0 to array2.Length-1 do res.[i * len2 + j] <- (array1.[i],array2.[j]) res @@ -693,7 +741,7 @@ namespace Microsoft.FSharp.Collections let len = array.Length let res1 = Array.zeroCreateUnchecked len let res2 = Array.zeroCreateUnchecked len - for i = 0 to len - 1 do + for i = 0 to array.Length-1 do let x,y = array.[i] res1.[i] <- x res2.[i] <- y @@ -706,7 +754,7 @@ namespace Microsoft.FSharp.Collections let res1 = Array.zeroCreateUnchecked len let res2 = Array.zeroCreateUnchecked len let res3 = Array.zeroCreateUnchecked len - for i = 0 to len - 1 do + for i = 0 to array.Length-1 do let x,y,z = array.[i] res1.[i] <- x res2.[i] <- y @@ -715,20 +763,20 @@ namespace Microsoft.FSharp.Collections [] let rev (array: _[]) = - checkNonNull "array" array - let len = array.Length - let res = Array.zeroCreateUnchecked len - for i = 0 to len - 1 do - res.[(len - i) - 1] <- array.[i] + checkNonNull "array" array + let res = Array.zeroCreateUnchecked array.Length + let mutable j = array.Length-1 + for i = 0 to array.Length-1 do + res.[j] <- array.[i] + j <- j - 1 res [] let fold<'T,'State> (f : 'State -> 'T -> 'State) (acc: 'State) (array:'T[]) = checkNonNull "array" array let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable state = acc - let len = array.Length - for i = 0 to len - 1 do + let mutable state = acc + for i = 0 to array.Length-1 do state <- f.Invoke(state,array.[i]) state @@ -736,9 +784,8 @@ namespace Microsoft.FSharp.Collections let foldBack<'T,'State> (f : 'T -> 'State -> 'State) (array:'T[]) (acc: 'State) = checkNonNull "array" array let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable res = acc - let len = array.Length - for i = len - 1 downto 0 do + let mutable res = acc + for i = array.Length-1 downto 0 do res <- f.Invoke(array.[i],res) res @@ -750,8 +797,8 @@ namespace Microsoft.FSharp.Collections let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) let mutable res = acc let len = array1.Length - if len <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)) - for i = len - 1 downto 0 do + if len <> array2.Length then invalidArgDifferentArrayLength "array1" len "array2" array2.Length + for i = len-1 downto 0 do res <- f.Invoke(array1.[i],array2.[i],res) res @@ -761,9 +808,8 @@ namespace Microsoft.FSharp.Collections checkNonNull "array2" array2 let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) let mutable state = acc - let len = array1.Length - if len <> array2.Length then invalidArg "array2" (SR.GetString(SR.arraysHadDifferentLengths)) - for i = 0 to len - 1 do + if array1.Length <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + for i = 0 to array1.Length-1 do state <- f.Invoke(state,array1.[i],array2.[i]) state @@ -782,7 +828,7 @@ namespace Microsoft.FSharp.Collections let mutable state = initState let res = create (2+fin-start) initState for i = start to fin do - state <- f.Invoke(state,array.[i]); + state <- f.Invoke(state,array.[i]) res.[i - start+1] <- state res @@ -815,7 +861,7 @@ namespace Microsoft.FSharp.Collections else let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) let mutable res = array.[0] - for i = 1 to len - 1 do + for i = 1 to array.Length-1 do res <- f.Invoke(res,array.[i]) res @@ -835,7 +881,7 @@ namespace Microsoft.FSharp.Collections let c = f array.[0] array.[1] if c > 0 then let tmp = array.[0] - array.[0] <- array.[1]; + array.[0] <- array.[1] array.[1] <- tmp else Array.Sort(array, ComparisonIdentity.FromFunction(f)) @@ -918,9 +964,9 @@ namespace Microsoft.FSharp.Collections Array.permute p array [] - let inline sum (array: (^T)[] ) : ^T = + let inline sum (array: ^T[] ) : ^T = checkNonNull "array" array - let mutable acc = LanguagePrimitives.GenericZero< (^T) > + let mutable acc = LanguagePrimitives.GenericZero< ^T> for i = 0 to array.Length - 1 do acc <- Checked.(+) acc array.[i] acc @@ -928,7 +974,7 @@ namespace Microsoft.FSharp.Collections [] let inline sumBy (f: 'T -> ^U) (array:'T[]) : ^U = checkNonNull "array" array - let mutable acc = LanguagePrimitives.GenericZero< (^U) > + let mutable acc = LanguagePrimitives.GenericZero< ^U> for i = 0 to array.Length - 1 do acc <- Checked.(+) acc (f array.[i]) acc @@ -987,43 +1033,51 @@ namespace Microsoft.FSharp.Collections let inline average (array:'T[]) = checkNonNull "array" array if array.Length = 0 then invalidArg "array" LanguagePrimitives.ErrorStrings.InputArrayEmptyString - let mutable acc = LanguagePrimitives.GenericZero< (^T) > + let mutable acc = LanguagePrimitives.GenericZero< ^T> for i = 0 to array.Length - 1 do acc <- Checked.(+) acc array.[i] - LanguagePrimitives.DivideByInt< (^T) > acc array.Length + LanguagePrimitives.DivideByInt< ^T> acc array.Length [] - let inline averageBy f (array:_[]) = + let inline averageBy (f : 'T -> ^U) (array:'T[]) : ^U = checkNonNull "array" array - Seq.averageBy f array + if array.Length = 0 then invalidArg "array" LanguagePrimitives.ErrorStrings.InputArrayEmptyString + let mutable acc = LanguagePrimitives.GenericZero< ^U> + for i = 0 to array.Length - 1 do + acc <- Checked.(+) acc (f array.[i]) + LanguagePrimitives.DivideByInt< ^U> acc array.Length [] let inline compareWith (comparer:'T -> 'T -> int) (array1: 'T[]) (array2: 'T[]) = checkNonNull "array1" array1 checkNonNull "array2" array2 - + let length1 = array1.Length let length2 = array2.Length - let minLength = Operators.min length1 length2 - - let rec loop index = - if index = minLength then - if length1 = length2 then 0 - elif length1 < length2 then -1 - else 1 - else - let result = comparer array1.[index] array2.[index] - if result <> 0 then result else - loop (index+1) + + let mutable i = 0 + let mutable result = 0 + + if length1 < length2 then + while i < array1.Length && result = 0 do + result <- comparer array1.[i] array2.[i] + i <- i + 1 + else + while i < array2.Length && result = 0 do + result <- comparer array1.[i] array2.[i] + i <- i + 1 - loop 0 + if result <> 0 then result + elif length1 = length2 then 0 + elif length1 < length2 then -1 + else 1 [] let sub (array:'T[]) (startIndex:int) (count:int) = checkNonNull "array" array - if startIndex < 0 then invalidArg "startIndex" (SR.GetString(SR.inputMustBeNonNegative)) - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) - if startIndex + count > array.Length then invalidArg "count" (SR.GetString(SR.outOfRange)) + if startIndex < 0 then invalidArgInputMustBeNonNegative "startIndex" startIndex + if count < 0 then invalidArgInputMustBeNonNegative "count" count + if startIndex + count > array.Length then invalidArgOutOfRange "count" count "array.Length" array.Length Array.subUnchecked startIndex count array [] @@ -1047,8 +1101,8 @@ namespace Microsoft.FSharp.Collections [] let fill (target:'T[]) (targetIndex:int) (count:int) (x:'T) = checkNonNull "target" target - if targetIndex < 0 then invalidArg "targetIndex" (SR.GetString(SR.inputMustBeNonNegative)) - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if targetIndex < 0 then invalidArgInputMustBeNonNegative "targetIndex" targetIndex + if count < 0 then invalidArgInputMustBeNonNegative "count" count for i = targetIndex to targetIndex + count - 1 do target.[i] <- x @@ -1076,28 +1130,27 @@ namespace Microsoft.FSharp.Collections [] let choose f (array: 'T[]) = checkNonNull "array" array - let inputLength = array.Length - let lastInputIndex = inputLength - 1 + let inputLength = array.Length let isChosen : bool [] = Array.zeroCreateUnchecked inputLength - let results : 'U [] = Array.zeroCreateUnchecked inputLength - - Parallel.For(0, inputLength, (fun i -> - match f array.[i] with - | None -> () - | Some v -> - isChosen.[i] <- true; - results.[i] <- v - )) |> ignore - - let mutable outputLength = 0 - for i = 0 to lastInputIndex do - if isChosen.[i] then - outputLength <- outputLength + 1 - + let results : 'U [] = Array.zeroCreateUnchecked inputLength + let mutable outputLength = 0 + Parallel.For(0, + inputLength, + (fun () ->0), + (fun i _ count -> + match f array.[i] with + | None -> count + | Some v -> + isChosen.[i] <- true; + results.[i] <- v + count+1), + Action (fun x -> System.Threading.Interlocked.Add(&outputLength,x) |> ignore ) + ) |> ignore + let output = Array.zeroCreateUnchecked outputLength let mutable curr = 0 - for i = 0 to lastInputIndex do + for i = 0 to isChosen.Length-1 do if isChosen.[i] then output.[curr] <- results.[i] curr <- curr + 1 @@ -1151,29 +1204,33 @@ namespace Microsoft.FSharp.Collections [] let partition predicate (array : 'T[]) = checkNonNull "array" array - let inputLength = array.Length - let lastInputIndex = inputLength - 1 + let inputLength = array.Length + + let isTrue = Array.zeroCreateUnchecked inputLength + let mutable trueLength = 0 + Parallel.For(0, + inputLength, + (fun () -> 0), + (fun i _ trueCount -> + if predicate array.[i] then + isTrue.[i] <- true + trueCount + 1 + else + trueCount), + Action (fun x -> System.Threading.Interlocked.Add(&trueLength,x) |> ignore) ) |> ignore + + let res1 = Array.zeroCreateUnchecked trueLength + let res2 = Array.zeroCreateUnchecked (inputLength - trueLength) - let isTrue = Array.zeroCreateUnchecked inputLength - Parallel.For(0, inputLength, - fun i -> isTrue.[i] <- predicate array.[i] - ) |> ignore - - let mutable trueLength = 0 - for i in 0 .. lastInputIndex do - if isTrue.[i] then trueLength <- trueLength + 1 - - let trueResult = Array.zeroCreateUnchecked trueLength - let falseResult = Array.zeroCreateUnchecked (inputLength - trueLength) let mutable iTrue = 0 let mutable iFalse = 0 - for i = 0 to lastInputIndex do + for i = 0 to isTrue.Length-1 do if isTrue.[i] then - trueResult.[iTrue] <- array.[i] + res1.[iTrue] <- array.[i] iTrue <- iTrue + 1 else - falseResult.[iFalse] <- array.[i] + res2.[iFalse] <- array.[i] iFalse <- iFalse + 1 - (trueResult, falseResult) + res1, res2 #endif diff --git a/src/fsharp/FSharp.Core/array2.fs b/src/fsharp/FSharp.Core/array2.fs index bcab855a895..4eb258c7210 100644 --- a/src/fsharp/FSharp.Core/array2.fs +++ b/src/fsharp/FSharp.Core/array2.fs @@ -37,8 +37,8 @@ namespace Microsoft.FSharp.Collections [] let zeroCreate (n:int) (m:int) = - if n < 0 then invalidArg "n" (SR.GetString(SR.inputMustBeNonNegative)) - if m < 0 then invalidArg "m" (SR.GetString(SR.inputMustBeNonNegative)) + if n < 0 then invalidArgInputMustBeNonNegative "length1" n + if m < 0 then invalidArgInputMustBeNonNegative "length2" m (# "newarr.multi 2 !0" type ('T) n m : 'T[,] #) [] @@ -130,17 +130,27 @@ namespace Microsoft.FSharp.Collections init (length1 array) (length2 array) (fun i j -> array.[b1+i,b2+j]) [] - let blit (source : 'T[,]) sourceIndex1 sourceIndex2 (target : 'T[,]) targetIndex1 targetIndex2 count1 count2 = + let blit (source : 'T[,]) sourceIndex1 sourceIndex2 (target: 'T[,]) targetIndex1 targetIndex2 count1 count2 = checkNonNull "source" source checkNonNull "target" target - if sourceIndex1 < source.GetLowerBound(0) then invalidArg "sourceIndex1" (SR.GetString(SR.outOfRange)) - if sourceIndex2 < source.GetLowerBound(1) then invalidArg "sourceIndex2" (SR.GetString(SR.outOfRange)) - if targetIndex1 < target.GetLowerBound(0) then invalidArg "targetIndex1" (SR.GetString(SR.outOfRange)) - if targetIndex2 < target.GetLowerBound(1) then invalidArg "targetIndex2" (SR.GetString(SR.outOfRange)) - if sourceIndex1 + count1 > (length1 source) + source.GetLowerBound(0) then invalidArg "count1" (SR.GetString(SR.outOfRange)) - if sourceIndex2 + count2 > (length2 source) + source.GetLowerBound(1) then invalidArg "count2" (SR.GetString(SR.outOfRange)) - if targetIndex1 + count1 > (length1 target) + target.GetLowerBound(0) then invalidArg "count1" (SR.GetString(SR.outOfRange)) - if targetIndex2 + count2 > (length2 target) + target.GetLowerBound(1) then invalidArg "count2" (SR.GetString(SR.outOfRange)) + + let sourceX0, sourceY0 = source.GetLowerBound 0 , source.GetLowerBound 1 + let sourceXN, sourceYN = (length1 source) + sourceX0, (length2 source) + sourceY0 + let targetX0, targetY0 = target.GetLowerBound 0 , target.GetLowerBound 1 + let targetXN, targetYN = (length1 target) + targetX0, (length2 target) + targetY0 + + if sourceIndex1 < sourceX0 then invalidArgOutOfRange "sourceIndex1" sourceIndex1 "source axis-0 lower bound" sourceX0 + if sourceIndex2 < sourceY0 then invalidArgOutOfRange "sourceIndex2" sourceIndex2 "source axis-1 lower bound" sourceY0 + if targetIndex1 < targetX0 then invalidArgOutOfRange "targetIndex1" targetIndex1 "target axis-0 lower bound" targetX0 + if targetIndex2 < targetY0 then invalidArgOutOfRange "targetIndex2" targetIndex2 "target axis-1 lower bound" targetY0 + if sourceIndex1 + count1 > sourceXN then + invalidArgOutOfRange "count1" count1 ("source axis-0 end index = " + string(sourceIndex1+count1) + " source axis-0 upper bound") sourceXN + if sourceIndex2 + count2 > sourceYN then + invalidArgOutOfRange "count2" count2 ("source axis-1 end index = " + string(sourceIndex2+count2) + " source axis-1 upper bound") sourceYN + if targetIndex1 + count1 > targetXN then + invalidArgOutOfRange "count1" count1 ("target axis-0 end index = " + string(targetIndex1+count1) + " target axis-0 upper bound") targetXN + if targetIndex2 + count2 > targetYN then + invalidArgOutOfRange "count2" count2 ("target axis-1 end index = " + string(targetIndex2+count2) + " target axis-1 upper bound") targetYN for i = 0 to count1 - 1 do for j = 0 to count2 - 1 do diff --git a/src/fsharp/FSharp.Core/array3.fs b/src/fsharp/FSharp.Core/array3.fs index db94d654894..9c1e6d826c1 100644 --- a/src/fsharp/FSharp.Core/array3.fs +++ b/src/fsharp/FSharp.Core/array3.fs @@ -35,9 +35,9 @@ namespace Microsoft.FSharp.Collections [] let zeroCreate (n1:int) (n2:int) (n3:int) = - if n1 < 0 then invalidArg "n1" (SR.GetString(SR.inputMustBeNonNegative)) - if n2 < 0 then invalidArg "n2" (SR.GetString(SR.inputMustBeNonNegative)) - if n3 < 0 then invalidArg "n3" (SR.GetString(SR.inputMustBeNonNegative)) + if n1 < 0 then invalidArgInputMustBeNonNegative "n1" n1 + if n2 < 0 then invalidArgInputMustBeNonNegative "n2" n2 + if n3 < 0 then invalidArgInputMustBeNonNegative "n3" n3 (# "newarr.multi 3 !0" type ('T) n1 n2 n3 : 'T[,,] #) [] @@ -127,10 +127,10 @@ namespace Microsoft.FSharp.Collections [] let zeroCreate (n1:int) (n2:int) (n3:int) (n4:int) = - if n1 < 0 then invalidArg "n1" (SR.GetString(SR.inputMustBeNonNegative)) - if n2 < 0 then invalidArg "n2" (SR.GetString(SR.inputMustBeNonNegative)) - if n3 < 0 then invalidArg "n3" (SR.GetString(SR.inputMustBeNonNegative)) - if n4 < 0 then invalidArg "n4" (SR.GetString(SR.inputMustBeNonNegative)) + if n1 < 0 then invalidArgInputMustBeNonNegative "n1" n1 + if n2 < 0 then invalidArgInputMustBeNonNegative "n2" n2 + if n3 < 0 then invalidArgInputMustBeNonNegative "n3" n3 + if n4 < 0 then invalidArgInputMustBeNonNegative "n4" n4 (# "newarr.multi 4 !0" type ('T) n1 n2 n3 n4 : 'T[,,,] #) [] @@ -156,7 +156,7 @@ namespace Microsoft.FSharp.Collections [] - let get (array: 'T[,,,]) n1 n2 n3 n4 = array.[n1,n2,n3,n4] + let get (array: 'T[,,,]) n1 n2 n3 n4 = array.[n1,n2,n3,n4] [] - let set (array: 'T[,,,]) n1 n2 n3 n4 x = array.[n1,n2,n3,n4] <- x + let set (array: 'T[,,,]) n1 n2 n3 n4 x = array.[n1,n2,n3,n4] <- x diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs index 0cef9daf773..6f58a8c47e0 100644 --- a/src/fsharp/FSharp.Core/control.fs +++ b/src/fsharp/FSharp.Core/control.fs @@ -50,7 +50,7 @@ namespace System.Threading member this.Equals(ctr:CancellationTokenRegistration) = match this.source with - | null -> ctr.source = null + | null -> isNull ctr.source | _ -> this.source.Equals(ctr.source) && this.id = ctr.id override this.Equals(o:obj) = @@ -91,7 +91,7 @@ namespace System.Threading member this.Equals(ct:CancellationToken) = match this.source with - | null -> ct.source = null + | null -> isNull ct.source | _ -> this.source.Equals(ct.source) override this.Equals(o:obj) = @@ -1548,12 +1548,13 @@ namespace Microsoft.FSharp.Control // Contains helpers that will attach continuation to the given task. // Should be invoked as a part of protectedPrimitive(withResync) call module TaskHelpers = - let continueWith (task : Task<'T>, args) = + let continueWith (task : Task<'T>, args, useCcontForTaskCancellation) = let continuation (completedTask : Task<_>) : unit = args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then - args.aux.econt (ExceptionDispatchInfo.Capture(new OperationCanceledException())) + if useCcontForTaskCancellation then args.aux.ccont(new OperationCanceledException()) + else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException())) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) else @@ -1561,12 +1562,13 @@ namespace Microsoft.FSharp.Control task.ContinueWith(Action>(continuation), TaskContinuationOptions.None) |> ignore |> fake - let continueWithUnit (task : Task, args) = + let continueWithUnit (task : Task, args, useCcontForTaskCancellation) = let continuation (completedTask : Task) : unit = args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then - args.aux.ccont (new OperationCanceledException()) + if useCcontForTaskCancellation then args.aux.ccont (new OperationCanceledException()) + else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException())) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) else @@ -1623,7 +1625,7 @@ namespace Microsoft.FSharp.Control null match edi with - | null -> TaskHelpers.continueWithUnit(task, args) + | null -> TaskHelpers.continueWithUnit (task, args, true) | _ -> aux.econt edi ) #else @@ -2117,12 +2119,12 @@ namespace Microsoft.FSharp.Control #else static member AwaitTask (task:Task<'T>) : Async<'T> = protectedPrimitiveWithResync (fun args -> - TaskHelpers.continueWith(task, args) + TaskHelpers.continueWith(task, args, false) ) static member AwaitTask (task:Task) : Async = protectedPrimitiveWithResync (fun args -> - TaskHelpers.continueWithUnit(task, args) + TaskHelpers.continueWithUnit (task, args, false) ) #endif @@ -2139,7 +2141,7 @@ namespace Microsoft.FSharp.Control #if FX_NO_BEGINEND_READWRITE // use combo protectedPrimitiveWithResync + continueWith instead of AwaitTask so we can pass cancellation token to the ReadAsync task protectedPrimitiveWithResync (fun ({ aux = aux } as args) -> - TaskHelpers.continueWith(stream.ReadAsync(buffer, offset, count, aux.token), args) + TaskHelpers.continueWith(stream.ReadAsync(buffer, offset, count, aux.token), args, false) ) #else Async.FromBeginEnd (buffer,offset,count,stream.BeginRead,stream.EndRead) @@ -2163,7 +2165,7 @@ namespace Microsoft.FSharp.Control #if FX_NO_BEGINEND_READWRITE // use combo protectedPrimitiveWithResync + continueWith instead of AwaitTask so we can pass cancellation token to the WriteAsync task protectedPrimitiveWithResync ( fun ({ aux = aux} as args) -> - TaskHelpers.continueWithUnit(stream.WriteAsync(buffer, offset, count, aux.token), args) + TaskHelpers.continueWithUnit(stream.WriteAsync(buffer, offset, count, aux.token), args, false) ) #else Async.FromBeginEnd (buffer,offset,count,stream.BeginWrite,stream.EndWrite) @@ -2226,7 +2228,7 @@ namespace Microsoft.FSharp.Control event.RemoveHandler handle if args.Cancelled then ccont (new OperationCanceledException()) - elif args.Error <> null then + elif isNotNull args.Error then econt args.Error else cont (result args) @@ -2513,8 +2515,8 @@ namespace Microsoft.FSharp.Control | Some res -> return res } interface System.IDisposable with - member x.Dispose() = - if pulse <> null then (pulse :> IDisposable).Dispose() + member __.Dispose() = + if isNotNull pulse then (pulse :> IDisposable).Dispose() #if DEBUG member x.UnsafeContents = diff --git a/src/fsharp/FSharp.Core/list.fs b/src/fsharp/FSharp.Core/list.fs index 608e4f6fd34..e616c92eaa5 100644 --- a/src/fsharp/FSharp.Core/list.fs +++ b/src/fsharp/FSharp.Core/list.fs @@ -153,7 +153,7 @@ namespace Microsoft.FSharp.Collections let nth list index = item index list [] - let choose f xs = Microsoft.FSharp.Primitives.Basics.List.choose f xs + let choose f xs = List.choose f xs [] let splitAt index (list:'T list) = List.splitAt index list @@ -185,7 +185,8 @@ namespace Microsoft.FSharp.Collections match list1,list2 with | [],[] -> () | h1::t1, h2::t2 -> f.Invoke(h1,h2); loop t1 t2 - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length loop list1 list2 [] @@ -195,7 +196,8 @@ namespace Microsoft.FSharp.Collections match list1,list2 with | [],[] -> () | h1::t1, h2::t2 -> f.Invoke(n,h1,h2); loop (n+1) t1 t2 - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length loop 0 list1 list2 [] @@ -223,7 +225,7 @@ namespace Microsoft.FSharp.Collections [] let pairwise (list: 'T list) = - Microsoft.FSharp.Primitives.Basics.List.pairwise list + List.pairwise list [] let reduce f list = @@ -245,7 +247,8 @@ namespace Microsoft.FSharp.Collections match list1,list2 with | [],[] -> acc | h1::t1, h2::t2 -> loop (f.Invoke(acc,h1,h2)) t1 t2 - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length loop acc list1 list2 let foldArraySubRight (f:OptimizedClosures.FSharpFunc<'T,_,_>) (arr: 'T[]) start fin acc = @@ -308,7 +311,10 @@ namespace Microsoft.FSharp.Collections let arr2 = toArray list2 let n1 = arr1.Length let n2 = arr2.Length - if n1 <> n2 then invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)); + if n1 <> n2 then + invalidArgFmt "list1, list2" + "{0}\nlist1.Length = {1}, list2.Length = {2}" + [|SR.GetString SR.listsHadDifferentLengths; arr1.Length; arr2.Length|] let mutable res = acc for i = n1 - 1 downto 0 do res <- f.Invoke(arr1.[i],arr2.[i],res) @@ -326,13 +332,15 @@ namespace Microsoft.FSharp.Collections | [h2;h3],[k2;k3] -> f.Invoke(h1,k1,f.Invoke(h2,k2,f.Invoke(h3,k3,acc))) | [h2;h3;h4],[k2;k3;k4] -> f.Invoke(h1,k1,f.Invoke(h2,k2,f.Invoke(h3,k3,f.Invoke(h4,k4,acc)))) | _ -> foldBack2UsingArrays f list1 list2 acc - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length let rec forall2aux (f:OptimizedClosures.FSharpFunc<_,_,_>) list1 list2 = match list1,list2 with | [],[] -> true | h1::t1, h2::t2 -> f.Invoke(h1,h2) && forall2aux f t1 t2 - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length [] let forall2 f list1 list2 = @@ -419,28 +427,7 @@ namespace Microsoft.FSharp.Collections let where f x = List.filter f x let inline groupByImpl (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (list: 'T list) = - let dict = Dictionary<_,ResizeArray<_>> comparer - - // Build the groupings - let rec loop list = - match list with - | v :: t -> - let safeKey = keyf v - let mutable prev = Unchecked.defaultof<_> - if dict.TryGetValue(safeKey, &prev) then - prev.Add v - else - let prev = ResizeArray () - dict.[safeKey] <- prev - prev.Add v - loop t - | _ -> () - loop list - - // Return the list-of-lists. - dict - |> Seq.map (fun group -> (getKey group.Key, Seq.toList group.Value)) - |> Seq.toList + List.groupBy comparer keyf getKey list // We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance let groupByValueType (keyf:'T->'Key) (list:'T list) = groupByImpl HashIdentity.Structural<'Key> keyf id list @@ -489,7 +476,7 @@ namespace Microsoft.FSharp.Collections match lst with | _ when i = 0 -> lst | _::t -> loop (i-1) t - | [] -> invalidArg "count" (SR.GetString(SR.outOfRange)) + | [] -> invalidArgOutOfRange "count" count "distance past the list" i loop count list [] diff --git a/src/fsharp/FSharp.Core/local.fs b/src/fsharp/FSharp.Core/local.fs index fb234f75eee..6232d9ec3d4 100644 --- a/src/fsharp/FSharp.Core/local.fs +++ b/src/fsharp/FSharp.Core/local.fs @@ -1,5 +1,76 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.FSharp.Core +[] +module internal DetailedExceptions = + open System + open Microsoft.FSharp.Core + + /// takes an argument, a formatting string, a param array to splice into the formatting string + let inline invalidArgFmt (arg:string) (format:string) paramArray = + let msg = String.Format (format,paramArray) + raise (new ArgumentException (msg,arg)) + + /// takes a formatting string and a param array to splice into the formatting string + let inline invalidOpFmt (format:string) paramArray = + let msg = String.Format (format,paramArray) + raise (new InvalidOperationException(msg)) + + /// throws an invalid argument exception and returns the difference between the lists' lengths + let invalidArgDifferentListLength (arg1:string) (arg2:string) (diff:int) = + invalidArgFmt arg1 + "{0}\n{1} is {2} {3} shorter than {4}" + [|SR.GetString SR.listsHadDifferentLengths; arg1; diff; (if diff=1 then "element" else "elements"); arg2|] + + /// throws an invalid argument exception and returns the length of the 3 arrays + let invalidArg3ListsDifferent (arg1:string) (arg2:string) (arg3:string) (len1:int) (len2:int) (len3:int) = + invalidArgFmt (String.Concat [|arg1; ", "; arg2; ", "; arg3|]) + "{0}\n {1}.Length = {2}, {3}.Length = {4}, {5}.Length = {6}" + [|SR.GetString SR.listsHadDifferentLengths; arg1; len1; arg2; len2; arg3; len3|] + + /// throws an invalid operation exception and returns how many elements the + /// list is shorter than the index + let invalidOpListNotEnoughElements (index:int) = + invalidOpFmt + "{0}\nThe list was {1} {2} shorter than the index" + [|SR.GetString SR.notEnoughElements; index; (if index=1 then "element" else "elements")|] + + + /// eg. tried to {skip} {2} {elements} past the end of the seq. Seq.Length = {10} + let invalidOpExceededSeqLength (fnName:string) (diff:int) (len:int) = + invalidOpFmt "{0}\ntried to {1} {2} {3} past the end of the seq\nSeq.Length = {4}" + [|SR.GetString SR.notEnoughElements; fnName; diff; (if diff=1 then "element" else "elements");len|] + + /// throws an invalid argument exception and returns the arg's value + let inline invalidArgInputMustBeNonNegative (arg:string) (count:int) = + invalidArgFmt arg "{0}\n{1} = {2}" [|LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString ; arg; count|] + + /// throws an invalid argument exception and returns the arg's value + let inline invalidArgInputMustBePositive (arg:string) (count:int) = + invalidArgFmt arg "{0}\n{1} = {2}" [|SR.GetString SR.inputMustBePositive; arg; count|] + + /// throws an invalid argument exception and returns the out of range index, + /// a text description of the range, and the bound of the range + /// e.g. sourceIndex = -4, source axis-0 lower bound = 0" + let invalidArgOutOfRange (arg:string) (index:int) (text:string) (bound:int) = + invalidArgFmt arg + "{0}\n{1} = {2}, {3} = {4}" + [|SR.GetString SR.outOfRange; arg; index; text; bound|] + + /// throws an invalid argument exception and returns the difference between the lists' lengths + let invalidArgDifferentArrayLength (arg1:string) (len1:int) (arg2:string) (len2:int) = + invalidArgFmt arg1 + "{0}\n{1}.Length = {2}, {3}.Length = {4}" + [|SR.GetString SR.arraysHadDifferentLengths; arg1; len1; arg2; len2 |] + + /// throws an invalid argument exception and returns the lengths of the 3 arrays + let invalidArg3ArraysDifferent (arg1:string) (arg2:string) (arg3:string) (len1:int) (len2:int) (len3:int) = + invalidArgFmt (String.Concat [|arg1; ", "; arg2; ", "; arg3|]) + "{0}\n {1}.Length = {2}, {3}.Length = {4}, {5}.Length = {6}" + [|SR.GetString SR.arraysHadDifferentLengths; arg1; len1; arg2; len2; arg3; len3|] + + namespace Microsoft.FSharp.Primitives.Basics open Microsoft.FSharp.Core @@ -32,7 +103,7 @@ module internal List = match list with | [] -> setFreshConsTail cons [] | x::rest -> - if hashSet.Add(x) then + if hashSet.Add x then let cons2 = freshConsNoTail x setFreshConsTail cons cons2 distinctToFreshConsTail cons2 hashSet rest @@ -45,7 +116,7 @@ module internal List = | [h] -> [h] | x::rest -> let hashSet = HashSet<'T>(comparer) - hashSet.Add(x) |> ignore + hashSet.Add x |> ignore let cons = freshConsNoTail x distinctToFreshConsTail cons hashSet rest cons @@ -125,7 +196,42 @@ module internal List = let cons = freshConsNoTail x chooseToFreshConsTail cons f t cons - + + let groupBy (comparer:IEqualityComparer<'SafeKey>) (keyf:'T->'SafeKey) (getKey:'SafeKey->'Key) (list: 'T list) = + let dict = Dictionary<_, _ list []> comparer + + // Build the groupings + let rec loop list = + match list with + | v :: t -> + let safeKey = keyf v + match dict.TryGetValue(safeKey) with + | true, prev -> + let cons2 = freshConsNoTail v + setFreshConsTail prev.[1] cons2 + prev.[1] <- cons2 + | _ -> let res = freshConsNoTail v + dict.[safeKey] <- [|res; res |] // First index stores the result list; second index is the most recent cons. + + loop t + | _ -> () + loop list + + let mutable ie = dict.GetEnumerator() + if not (ie.MoveNext()) then [] + else + let mutable curr = ie.Current + setFreshConsTail curr.Value.[1] [] + let res = freshConsNoTail (getKey curr.Key, curr.Value.[0]) + let mutable cons = res + while ie.MoveNext() do + curr <- ie.Current + setFreshConsTail curr.Value.[1] [] + let cons2 = freshConsNoTail (getKey curr.Key, curr.Value.[0]) + setFreshConsTail cons cons2 + cons <- cons2 + setFreshConsTail cons [] + res let rec mapToFreshConsTail cons f x = match x with @@ -172,7 +278,8 @@ module internal List = let cons2 = freshConsNoTail (f.Invoke(h1,h2)) setFreshConsTail cons cons2 map2ToFreshConsTail cons2 f t1 t2 - | _ -> invalidArg "xs2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length let map2 f xs1 xs2 = match xs1,xs2 with @@ -182,7 +289,8 @@ module internal List = let cons = freshConsNoTail (f.Invoke(h1,h2)) map2ToFreshConsTail cons f t1 t2 cons - | _ -> invalidArg "xs2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length let rec map3ToFreshConsTail cons (f:OptimizedClosures.FSharpFunc<_,_,_,_>) xs1 xs2 xs3 = match xs1,xs2,xs3 with @@ -192,7 +300,8 @@ module internal List = let cons2 = freshConsNoTail (f.Invoke(h1,h2,h3)) setFreshConsTail cons cons2 map3ToFreshConsTail cons2 f t1 t2 t3 - | _ -> invalidArg "list3" (SR.GetString(SR.listsHadDifferentLengths)) + | xs1,xs2,xs3 -> + invalidArg3ListsDifferent "list1" "list2" "list3" xs1.Length xs2.Length xs3.Length let map3 f xs1 xs2 xs3 = match xs1,xs2,xs3 with @@ -202,7 +311,8 @@ module internal List = let cons = freshConsNoTail (f.Invoke(h1,h2,h3)) map3ToFreshConsTail cons f t1 t2 t3 cons - | _ -> invalidArg "list3" (SR.GetString(SR.listsHadDifferentLengths)) + | xs1,xs2,xs3 -> + invalidArg3ListsDifferent "list1" "list2" "list3" xs1.Length xs2.Length xs3.Length let rec mapi2ToFreshConsTail n cons (f:OptimizedClosures.FSharpFunc<_,_,_,_>) xs1 xs2 = match xs1,xs2 with @@ -212,7 +322,8 @@ module internal List = let cons2 = freshConsNoTail (f.Invoke(n,h1,h2)) setFreshConsTail cons cons2 mapi2ToFreshConsTail (n + 1) cons2 f t1 t2 - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length let mapi2 f xs1 xs2 = match xs1,xs2 with @@ -222,7 +333,8 @@ module internal List = let cons = freshConsNoTail (f.Invoke(0, h1,h2)) mapi2ToFreshConsTail 1 cons f t1 t2 cons - | _ -> invalidArg "list2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length let rec scanToFreshConsTail cons xs s (f: OptimizedClosures.FSharpFunc<_,_,_>) = match xs with @@ -426,10 +538,9 @@ module internal List = loop 0 l res - let ofArray (arr:'T[]) = - let len = arr.Length + let ofArray (arr:'T[]) = let mutable res = ([]: 'T list) - for i = len - 1 downto 0 do + for i = arr.Length-1 downto 0 do res <- arr.[i] :: res res @@ -467,7 +578,7 @@ module internal List = let init count f = - if count < 0 then invalidArg "count" LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString + if count < 0 then invalidArgInputMustBeNonNegative "count" count if count = 0 then [] else let res = freshConsNoTail (f 0) @@ -477,17 +588,17 @@ module internal List = let rec takeFreshConsTail cons n l = if n = 0 then setFreshConsTail cons [] else match l with - | [] -> raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) + | [] -> invalidOpListNotEnoughElements n | x::xs -> let cons2 = freshConsNoTail x setFreshConsTail cons cons2 takeFreshConsTail cons2 (n - 1) xs let take n l = - if n < 0 then invalidArg "count" LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString + if n < 0 then invalidArgInputMustBeNonNegative "count" n if n = 0 then [] else match l with - | [] -> raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) + | [] -> invalidOpListNotEnoughElements n | x::xs -> let cons = freshConsNoTail x takeFreshConsTail cons (n - 1) xs @@ -499,18 +610,20 @@ module internal List = l else match l with - | [] -> raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) + | [] -> invalidOpListNotEnoughElements index | x :: xs -> let cons2 = freshConsNoTail x setFreshConsTail cons cons2 splitAtFreshConsTail cons2 (index - 1) xs let splitAt index l = - if index < 0 then invalidArg "index" (SR.GetString(SR.inputMustBeNonNegative)) + if index < 0 then invalidArgInputMustBeNonNegative "index" index if index = 0 then [], l else match l with - | [] -> raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) - | [_] -> if index = 1 then l, [] else raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) + | [] -> invalidOp (SR.GetString SR.inputListWasEmpty) + | [_] -> + if index = 1 then l, [] else + invalidOpListNotEnoughElements (index-1) | x::xs -> if index = 1 then [x], xs else let cons = freshConsNoTail x @@ -673,7 +786,7 @@ module internal List = windowedToFreshConsTail cons2 windowSize (i - 1) list.Tail let windowed windowSize (list: 'T list) = - if windowSize <= 0 then invalidArg "windowSize" (SR.GetString(SR.inputMustBePositive)) + if windowSize <= 0 then invalidArgInputMustBePositive "windowSize" windowSize let len = list.Length if windowSize > len then [] @@ -699,7 +812,7 @@ module internal List = chunkBySizeToFreshConsTail cons resCons chunkSize (i+1) t let chunkBySize chunkSize list = - if chunkSize <= 0 then invalidArg "chunkSize" (SR.GetString(SR.inputMustBePositive)) + if chunkSize <= 0 then invalidArgInputMustBePositive "chunkSize" chunkSize match list with | [] -> [] | head::tail -> @@ -725,7 +838,7 @@ module internal List = splitIntoToFreshConsTail cons resCons lenDivCount lenModCount i (j + 1) t let splitInto count (list: _ list) = - if count <= 0 then invalidArg "count" (SR.GetString(SR.inputMustBePositive)) + if count <= 0 then invalidArgInputMustBePositive "count" count match list.Length with | 0 -> [] | len -> @@ -745,8 +858,8 @@ module internal List = let cons2 = freshConsNoTail (h1,h2) setFreshConsTail cons cons2 zipToFreshConsTail cons2 t1 t2 - | _ -> - invalidArg "xs2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length // optimized mutation-based implementation. This code is only valid in fslib, where mutation of private // tail cons cells is permitted in carefully written library code. @@ -757,8 +870,8 @@ module internal List = let res = freshConsNoTail (h1,h2) zipToFreshConsTail res t1 t2 res - | _ -> - invalidArg "xs2" (SR.GetString(SR.listsHadDifferentLengths)) + | [],xs2 -> invalidArgDifferentListLength "list1" "list2" xs2.Length + | xs1,[] -> invalidArgDifferentListLength "list2" "list1" xs1.Length // optimized mutation-based implementation. This code is only valid in fslib, where mutation of private // tail cons cells is permitted in carefully written library code. @@ -770,8 +883,8 @@ module internal List = let cons2 = freshConsNoTail (h1,h2,h3) setFreshConsTail cons cons2 zip3ToFreshConsTail cons2 t1 t2 t3 - | _ -> - invalidArg "xs1" (SR.GetString(SR.listsHadDifferentLengths)) + | xs1,xs2,xs3 -> + invalidArg3ListsDifferent "list1" "list2" "list3" xs1.Length xs2.Length xs3.Length // optimized mutation-based implementation. This code is only valid in fslib, where mutation of private // tail cons cells is permitted in carefully written library code. @@ -783,8 +896,8 @@ module internal List = let res = freshConsNoTail (h1,h2,h3) zip3ToFreshConsTail res t1 t2 t3 res - | _ -> - invalidArg "xs1" (SR.GetString(SR.listsHadDifferentLengths)) + | xs1,xs2,xs3 -> + invalidArg3ListsDifferent "list1" "list2" "list3" xs1.Length xs2.Length xs3.Length let rec takeWhileFreshConsTail cons p l = match l with @@ -891,9 +1004,9 @@ module internal Array = (# "newarr !0" type ('T) count : 'T array #) let inline init (count:int) (f: int -> 'T) = - if count < 0 then invalidArg "count" LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString + if count < 0 then invalidArgInputMustBeNonNegative "count" count let arr = (zeroCreateUnchecked count : 'T array) - for i = 0 to count - 1 do + for i = 0 to arr.Length-1 do arr.[i] <- f i arr @@ -946,7 +1059,7 @@ module internal Array = let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) let mutable acc = acc let res = zeroCreateUnchecked len - for i = 0 to len - 1 do + for i = 0 to array.Length-1 do let h',s' = f.Invoke(acc,array.[i]) res.[i] <- h' acc <- s' @@ -1056,7 +1169,7 @@ module internal Array = let inline subUnchecked startIndex count (array : 'T[]) = let res = zeroCreateUnchecked count : 'T[] if count < 64 then - for i = 0 to count - 1 do + for i = 0 to res.Length-1 do res.[i] <- array.[startIndex+i] else Array.Copy(array, startIndex, res, 0, count) diff --git a/src/fsharp/FSharp.Core/local.fsi b/src/fsharp/FSharp.Core/local.fsi index 245ae8eabc5..dcf8f2a6e15 100644 --- a/src/fsharp/FSharp.Core/local.fsi +++ b/src/fsharp/FSharp.Core/local.fsi @@ -1,5 +1,22 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +namespace Microsoft.FSharp.Core +open Microsoft.FSharp.Core + +[] +module internal DetailedExceptions = + val inline invalidArgFmt: arg:string -> format:string -> paramArray:obj array -> _ + val inline invalidOpFmt: format:string -> paramArray:obj array -> _ + val invalidArgDifferentListLength: arg1:string -> arg2:string -> diff:int -> _ + val invalidArg3ListsDifferent: arg1:string -> arg2:string -> arg3:string -> len1:int -> len2:int -> len3:int -> _ + val invalidOpListNotEnoughElements: index:int -> _ + val invalidOpExceededSeqLength: fnName:string -> diff:int -> len: int -> _ + val inline invalidArgInputMustBeNonNegative: arg:string -> count:int -> _ + val inline invalidArgInputMustBePositive: arg:string -> count:int -> _ + val invalidArgOutOfRange: arg:string -> index:int -> text:string -> bound:int -> _ + val invalidArgDifferentArrayLength: arg1:string -> len1:int -> arg2:string -> len2:int -> _ + val invalidArg3ArraysDifferent: arg1:string -> arg2:string -> arg3:string -> len1:int -> len2:int -> len3:int -> _ + /// Definitions internal for this library. namespace Microsoft.FSharp.Primitives.Basics @@ -11,6 +28,7 @@ module internal List = val choose: ('T -> 'U option) -> 'T list -> 'U list val countBy : System.Collections.Generic.Dictionary<'T1, int> -> ('T1 -> 'T2) -> ('T2 * int) list val pairwise : 'T list -> ('T * 'T) list + val groupBy : System.Collections.Generic.IEqualityComparer<'SafeKey> -> ('T->'SafeKey) -> ('SafeKey->'Key) -> 'T list -> ('Key*'T list) list val distinctWithComparer : System.Collections.Generic.IEqualityComparer<'T> -> 'T list -> 'T list val distinctByWithComparer : System.Collections.Generic.IEqualityComparer<'Key> -> ('T -> 'Key) -> list:'T list -> 'T list when 'Key : equality val init : int -> (int -> 'T) -> 'T list diff --git a/src/fsharp/FSharp.Core/math/z.fs b/src/fsharp/FSharp.Core/math/z.fs index ae03db625d1..286e11f5143 100644 --- a/src/fsharp/FSharp.Core/math/z.fs +++ b/src/fsharp/FSharp.Core/math/z.fs @@ -305,7 +305,7 @@ namespace System.Numerics | _ -> invalidArg "x" "signs should be +/- 1 or 0" static member Parse(text:string) = - if text = null then raise (new ArgumentNullException("text")) + if isNull text then raise (new ArgumentNullException("text")) let text = text.Trim() let len = text.Length if len = 0 then raise (new System.FormatException(SR.GetString(SR.badFormatString))) diff --git a/src/fsharp/FSharp.Core/option.fs b/src/fsharp/FSharp.Core/option.fs index 391355aab1c..3bca435ce6b 100644 --- a/src/fsharp/FSharp.Core/option.fs +++ b/src/fsharp/FSharp.Core/option.fs @@ -11,13 +11,13 @@ namespace Microsoft.FSharp.Core let get option = match option with None -> invalidArg "option" (SR.GetString(SR.optionValueWasNone)) | Some x -> x [] - let isSome option = match option with None -> false | Some _ -> true + let inline isSome option = match option with None -> false | Some _ -> true [] - let isNone option = match option with None -> true | Some _ -> false + let inline isNone option = match option with None -> true | Some _ -> false [] - let count option = match option with None -> 0 | Some _ -> 1 + let count option = match option with None -> 0 | Some _ -> 1 [] let fold<'T,'State> f (s:'State) (inp: option<'T>) = match inp with None -> s | Some x -> f s x diff --git a/src/fsharp/FSharp.Core/option.fsi b/src/fsharp/FSharp.Core/option.fsi index 27432956f03..3225893e284 100644 --- a/src/fsharp/FSharp.Core/option.fsi +++ b/src/fsharp/FSharp.Core/option.fsi @@ -11,18 +11,17 @@ namespace Microsoft.FSharp.Core [] /// Basic operations on options. module Option = - /// Returns true if the option is not None. /// The input option. /// True if the option is not None. [] - val isSome: option:'T option -> bool + val inline isSome: option:'T option -> bool /// Returns true if the option is None. /// The input option. /// True if the option is None. [] - val isNone: option:'T option -> bool + val inline isNone: option:'T option -> bool /// Gets the value associated with the option. /// The input option. diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 551537cbc87..a3b0f055e1d 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3804,6 +3804,12 @@ namespace Microsoft.FSharp.Core | null -> true | _ -> false + [] + let inline isNotNull (value : 'T) = + match value with + | null -> false + | _ -> true + [] let raise (e: exn) = (# "throw" e : 'T #) @@ -4122,7 +4128,7 @@ namespace Microsoft.FSharp.Core #if FX_NO_CHAR_PARSE // replace System.Char.Parse let inline charParse (s: string) = - if s = null then raise (System.ArgumentNullException()) + if isNull s then raise (System.ArgumentNullException()) elif s.Length = 1 then s.[0] else raise (System.FormatException "String must be exactly one character long.") #endif diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index ee2b08f356b..616be0f73e7 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -2150,6 +2150,12 @@ namespace Microsoft.FSharp.Core /// True when value is null, false otherwise. [] val inline isNull : value:'T -> bool when 'T : null + + /// Determines whether the given value is not null. + /// The value to check. + /// True when value is not null, false otherwise. + [] + val inline isNotNull : value:'T -> bool when 'T : null /// Throw a System.Exception exception. /// The exception message. diff --git a/src/fsharp/FSharp.Core/printf.fs b/src/fsharp/FSharp.Core/printf.fs index 7aece24c5d4..26c9647b86e 100644 --- a/src/fsharp/FSharp.Core/printf.fs +++ b/src/fsharp/FSharp.Core/printf.fs @@ -490,7 +490,10 @@ module internal PrintfImpl = let invariantCulture = System.Globalization.CultureInfo.InvariantCulture let inline boolToString v = if v then "true" else "false" - let inline stringToSafeString v = if v = null then "" else v + let inline stringToSafeString v = + match v with + | null -> "" + | _ -> v [] let DefaultPrecision = 6 @@ -933,10 +936,7 @@ module internal PrintfImpl = System.Diagnostics.Debug.Assert((i = n), "i = n") buf.[i] <- ty buf - go ty 0 - - [] - let ContinuationOnStack = -1 + go ty 0 type private PrintfBuilderStack() = let args = Stack(10) @@ -948,7 +948,7 @@ module internal PrintfImpl = arr.[start + i] <- s.Pop() arr - member this.GetArgumentAndTypesAsArrays + member __.GetArgumentAndTypesAsArrays ( argsArraySize, argsArrayStartPos, argsArrayTotalCount, typesArraySize, typesArrayStartPos, typesArrayTotalCount @@ -957,7 +957,7 @@ module internal PrintfImpl = let typesArray = stackToArray typesArraySize typesArrayStartPos typesArrayTotalCount types argsArray, typesArray - member this.PopContinuationWithType() = + member __.PopContinuationWithType() = System.Diagnostics.Debug.Assert(args.Count = 1, "args.Count = 1") System.Diagnostics.Debug.Assert(types.Count = 1, "types.Count = 1") @@ -966,7 +966,7 @@ module internal PrintfImpl = cont, contTy - member this.PopValueUnsafe() = args.Pop() + member __.PopValueUnsafe() = args.Pop() member this.PushContinuationWithType (cont : obj, contTy : Type) = System.Diagnostics.Debug.Assert(this.IsEmpty, "this.IsEmpty") @@ -980,17 +980,17 @@ module internal PrintfImpl = this.PushArgumentWithType(cont, contTy) - member this.PushArgument(value : obj) = + member __.PushArgument(value : obj) = args.Push value - member this.PushArgumentWithType(value : obj, ty) = + member __.PushArgumentWithType(value : obj, ty) = args.Push value types.Push ty - member this.HasContinuationOnStack(expectedNumberOfArguments) = + member __.HasContinuationOnStack(expectedNumberOfArguments) = types.Count = expectedNumberOfArguments + 1 - member this.IsEmpty = + member __.IsEmpty = System.Diagnostics.Debug.Assert(args.Count = types.Count, "args.Count = types.Count") args.Count = 0 @@ -1001,25 +1001,30 @@ module internal PrintfImpl = type private PrintfBuilder<'S, 'Re, 'Res>() = let mutable count = 0 - - let verifyMethodInfoWasTaken (_mi : System.Reflection.MemberInfo) = #if DEBUG - if _mi = null then + let verifyMethodInfoWasTaken (mi : System.Reflection.MemberInfo) = + if isNull mi then ignore (System.Diagnostics.Debugger.Launch()) #else - () #endif let buildSpecialChained(spec : FormatSpecifier, argTys : Type[], prefix : string, tail : obj, retTy) = if spec.TypeChar = 'a' then let mi = typeof>.GetMethod("LittleAChained", NonPublicStatics) +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif + let mi = mi.MakeGenericMethod([| argTys.[1]; retTy |]) let args = [| box prefix; tail |] mi.Invoke(null, args) elif spec.TypeChar = 't' then let mi = typeof>.GetMethod("TChained", NonPublicStatics) +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif let mi = mi.MakeGenericMethod([| retTy |]) let args = [| box prefix; tail |] mi.Invoke(null, args) @@ -1031,9 +1036,10 @@ module internal PrintfImpl = let prefix = if spec.TypeChar = '%' then "PercentStarChained" else "StarChained" let name = prefix + (string n) typeof>.GetMethod(name, NonPublicStatics) - +#if DEBUG verifyMethodInfoWasTaken mi - +#else +#endif let argTypes, args = if spec.TypeChar = '%' then [| retTy |], [| box prefix; tail |] @@ -1048,13 +1054,19 @@ module internal PrintfImpl = let buildSpecialFinal(spec : FormatSpecifier, argTys : Type[], prefix : string, suffix : string) = if spec.TypeChar = 'a' then let mi = typeof>.GetMethod("LittleAFinal", NonPublicStatics) +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif let mi = mi.MakeGenericMethod(argTys.[1] : Type) let args = [| box prefix; box suffix |] mi.Invoke(null, args) elif spec.TypeChar = 't' then let mi = typeof>.GetMethod("TFinal", NonPublicStatics) +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif let args = [| box prefix; box suffix |] mi.Invoke(null, args) else @@ -1065,8 +1077,10 @@ module internal PrintfImpl = let prefix = if spec.TypeChar = '%' then "PercentStarFinal" else "StarFinal" let name = prefix + (string n) typeof>.GetMethod(name, NonPublicStatics) - +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif let mi, args = if spec.TypeChar = '%' then @@ -1081,13 +1095,19 @@ module internal PrintfImpl = let buildPlainFinal(args : obj[], argTypes : Type[]) = let mi = typeof>.GetMethod("Final" + (argTypes.Length.ToString()), NonPublicStatics) +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif let mi = mi.MakeGenericMethod(argTypes) mi.Invoke(null, args) let buildPlainChained(args : obj[], argTypes : Type[]) = let mi = typeof>.GetMethod("Chained" + ((argTypes.Length - 1).ToString()), NonPublicStatics) +#if DEBUG verifyMethodInfoWasTaken mi +#else +#endif let mi = mi.MakeGenericMethod(argTypes) mi.Invoke(null, args) @@ -1224,7 +1244,7 @@ module internal PrintfImpl = else buildPlain n prefix - member this.Build<'T>(s : string) : PrintfFactory<'S, 'Re, 'Res, 'T> * int = + member __.Build<'T>(s : string) : PrintfFactory<'S, 'Re, 'Res, 'T> * int = parseFormatString s typeof<'T> :?> _, (2 * count + 1) // second component is used in SprintfEnv as value for internal buffer /// Type of element that is stored in cache @@ -1288,23 +1308,23 @@ module internal PrintfImpl = let buf : string[] = Array.zeroCreate n let mutable ptr = 0 - override this.Finalize() : 'Result = k (String.Concat(buf)) - override this.Write(s : string) = + override __.Finalize() : 'Result = k (String.Concat(buf)) + override __.Write(s : string) = buf.[ptr] <- s ptr <- ptr + 1 override this.WriteT(s) = this.Write s type StringBuilderPrintfEnv<'Result>(k, buf) = inherit PrintfEnv(buf) - override this.Finalize() : 'Result = k () - override this.Write(s : string) = ignore(buf.Append(s)) - override this.WriteT(()) = () + override __.Finalize() : 'Result = k () + override __.Write(s : string) = ignore(buf.Append(s)) + override __.WriteT(()) = () type TextWriterPrintfEnv<'Result>(k, tw : IO.TextWriter) = inherit PrintfEnv(tw) - override this.Finalize() : 'Result = k() - override this.Write(s : string) = tw.Write s - override this.WriteT(()) = () + override __.Finalize() : 'Result = k() + override __.Write(s : string) = tw.Write s + override __.WriteT(()) = () let inline doPrintf fmt f = let formatter, n = Cache<_, _, _, _>.Get fmt diff --git a/src/fsharp/FSharp.Core/quotations.fs b/src/fsharp/FSharp.Core/quotations.fs index 4377312f897..f333cc9c1bc 100644 --- a/src/fsharp/FSharp.Core/quotations.fs +++ b/src/fsharp/FSharp.Core/quotations.fs @@ -931,7 +931,7 @@ module Patterns = | Some methInfo -> methInfo let bindMethodHelper (parentT: Type, nm,marity,argtys,rty) = - if parentT = null then invalidArg "parentT" (SR.GetString(SR.QparentCannotBeNull)) + if isNull parentT then invalidArg "parentT" (SR.GetString(SR.QparentCannotBeNull)) if marity = 0 then let tyargTs = if parentT.IsGenericType then parentT.GetGenericArguments() else [| |] let argTs = Array.ofList (List.map (instFormal tyargTs) argtys) diff --git a/src/fsharp/FSharp.Core/reflect.fs b/src/fsharp/FSharp.Core/reflect.fs index cfff7f82422..e66038bc1f4 100644 --- a/src/fsharp/FSharp.Core/reflect.fs +++ b/src/fsharp/FSharp.Core/reflect.fs @@ -41,8 +41,6 @@ open Microsoft.FSharp.Primitives.Basics module internal Impl = - let debug = false - #if FX_RESHAPED_REFLECTION open PrimReflectionAdapters open ReflectionAdapters @@ -54,11 +52,7 @@ module internal Impl = match box v with | null -> nullArg argName | _ -> () - - - let emptyArray arr = (Array.length arr = 0) - let nonEmptyArray arr = Array.length arr > 0 - + let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer) let equivHeadTypes (ty1:Type) (ty2:Type) = @@ -68,7 +62,6 @@ module internal Impl = else ty1.Equals(ty2) - let option = typedefof let func = typedefof<(obj -> obj)> let isOptionType typ = equivHeadTypes typ (typeof) @@ -149,21 +142,21 @@ module internal Impl = let tryFindCompilationMappingAttributeFromType (typ:Type) = let assem = typ.Assembly - if assem <> null && assem.ReflectionOnly then + if isNotNull assem && assem.ReflectionOnly then tryFindCompilationMappingAttributeFromData ( typ.GetCustomAttributesData()) else tryFindCompilationMappingAttribute ( typ.GetCustomAttributes (typeof,false)) let tryFindCompilationMappingAttributeFromMemberInfo (info:MemberInfo) = let assem = info.DeclaringType.Assembly - if assem <> null && assem.ReflectionOnly then + if isNotNull assem && assem.ReflectionOnly then tryFindCompilationMappingAttributeFromData (info.GetCustomAttributesData()) else tryFindCompilationMappingAttribute (info.GetCustomAttributes (typeof,false)) let findCompilationMappingAttributeFromMemberInfo (info:MemberInfo) = let assem = info.DeclaringType.Assembly - if assem <> null && assem.ReflectionOnly then + if isNotNull assem && assem.ReflectionOnly then findCompilationMappingAttributeFromData (info.GetCustomAttributesData()) else findCompilationMappingAttribute (info.GetCustomAttributes (typeof,false)) @@ -180,9 +173,6 @@ module internal Impl = | None -> false | Some (flags,_n,_vn) -> (flags &&& SourceConstructFlags.KindMask) = SourceConstructFlags.Field - let allInstance (ps : PropertyInfo[]) = (ps, false) - let allStatic (ps : PropertyInfo[]) = (ps, true) - let tryFindSourceConstructFlagsOfType (typ:Type) = match tryFindCompilationMappingAttributeFromType typ with | None -> None @@ -283,9 +273,7 @@ module internal Impl = let unionTypeOfUnionCaseType (typ:Type,bindingFlags) = let rec get (typ:Type) = if isUnionType (typ,bindingFlags) then typ else match typ.BaseType with null -> typ | b -> get b - get typ - - let swap (x,y) = (y,x) + get typ let fieldsPropsOfUnionCase(typ:Type, tag:int, bindingFlags) = if isOptionType typ then @@ -344,15 +332,15 @@ module internal Impl = | info -> (info :> MemberInfo) let isUnionCaseNullary (typ:Type, tag:int, bindingFlags) = - let props = fieldsPropsOfUnionCase(typ, tag, bindingFlags) - emptyArray props + fieldsPropsOfUnionCase(typ, tag, bindingFlags).Length = 0 let getUnionCaseConstructorMethod (typ:Type,tag:int,bindingFlags) = let constrname = getUnionTagConverter (typ,bindingFlags) tag let methname = - if isUnionCaseNullary (typ, tag, bindingFlags) then "get_"+constrname + if isUnionCaseNullary (typ, tag, bindingFlags) then "get_" + constrname elif isListType typ || isOptionType typ then constrname - else "New"+constrname + else "New" + constrname + match typ.GetMethod(methname, BindingFlags.Static ||| bindingFlags) with | null -> raise <| System.InvalidOperationException (SR.GetString1(SR.constructorForUnionCaseNotFound, methname)) | meth -> meth @@ -372,7 +360,6 @@ module internal Impl = invalidArg "unionType" (SR.GetString1(SR.privateUnionType, unionType.FullName)) else invalidArg "unionType" (SR.GetString1(SR.notAUnionType, unionType.FullName)) - let emptyObjArray : obj[] = [| |] //----------------------------------------------------------------- // TUPLE DECOMPILATION @@ -387,11 +374,11 @@ module internal Impl = let isTupleType (typ:Type) = // Simple Name Match on typ if typ.IsEnum || typ.IsArray || typ.IsPointer then false - else tupleNames |> Seq.exists(fun n -> typ.FullName.StartsWith(n)) + else tupleNames |> Seq.exists typ.FullName.StartsWith let maxTuple = 8 // Which field holds the nested tuple? - let tupleEncField = maxTuple-1 + let tupleEncField = maxTuple - 1 let dictionaryLock = obj() let refTupleTypes = System.Collections.Generic.Dictionary() @@ -715,29 +702,29 @@ type UnionCaseInfo(typ: System.Type, tag:int) = // Cache the tag -> name map let mutable names = None let getMethInfo() = Impl.getUnionCaseConstructorMethod (typ, tag, BindingFlags.Public ||| BindingFlags.NonPublic) - member x.Name = + member __.Name = match names with | None -> (let conv = Impl.getUnionTagConverter (typ,BindingFlags.Public ||| BindingFlags.NonPublic) in names <- Some conv; conv tag) | Some conv -> conv tag - member x.DeclaringType = typ - //member x.CustomAttributes = failwith "nyi" - member x.GetFields() = + member __.DeclaringType = typ + + member __.GetFields() = let props = Impl.fieldsPropsOfUnionCase(typ,tag,BindingFlags.Public ||| BindingFlags.NonPublic) props - member x.GetCustomAttributes() = getMethInfo().GetCustomAttributes(false) + member __.GetCustomAttributes() = getMethInfo().GetCustomAttributes(false) - member x.GetCustomAttributes(attributeType) = getMethInfo().GetCustomAttributes(attributeType,false) + member __.GetCustomAttributes(attributeType) = getMethInfo().GetCustomAttributes(attributeType,false) #if FX_NO_CUSTOMATTRIBUTEDATA #else - member x.GetCustomAttributesData() = getMethInfo().GetCustomAttributesData() + member __.GetCustomAttributesData() = getMethInfo().GetCustomAttributesData() #endif - member x.Tag = tag + member __.Tag = tag override x.ToString() = typ.Name + "." + x.Name override x.GetHashCode() = typ.GetHashCode() + tag - override x.Equals(obj:obj) = + override __.Equals(obj:obj) = match obj with | :? UnionCaseInfo as uci -> uci.DeclaringType = typ && uci.Tag = tag | _ -> false @@ -831,7 +818,7 @@ type FSharpType = type DynamicFunction<'T1,'T2>() = inherit FSharpFunc obj, obj>() - override x.Invoke(impl: obj -> obj) : obj = + override __.Invoke(impl: obj -> obj) : obj = box<('T1 -> 'T2)> (fun inp -> unbox<'T2>(impl (box<'T1>(inp)))) [] diff --git a/src/fsharp/FSharp.Core/seq.fs b/src/fsharp/FSharp.Core/seq.fs index 448051fd561..919add4dc7e 100644 --- a/src/fsharp/FSharp.Core/seq.fs +++ b/src/fsharp/FSharp.Core/seq.fs @@ -14,7 +14,7 @@ namespace Microsoft.FSharp.Collections open Microsoft.FSharp.Collections open Microsoft.FSharp.Primitives.Basics - module IEnumerator = + module IEnumerator = let noReset() = raise (new System.NotSupportedException(SR.GetString(SR.resetNotSupported))) @@ -23,39 +23,39 @@ namespace Microsoft.FSharp.Collections let check started = if not started then notStarted() let dispose (r : System.IDisposable) = r.Dispose() - let cast (e : IEnumerator) : IEnumerator<'T> = - { new IEnumerator<'T> with + let cast (e : IEnumerator) : IEnumerator<'T> = + { new IEnumerator<'T> with member x.Current = unbox<'T> e.Current - interface IEnumerator with + interface IEnumerator with member x.Current = unbox<'T> e.Current :> obj member x.MoveNext() = e.MoveNext() member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = - match e with + interface System.IDisposable with + member x.Dispose() = + match e with | :? System.IDisposable as e -> e.Dispose() | _ -> () } - + /// A concrete implementation of an enumerator that returns no values [] - type EmptyEnumerator<'T>() = - let mutable started = false - interface IEnumerator<'T> with - member x.Current = - check started; + type EmptyEnumerator<'T>() = + let mutable started = false + interface IEnumerator<'T> with + member x.Current = + check started (alreadyFinished() : 'T) - - interface System.Collections.IEnumerator with - member x.Current = - check started; + + interface System.Collections.IEnumerator with + member x.Current = + check started (alreadyFinished() : obj) - member x.MoveNext() = - if not started then started <- true; + member x.MoveNext() = + if not started then started <- true false member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () - + interface System.IDisposable with + member x.Dispose() = () + let Empty<'T> () = (new EmptyEnumerator<'T>() :> IEnumerator<'T>) let rec tryItem index (e : IEnumerator<'T>) = @@ -63,15 +63,18 @@ namespace Microsoft.FSharp.Collections elif index = 0 then Some(e.Current) else tryItem (index-1) e - let rec nth index (e : IEnumerator<'T>) = - if not (e.MoveNext()) then invalidArg "index" (SR.GetString(SR.notEnoughElements)) + let rec nth index (e : IEnumerator<'T>) = + if not (e.MoveNext()) then + invalidArgFmt "index" + "{0}\nseq was short by {1} {2}" + [|SR.GetString SR.notEnoughElements; index; (if index=1 then "element" else "elements")|] if index = 0 then e.Current else nth (index-1) e [] - type MapEnumeratorState = - | NotStarted - | InProcess + type MapEnumeratorState = + | NotStarted + | InProcess | Finished [] @@ -79,20 +82,20 @@ namespace Microsoft.FSharp.Collections let mutable state = NotStarted [] val mutable private curr : 'T - + member this.GetCurrent () = match state with | NotStarted -> notStarted() | Finished -> alreadyFinished() | InProcess -> () this.curr - + abstract DoMoveNext : byref<'T> -> bool abstract Dispose : unit -> unit - + interface IEnumerator<'T> with member this.Current = this.GetCurrent() - + interface IEnumerator with member this.Current = box(this.GetCurrent()) member this.MoveNext () = @@ -105,9 +108,9 @@ namespace Microsoft.FSharp.Collections member this.Reset() = noReset() interface System.IDisposable with member this.Dispose() = this.Dispose() - + let map f (e : IEnumerator<_>) : IEnumerator<_>= - upcast + upcast { new MapEnumerator<_>() with member this.DoMoveNext (curr : byref<_>) = if e.MoveNext() then @@ -117,10 +120,10 @@ namespace Microsoft.FSharp.Collections false member this.Dispose() = e.Dispose() } - + let mapi f (e : IEnumerator<_>) : IEnumerator<_> = let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let i = ref (-1) + let i = ref (-1) upcast { new MapEnumerator<_>() with member this.DoMoveNext curr = @@ -132,22 +135,22 @@ namespace Microsoft.FSharp.Collections false member this.Dispose() = e.Dispose() } - + let map2 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) : IEnumerator<_>= let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - upcast + upcast { new MapEnumerator<_>() with - member this.DoMoveNext curr = + member this.DoMoveNext curr = let n1 = e1.MoveNext() let n2 = e2.MoveNext() if n1 && n2 then curr <- f.Invoke(e1.Current, e2.Current) true - else + else false - member this.Dispose() = - try - e1.Dispose() + member this.Dispose() = + try + e1.Dispose() finally e2.Dispose() } @@ -171,21 +174,21 @@ namespace Microsoft.FSharp.Collections e2.Dispose() } - let map3 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) (e3 : IEnumerator<_>) : IEnumerator<_> = + let map3 f (e1 : IEnumerator<_>) (e2 : IEnumerator<_>) (e3 : IEnumerator<_>) : IEnumerator<_> = let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - upcast + upcast { new MapEnumerator<_>() with - member this.DoMoveNext curr = + member this.DoMoveNext curr = let n1 = e1.MoveNext() let n2 = e2.MoveNext() let n3 = e3.MoveNext() - if n1 && n2 && n3 then + if n1 && n2 && n3 then curr <- f.Invoke(e1.Current, e2.Current, e3.Current) true else false - member this.Dispose() = + member this.Dispose() = try e1.Dispose() finally @@ -195,44 +198,44 @@ namespace Microsoft.FSharp.Collections e3.Dispose() } - let choose f (e : IEnumerator<'T>) = - let started = ref false - let curr = ref None - let get() = check !started; (match !curr with None -> alreadyFinished() | Some x -> x) - { new IEnumerator<'U> with + let choose f (e : IEnumerator<'T>) = + let started = ref false + let curr = ref None + let get() = check !started; (match !curr with None -> alreadyFinished() | Some x -> x) + { new IEnumerator<'U> with member x.Current = get() - interface IEnumerator with + interface IEnumerator with member x.Current = box (get()) - member x.MoveNext() = - if not !started then started := true; - curr := None; - while ((!curr).IsNone && e.MoveNext()) do - curr := f e.Current; + member x.MoveNext() = + if not !started then started := true + curr := None + while ((!curr).IsNone && e.MoveNext()) do + curr := f e.Current Option.isSome !curr member x.Reset() = noReset() - interface System.IDisposable with + interface System.IDisposable with member x.Dispose() = e.Dispose() } - let filter f (e : IEnumerator<'T>) = - let started = ref false - let this = - { new IEnumerator<'T> with + let filter f (e : IEnumerator<'T>) = + let started = ref false + let this = + { new IEnumerator<'T> with member x.Current = check !started; e.Current - interface IEnumerator with + interface IEnumerator with member x.Current = check !started; box e.Current - member x.MoveNext() = + member x.MoveNext() = let rec next() = - if not !started then started := true; - e.MoveNext() && (f e.Current || next()) + if not !started then started := true + e.MoveNext() && (f e.Current || next()) next() member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = e.Dispose() } + interface System.IDisposable with + member x.Dispose() = e.Dispose() } this - + let unfold f x : IEnumerator<_> = let state = ref x - upcast + upcast { new MapEnumerator<_>() with member this.DoMoveNext curr = match f !state with @@ -247,13 +250,13 @@ namespace Microsoft.FSharp.Collections let upto lastOption f = match lastOption with | Some b when b<0 -> Empty() // a request for -ve length returns empty sequence - | _ -> + | _ -> let unstarted = -1 // index value means unstarted (and no valid index) let completed = -2 // index value means completed (and no valid index) let unreachable = -3 // index is unreachable from 0,1,2,3,... let finalIndex = match lastOption with | Some b -> b // here b>=0, a valid end value. - | None -> unreachable // run "forever", well as far as Int32.MaxValue since indexing with a bounded type. + | None -> unreachable // run "forever", well as far as Int32.MaxValue since indexing with a bounded type. // The Current value for a valid index is "f i". // Lazy<_> values are used as caches, to store either the result or an exception if thrown. // These "Lazy<_>" caches are created only on the first call to current and forced immediately. @@ -264,19 +267,19 @@ namespace Microsoft.FSharp.Collections // a Lazy node to cache the result/exception let current = ref (Unchecked.defaultof<_>) let setIndex i = index := i; current := (Unchecked.defaultof<_>) // cache node unprimed, initialised on demand. - let getCurrent() = + let getCurrent() = if !index = unstarted then notStarted() if !index = completed then alreadyFinished() - match box !current with - | null -> current := Lazy<_>.Create(fun () -> f !index); + match box !current with + | null -> current := Lazy<_>.Create(fun () -> f !index) | _ -> () - // forced or re-forced immediately. - (!current).Force() - { new IEnumerator<'U> with + // forced or re-forced immediately. + (!current).Force() + { new IEnumerator<'U> with member x.Current = getCurrent() - interface IEnumerator with + interface IEnumerator with member x.Current = box (getCurrent()) - member x.MoveNext() = + member x.MoveNext() = if !index = completed then false elif !index = unstarted then @@ -291,67 +294,67 @@ namespace Microsoft.FSharp.Collections true ) member self.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () } - - let readAndClear r = + interface System.IDisposable with + member x.Dispose() = () } + + let readAndClear r = lock r (fun () -> match !r with None -> None | Some _ as res -> r := None; res) - - let generateWhileSome openf compute closef : IEnumerator<'U> = - let started = ref false + + let generateWhileSome openf compute closef : IEnumerator<'U> = + let started = ref false let curr = ref None - let state = ref (Some(openf())) - let getCurr() = - check !started; - match !curr with None -> alreadyFinished() | Some x -> x - let start() = if not !started then (started := true) + let state = ref (Some(openf())) + let getCurr() = + check !started + match !curr with None -> alreadyFinished() | Some x -> x + let start() = if not !started then (started := true) let dispose() = readAndClear state |> Option.iter closef - let finish() = (try dispose() finally curr := None) - { new IEnumerator<'U> with + let finish() = (try dispose() finally curr := None) + { new IEnumerator<'U> with member x.Current = getCurr() - interface IEnumerator with + interface IEnumerator with member x.Current = box (getCurr()) - member x.MoveNext() = - start(); - match !state with + member x.MoveNext() = + start() + match !state with | None -> false (* we started, then reached the end, then got another MoveNext *) - | Some s -> - match (try compute s with e -> finish(); reraise()) with + | Some s -> + match (try compute s with e -> finish(); reraise()) with | None -> finish(); false | Some _ as x -> curr := x; true member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = dispose() } + interface System.IDisposable with + member x.Dispose() = dispose() } [] - type ArrayEnumerator<'T>(arr: 'T array) = + type ArrayEnumerator<'T>(arr: 'T array) = let mutable curr = -1 let mutable len = arr.Length member x.Get() = - if curr >= 0 then + if curr >= 0 then if curr >= len then alreadyFinished() else arr.[curr] - else + else notStarted() - interface IEnumerator<'T> with + interface IEnumerator<'T> with member x.Current = x.Get() - interface System.Collections.IEnumerator with - member x.MoveNext() = + interface System.Collections.IEnumerator with + member x.MoveNext() = if curr >= len then false - else - curr <- curr + 1; + else + curr <- curr + 1 (curr < len) member x.Current = box(x.Get()) member x.Reset() = noReset() - interface System.IDisposable with - member x.Dispose() = () + interface System.IDisposable with + member x.Dispose() = () let ofArray arr = (new ArrayEnumerator<'T>(arr) :> IEnumerator<'T>) - [] - type Singleton<'T>(v:'T) = + [] + type Singleton<'T>(v:'T) = let mutable started = false interface IEnumerator<'T> with member x.Current = v @@ -360,11 +363,11 @@ namespace Microsoft.FSharp.Collections member x.MoveNext() = if started then false else (started <- true; true) member x.Reset() = noReset() interface System.IDisposable with - member x.Dispose() = () + member x.Dispose() = () let Singleton x = (new Singleton<'T>(x) :> IEnumerator<'T>) - let EnumerateThenFinally f (e : IEnumerator<'T>) = + let EnumerateThenFinally f (e : IEnumerator<'T>) = { new IEnumerator<'T> with member x.Current = e.Current interface IEnumerator with @@ -372,79 +375,79 @@ namespace Microsoft.FSharp.Collections member x.MoveNext() = e.MoveNext() member x.Reset() = noReset() interface System.IDisposable with - member x.Dispose() = + member x.Dispose() = try - e.Dispose() + e.Dispose() finally f() } // Use generators for some implementations of IEnumerables. // - module Generator = + module Generator = open System.Collections open System.Collections.Generic - + [] - type Step<'T> = + type Step<'T> = | Stop | Yield of 'T | Goto of Generator<'T> - and Generator<'T> = + and Generator<'T> = abstract Apply: (unit -> Step<'T>) abstract Disposer: (unit -> unit) option - let disposeG (g:Generator<'T>) = - match g.Disposer with - | None -> () + let disposeG (g:Generator<'T>) = + match g.Disposer with + | None -> () | Some f -> f() - + let appG (g:Generator<_>) = //System.Console.WriteLine("{0}.appG", box g) let res = g.Apply() - match res with - | Goto(next) -> + match res with + | Goto(next) -> Goto(next) - | Yield _ -> + | Yield _ -> res - | Stop -> + | Stop -> //System.Console.WriteLine("appG: Stop") - disposeG g; + disposeG g res - - // Binding. + + // Binding. // - // We use a type definition to apply a local dynamic optimization. + // We use a type definition to apply a local dynamic optimization. // We automatically right-associate binding, i.e. push the continuations to the right. // That is, bindG (bindG G1 cont1) cont2 --> bindG G1 (cont1 o cont2) // This makes constructs such as the following linear rather than quadratic: // - // let rec rwalk n = { if n > 0 then + // let rec rwalk n = { if n > 0 then // yield! rwalk (n-1) // yield n } type GenerateThen<'T>(g:Generator<'T>, cont : unit -> Generator<'T>) = member self.Generator = g member self.Cont = cont - interface Generator<'T> with - member x.Apply = (fun () -> - match appG g with - | Stop -> + interface Generator<'T> with + member x.Apply = (fun () -> + match appG g with + | Stop -> // OK, move onto the generator given by the continuation Goto(cont()) - | Yield _ as res -> + | Yield _ as res -> res - - | Goto next -> + + | Goto next -> Goto(GenerateThen<_>.Bind(next,cont))) - member x.Disposer = + member x.Disposer = g.Disposer - static member Bind (g:Generator<'T>, cont) = + static member Bind (g:Generator<'T>, cont) = match g with | :? GenerateThen<'T> as g -> GenerateThen<_>.Bind(g.Generator,(fun () -> GenerateThen<_>.Bind (g.Cont(), cont))) | g -> (new GenerateThen<'T>(g, cont) :> Generator<'T>) @@ -452,53 +455,21 @@ namespace Microsoft.FSharp.Collections let bindG g cont = GenerateThen<_>.Bind(g,cont) - //let emptyG () = - // { new Generator<_> with - // member x.Apply = (fun () -> Stop) - // member x.Disposer = None } - // - //let delayG f = - // { new Generator<_> with - // member x.Apply = fun () -> Goto(f()) - // member x.Disposer = None } - // - //let useG (v: System.IDisposable) f = - // { new Generator<_> with - // member x.Apply = (fun () -> - // let g = f v in - // // We're leaving this generator but want to maintain the disposal on the target. - // // Hence chain it into the disposer of the target - // Goto(chainDisposeG v.Dispose g)) - // member x.Disposer = Some (fun () -> v.Dispose()) } - // - //let yieldG (v:'T) = - // let yielded = ref false - // { new Generator<_> with - // member x.Apply = fun () -> if !yielded then Stop else (yielded := true; Yield(v)) - // member x.Disposer = None } - // - //let rec whileG gd b = if gd() then bindG (b()) (fun () -> whileG gd b) else emptyG() - // - //let yieldThenG x b = bindG (yieldG x) b - // - //let forG (v: seq<'T>) f = - // let e = v.GetEnumerator() in - // whileG e.MoveNext (fun () -> f e.Current) // Internal type. Drive an underlying generator. Crucially when the generator returns // a new generator we simply update our current generator and continue. Thus the enumerator // effectively acts as a reference cell holding the current generator. This means that - // infinite or large generation chains (e.g. caused by long sequences of append's, including + // infinite or large generation chains (e.g. caused by long sequences of append's, including // possible delay loops) can be referenced via a single enumerator. // // A classic case where this arises in this sort of sequence expression: - // let rec data s = { yield s; + // let rec data s = { yield s; // yield! data (s + random()) } // - // This translates to + // This translates to // let rec data s = Seq.delay (fun () -> Seq.append (Seq.singleton s) (Seq.delay (fun () -> data (s+random())))) // - // When you unwind through all the Seq, IEnumerator and Generator objects created, + // When you unwind through all the Seq, IEnumerator and Generator objects created, // you get (data s).GetEnumerator being an "GenerateFromEnumerator(EnumeratorWrappingLazyGenerator(...))" for the append. // After one element is yielded, we move on to the generator for the inner delay, which in turn // comes back to be a "GenerateFromEnumerator(EnumeratorWrappingLazyGenerator(...))". @@ -506,7 +477,6 @@ namespace Microsoft.FSharp.Collections // Defined as a type so we can optimize Enumerator/Generator chains in enumerateFromLazyGenerator // and GenerateFromEnumerator. - [] type EnumeratorWrappingLazyGenerator<'T>(g:Generator<'T>) = let mutable g = g @@ -517,18 +487,18 @@ namespace Microsoft.FSharp.Collections member x.Current= match curr with Some(v) -> v | None -> raise <| System.InvalidOperationException (SR.GetString(SR.moveNextNotCalledOrFinished)) interface System.Collections.IEnumerator with member x.Current = box (x :> IEnumerator<_>).Current - member x.MoveNext() = - not finished && - (match appG g with - | Stop -> - curr <- None; - finished <- true; + member x.MoveNext() = + not finished && + (match appG g with + | Stop -> + curr <- None + finished <- true false | Yield(v) -> - curr <- Some(v); + curr <- Some(v) true | Goto(next) -> - (g <- next); + (g <- next) (x :> IEnumerator).MoveNext()) member x.Reset() = IEnumerator.noReset() interface System.IDisposable with @@ -539,23 +509,23 @@ namespace Microsoft.FSharp.Collections type LazyGeneratorWrappingEnumerator<'T>(e:System.Collections.Generic.IEnumerator<'T>) = member g.Enumerator = e interface Generator<'T> with - member g.Apply = (fun () -> - if e.MoveNext() then - Yield(e.Current) - else + member g.Apply = (fun () -> + if e.MoveNext() then + Yield(e.Current) + else Stop) member g.Disposer= Some(e.Dispose) - let EnumerateFromGenerator(g:Generator<'T>) = - match g with + let EnumerateFromGenerator(g:Generator<'T>) = + match g with | :? LazyGeneratorWrappingEnumerator<'T> as g -> g.Enumerator | _ -> (new EnumeratorWrappingLazyGenerator<_>(g) :> System.Collections.Generic.IEnumerator<_>) let GenerateFromEnumerator (e:System.Collections.Generic.IEnumerator<'T>) = - match e with + match e with | :? EnumeratorWrappingLazyGenerator<'T> as e -> e.Generator | _ -> (new LazyGeneratorWrappingEnumerator<'T>(e) :> Generator<'T>) - + namespace Microsoft.FSharp.Core.CompilerServices open System @@ -570,45 +540,45 @@ namespace Microsoft.FSharp.Core.CompilerServices open System.Collections.Generic module RuntimeHelpers = - + [] - type internal StructBox<'T when 'T : equality>(value:'T) = + type internal StructBox<'T when 'T : equality>(value:'T) = member x.Value = value static member Comparer = let gcomparer = HashIdentity.Structural<'T> - { new IEqualityComparer> with + { new IEqualityComparer> with member __.GetHashCode(v) = gcomparer.GetHashCode(v.Value) member __.Equals(v1,v2) = gcomparer.Equals(v1.Value,v2.Value) } - let inline checkNonNull argName arg = - match box arg with - | null -> nullArg argName + let inline checkNonNull argName arg = + match box arg with + | null -> nullArg argName | _ -> () - let mkSeq f = - { new IEnumerable<'U> with + let mkSeq f = + { new IEnumerable<'U> with member x.GetEnumerator() = f() - interface IEnumerable with + interface IEnumerable with member x.GetEnumerator() = (f() :> IEnumerator) } [] - type EmptyEnumerable<'T> = + type EmptyEnumerable<'T> = | EmptyEnumerable - interface IEnumerable<'T> with + interface IEnumerable<'T> with member x.GetEnumerator() = IEnumerator.Empty<'T>() - interface IEnumerable with - member x.GetEnumerator() = (IEnumerator.Empty<'T>() :> IEnumerator) + interface IEnumerable with + member x.GetEnumerator() = (IEnumerator.Empty<'T>() :> IEnumerator) - let Generate openf compute closef = - mkSeq (fun () -> IEnumerator.generateWhileSome openf compute closef) - - let GenerateUsing (openf : unit -> ('U :> System.IDisposable)) compute = + let Generate openf compute closef = + mkSeq (fun () -> IEnumerator.generateWhileSome openf compute closef) + + let GenerateUsing (openf : unit -> ('U :> System.IDisposable)) compute = Generate openf compute (fun (s:'U) -> s.Dispose()) - let EnumerateFromFunctions opener moveNext current = - Generate - opener - (fun x -> if moveNext x then Some(current x) else None) + let EnumerateFromFunctions opener moveNext current = + Generate + opener + (fun x -> if moveNext x then Some(current x) else None) (fun x -> match box(x) with :? System.IDisposable as id -> id.Dispose() | _ -> ()) // A family of enumerators that can have additional 'finally' actions added to the enumerator through @@ -619,57 +589,57 @@ namespace Microsoft.FSharp.Core.CompilerServices // results in the 'while' loop giving an adjustable enumerator. This is then adjusted by adding the disposal action // from the 'use' into the enumerator. This means that we avoid constructing a two-deep enumerator chain in this // common case. - type IFinallyEnumerator = + type IFinallyEnumerator = abstract AppendFinallyAction : (unit -> unit) -> unit /// A concrete implementation of IEnumerable that adds the given compensation to the "Dispose" chain of any /// enumerators returned by the enumerable. [] - type FinallyEnumerable<'T>(compensation: unit -> unit, restf: unit -> seq<'T>) = - interface IEnumerable<'T> with - member x.GetEnumerator() = - try + type FinallyEnumerable<'T>(compensation: unit -> unit, restf: unit -> seq<'T>) = + interface IEnumerable<'T> with + member x.GetEnumerator() = + try let ie = restf().GetEnumerator() - match ie with - | :? IFinallyEnumerator as a -> - a.AppendFinallyAction(compensation); + match ie with + | :? IFinallyEnumerator as a -> + a.AppendFinallyAction(compensation) ie - | _ -> - IEnumerator.EnumerateThenFinally compensation ie - with e -> - compensation(); - reraise() - interface IEnumerable with - member x.GetEnumerator() = ((x :> IEnumerable<'T>).GetEnumerator() :> IEnumerator) - + | _ -> + IEnumerator.EnumerateThenFinally compensation ie + with e -> + compensation() + reraise() + interface IEnumerable with + member x.GetEnumerator() = ((x :> IEnumerable<'T>).GetEnumerator() :> IEnumerator) + /// An optimized object for concatenating a sequence of enumerables [] - type ConcatEnumerator<'T,'U when 'U :> seq<'T>>(sources: seq<'U>) = + type ConcatEnumerator<'T,'U when 'U :> seq<'T>>(sources: seq<'U>) = let mutable outerEnum = sources.GetEnumerator() let mutable currInnerEnum = IEnumerator.Empty() - let mutable started = false - let mutable finished = false + let mutable started = false + let mutable finished = false let mutable compensations = [] - + [] // false = unchecked val mutable private currElement : 'T - member x.Finish() = + member x.Finish() = finished <- true try - match currInnerEnum with + match currInnerEnum with | null -> () - | _ -> + | _ -> try currInnerEnum.Dispose() finally currInnerEnum <- null finally try - match outerEnum with + match outerEnum with | null -> () - | _ -> + | _ -> try outerEnum.Dispose() finally @@ -684,110 +654,110 @@ namespace Microsoft.FSharp.Core.CompilerServices compensations |> List.rev |> iter finally compensations <- [] - - member x.GetCurrent() = - IEnumerator.check started; + + member x.GetCurrent() = + IEnumerator.check started if finished then IEnumerator.alreadyFinished() else x.currElement - - interface IFinallyEnumerator with - member x.AppendFinallyAction(f) = + + interface IFinallyEnumerator with + member x.AppendFinallyAction(f) = compensations <- f :: compensations - - interface IEnumerator<'T> with + + interface IEnumerator<'T> with member x.Current = x.GetCurrent() - interface IEnumerator with + interface IEnumerator with member x.Current = box (x.GetCurrent()) - - member x.MoveNext() = - if not started then (started <- true) + + member x.MoveNext() = + if not started then (started <- true) if finished then false - else - let rec takeInner () = + else + let rec takeInner () = // check the inner list - if currInnerEnum.MoveNext() then - x.currElement <- currInnerEnum.Current; + if currInnerEnum.MoveNext() then + x.currElement <- currInnerEnum.Current true else // check the outer list - let rec takeOuter() = - if outerEnum.MoveNext() then - let ie = outerEnum.Current + let rec takeOuter() = + if outerEnum.MoveNext() then + let ie = outerEnum.Current // Optimization to detect the statically-allocated empty IEnumerables match box ie with - | :? EmptyEnumerable<'T> -> + | :? EmptyEnumerable<'T> -> // This one is empty, just skip, don't call GetEnumerator, try again takeOuter() - | _ -> + | _ -> // OK, this one may not be empty. // Don't forget to dispose of the enumerator for the inner list now we're done with it - currInnerEnum.Dispose(); - currInnerEnum <- ie.GetEnumerator(); + currInnerEnum.Dispose() + currInnerEnum <- ie.GetEnumerator() takeInner () - else + else // We're done x.Finish() false takeOuter() - takeInner () + takeInner () member x.Reset() = IEnumerator.noReset() - interface System.IDisposable with - member x.Dispose() = - if not finished then - x.Finish() - - let EnumerateUsing (resource : 'T :> System.IDisposable) (rest: 'T -> #seq<'U>) = - (FinallyEnumerable((fun () -> match box resource with null -> () | _ -> resource.Dispose()), + interface System.IDisposable with + member x.Dispose() = + if not finished then + x.Finish() + + let EnumerateUsing (resource : 'T :> System.IDisposable) (rest: 'T -> #seq<'U>) = + (FinallyEnumerable((fun () -> match box resource with null -> () | _ -> resource.Dispose()), (fun () -> rest resource :> seq<_>)) :> seq<_>) - let mkConcatSeq (sources: seq<'U :> seq<'T>>) = + let mkConcatSeq (sources: seq<'U :> seq<'T>>) = mkSeq (fun () -> new ConcatEnumerator<_,_>(sources) :> IEnumerator<'T>) - let EnumerateWhile (g : unit -> bool) (b: seq<'T>) : seq<'T> = - let started = ref false + let EnumerateWhile (g : unit -> bool) (b: seq<'T>) : seq<'T> = + let started = ref false let curr = ref None - let getCurr() = - IEnumerator.check !started; - match !curr with None -> IEnumerator.alreadyFinished() | Some x -> x - let start() = if not !started then (started := true) - - let finish() = (curr := None) - mkConcatSeq - (mkSeq (fun () -> - { new IEnumerator<_> with + let getCurr() = + IEnumerator.check !started + match !curr with None -> IEnumerator.alreadyFinished() | Some x -> x + let start() = if not !started then (started := true) + + let finish() = (curr := None) + mkConcatSeq + (mkSeq (fun () -> + { new IEnumerator<_> with member x.Current = getCurr() - interface IEnumerator with + interface IEnumerator with member x.Current = box (getCurr()) - member x.MoveNext() = - start(); + member x.MoveNext() = + start() let keepGoing = (try g() with e -> finish (); reraise ()) in - if keepGoing then + if keepGoing then curr := Some(b); true - else + else finish(); false member x.Reset() = IEnumerator.noReset() - interface System.IDisposable with + interface System.IDisposable with member x.Dispose() = () })) let EnumerateThenFinally (rest : seq<'T>) (compensation : unit -> unit) = (FinallyEnumerable(compensation, (fun () -> rest)) :> seq<_>) - let CreateEvent (add : 'Delegate -> unit) (remove : 'Delegate -> unit) (create : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = - // Note, we implement each interface explicitly: this works around a bug in the CLR + let CreateEvent (add : 'Delegate -> unit) (remove : 'Delegate -> unit) (create : (obj -> 'Args -> unit) -> 'Delegate ) :IEvent<'Delegate,'Args> = + // Note, we implement each interface explicitly: this works around a bug in the CLR // implementation on CompactFramework 3.7, used on Windows Phone 7 { new obj() with member x.ToString() = "" - interface IEvent<'Delegate,'Args> - interface IDelegateEvent<'Delegate> with - member x.AddHandler(h) = add h - member x.RemoveHandler(h) = remove h - interface System.IObservable<'Args> with - member x.Subscribe(r:IObserver<'Args>) = + interface IEvent<'Delegate,'Args> + interface IDelegateEvent<'Delegate> with + member x.AddHandler(h) = add h + member x.RemoveHandler(h) = remove h + interface System.IObservable<'Args> with + member x.Subscribe(r:IObserver<'Args>) = let h = create (fun _ args -> r.OnNext(args)) - add h - { new System.IDisposable with + add h + { new System.IDisposable with member x.Dispose() = remove h } } @@ -795,53 +765,53 @@ namespace Microsoft.FSharp.Core.CompilerServices type GeneratedSequenceBase<'T>() = let mutable redirectTo : GeneratedSequenceBase<'T> = Unchecked.defaultof<_> let mutable redirect : bool = false - + abstract GetFreshEnumerator : unit -> IEnumerator<'T> abstract GenerateNext : next:byref> -> int // 0 = Stop, 1 = Yield, 2 = Goto abstract Close: unit -> unit abstract CheckClose: bool abstract LastGenerated : 'T - + //[] - member x.MoveNextImpl() = - let active = + member x.MoveNextImpl() = + let active = if redirect then redirectTo else x let mutable target = null - match active.GenerateNext(&target) with - | 1 -> + match active.GenerateNext(&target) with + | 1 -> true - | 2 -> - match target.GetEnumerator() with - | :? GeneratedSequenceBase<'T> as g when not active.CheckClose -> + | 2 -> + match target.GetEnumerator() with + | :? GeneratedSequenceBase<'T> as g when not active.CheckClose -> redirectTo <- g - | e -> - redirectTo <- - { new GeneratedSequenceBase<'T>() with + | e -> + redirectTo <- + { new GeneratedSequenceBase<'T>() with member x.GetFreshEnumerator() = e - member x.GenerateNext(_) = if e.MoveNext() then 1 else 0 + member x.GenerateNext(_) = if e.MoveNext() then 1 else 0 member x.Close() = try e.Dispose() finally active.Close() member x.CheckClose = true member x.LastGenerated = e.Current } redirect <- true x.MoveNextImpl() - | _ (* 0 *) -> + | _ (* 0 *) -> false - - interface IEnumerable<'T> with + + interface IEnumerable<'T> with member x.GetEnumerator() = x.GetFreshEnumerator() interface IEnumerable with - member x.GetEnumerator() = (x.GetFreshEnumerator() :> IEnumerator); - interface IEnumerator<'T> with + member x.GetEnumerator() = (x.GetFreshEnumerator() :> IEnumerator) + interface IEnumerator<'T> with member x.Current = if redirect then redirectTo.LastGenerated else x.LastGenerated member x.Dispose() = if redirect then redirectTo.Close() else x.Close() interface IEnumerator with member x.Current = box (if redirect then redirectTo.LastGenerated else x.LastGenerated) //[] - member x.MoveNext() = x.MoveNextImpl() - - member x.Reset() = raise <| new System.NotSupportedException(); + member x.MoveNext() = x.MoveNextImpl() + + member x.Reset() = raise <| new System.NotSupportedException() namespace Microsoft.FSharp.Collections @@ -861,36 +831,36 @@ namespace Microsoft.FSharp.Collections [] type CachedSeq<'T>(cleanup,res:seq<'T>) = - interface System.IDisposable with + interface System.IDisposable with member x.Dispose() = cleanup() - interface System.Collections.Generic.IEnumerable<'T> with + interface System.Collections.Generic.IEnumerable<'T> with member x.GetEnumerator() = res.GetEnumerator() - interface System.Collections.IEnumerable with + interface System.Collections.IEnumerable with member x.GetEnumerator() = (res :> System.Collections.IEnumerable).GetEnumerator() member obj.Clear() = cleanup() - + [] [] - module Seq = - + module Seq = + #if FX_NO_ICLONEABLE - open Microsoft.FSharp.Core.ICloneableExtensions + open Microsoft.FSharp.Core.ICloneableExtensions #else -#endif +#endif open Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers - + let mkDelayedSeq (f: unit -> IEnumerable<'T>) = mkSeq (fun () -> f().GetEnumerator()) - let mkUnfoldSeq f x = mkSeq (fun () -> IEnumerator.unfold f x) + let mkUnfoldSeq f x = mkSeq (fun () -> IEnumerator.unfold f x) let inline indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException(SR.GetString(SR.keyNotFoundAlt))) - + [] let delay f = mkDelayedSeq f [] let unfold f x = mkUnfoldSeq f x - + [] let empty<'T> = (EmptyEnumerable :> seq<'T>) @@ -899,20 +869,20 @@ namespace Microsoft.FSharp.Collections [] let init count f = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count mkSeq (fun () -> IEnumerator.upto (Some (count-1)) f) [] - let iter f (source : seq<'T>) = + let iter f (source : seq<'T>) = checkNonNull "source" source use e = source.GetEnumerator() while e.MoveNext() do - f e.Current; + f e.Current [] let item i (source : seq<'T>) = checkNonNull "source" source - if i < 0 then invalidArg "index" (SR.GetString(SR.inputMustBeNonNegative)) + if i < 0 then invalidArgInputMustBeNonNegative "index" i use e = source.GetEnumerator() IEnumerator.nth i e @@ -927,24 +897,24 @@ namespace Microsoft.FSharp.Collections let nth i (source : seq<'T>) = item i source [] - let iteri f (source : seq<'T>) = + let iteri f (source : seq<'T>) = checkNonNull "source" source use e = source.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable i = 0 + let mutable i = 0 while e.MoveNext() do - f.Invoke(i, e.Current); - i <- i + 1; + f.Invoke(i, e.Current) + i <- i + 1 [] - let exists f (source : seq<'T>) = + let exists f (source : seq<'T>) = checkNonNull "source" source use e = source.GetEnumerator() let mutable state = false while (not state && e.MoveNext()) do state <- f e.Current state - + [] let inline contains element (source : seq<'T>) = checkNonNull "source" source @@ -953,48 +923,48 @@ namespace Microsoft.FSharp.Collections while (not state && e.MoveNext()) do state <- element = e.Current state - + [] - let forall f (source : seq<'T>) = + let forall f (source : seq<'T>) = checkNonNull "source" source use e = source.GetEnumerator() - let mutable state = true + let mutable state = true while (state && e.MoveNext()) do state <- f e.Current state - - + + [] - let iter2 f (source1 : seq<_>) (source2 : seq<_>) = + let iter2 f (source1 : seq<_>) (source2 : seq<_>) = checkNonNull "source1" source1 checkNonNull "source2" source2 use e1 = source1.GetEnumerator() use e2 = source2.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) while (e1.MoveNext() && e2.MoveNext()) do - f.Invoke(e1.Current, e2.Current); + f.Invoke(e1.Current, e2.Current) [] - let iteri2 f (source1 : seq<_>) (source2 : seq<_>) = + let iteri2 f (source1 : seq<_>) (source2 : seq<_>) = checkNonNull "source1" source1 checkNonNull "source2" source2 use e1 = source1.GetEnumerator() use e2 = source2.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) - let mutable i = 0 + let mutable i = 0 while (e1.MoveNext() && e2.MoveNext()) do f.Invoke(i, e1.Current, e2.Current) i <- i + 1 // Build an IEnumerble by wrapping/transforming iterators as they get generated. let revamp f (ie : seq<_>) = mkSeq (fun () -> f (ie.GetEnumerator())) - let revamp2 f (ie1 : seq<_>) (source2 : seq<_>) = + let revamp2 f (ie1 : seq<_>) (source2 : seq<_>) = mkSeq (fun () -> f (ie1.GetEnumerator()) (source2.GetEnumerator())) - let revamp3 f (ie1 : seq<_>) (source2 : seq<_>) (source3 : seq<_>) = + let revamp3 f (ie1 : seq<_>) (source2 : seq<_>) (source3 : seq<_>) = mkSeq (fun () -> f (ie1.GetEnumerator()) (source2.GetEnumerator()) (source3.GetEnumerator())) [] - let filter f source = + let filter f source = checkNonNull "source" source revamp (IEnumerator.filter f) source @@ -1002,12 +972,12 @@ namespace Microsoft.FSharp.Collections let where f source = filter f source [] - let map f source = + let map f source = checkNonNull "source" source revamp (IEnumerator.map f) source [] - let mapi f source = + let mapi f source = checkNonNull "source" source revamp (IEnumerator.mapi f) source @@ -1018,20 +988,20 @@ namespace Microsoft.FSharp.Collections revamp2 (IEnumerator.mapi2 f) source1 source2 [] - let map2 f source1 source2 = + let map2 f source1 source2 = checkNonNull "source1" source1 checkNonNull "source2" source2 revamp2 (IEnumerator.map2 f) source1 source2 [] - let map3 f source1 source2 source3 = + let map3 f source1 source2 source3 = checkNonNull "source1" source1 checkNonNull "source2" source2 checkNonNull "source3" source3 revamp3 (IEnumerator.map3 f) source1 source2 source3 [] - let choose f source = + let choose f source = checkNonNull "source" source revamp (IEnumerator.choose f) source @@ -1041,116 +1011,117 @@ namespace Microsoft.FSharp.Collections mapi (fun i x -> i,x) source [] - let zip source1 source2 = + let zip source1 source2 = checkNonNull "source1" source1 checkNonNull "source2" source2 map2 (fun x y -> x,y) source1 source2 [] - let zip3 source1 source2 source3 = + let zip3 source1 source2 source3 = checkNonNull "source1" source1 checkNonNull "source2" source2 checkNonNull "source3" source3 map2 (fun x (y,z) -> x,y,z) source1 (zip source2 source3) [] - let cast (source: IEnumerable) = + let cast (source: IEnumerable) = checkNonNull "source" source mkSeq (fun () -> IEnumerator.cast (source.GetEnumerator())) [] - let tryPick f (source : seq<'T>) = + let tryPick f (source : seq<'T>) = checkNonNull "source" source use e = source.GetEnumerator() - let mutable res = None + let mutable res = None while (Option.isNone res && e.MoveNext()) do - res <- f e.Current; + res <- f e.Current res [] - let pick f source = + let pick f source = checkNonNull "source" source - match tryPick f source with + match tryPick f source with | None -> indexNotFound() | Some x -> x - + [] - let tryFind f (source : seq<'T>) = + let tryFind f (source : seq<'T>) = checkNonNull "source" source use e = source.GetEnumerator() - let mutable res = None + let mutable res = None while (Option.isNone res && e.MoveNext()) do - let c = e.Current + let c = e.Current if f c then res <- Some(c) res [] - let find f source = + let find f source = checkNonNull "source" source - match tryFind f source with + match tryFind f source with | None -> indexNotFound() | Some x -> x [] - let take count (source : seq<'T>) = + let take count (source : seq<'T>) = checkNonNull "source" source - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count (* Note: don't create or dispose any IEnumerable if n = 0 *) - if count = 0 then empty else - seq { use e = source.GetEnumerator() - for _ in 0 .. count - 1 do + if count = 0 then empty else + seq { use e = source.GetEnumerator() + for x in 0 .. count - 1 do if not (e.MoveNext()) then - raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) + invalidOpFmt "tried to take {0} {1} past the end of the seq" + [|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|] yield e.Current } [] - let isEmpty (source : seq<'T>) = + let isEmpty (source : seq<'T>) = checkNonNull "source" source - match source with + match source with | :? ('T[]) as a -> a.Length = 0 | :? list<'T> as a -> a.IsEmpty | :? ICollection<'T> as a -> a.Count = 0 - | _ -> + | _ -> use ie = source.GetEnumerator() not (ie.MoveNext()) [] - let concat sources = + let concat sources = checkNonNull "sources" sources mkConcatSeq sources [] - let length (source : seq<'T>) = + let length (source : seq<'T>) = checkNonNull "source" source - match source with + match source with | :? ('T[]) as a -> a.Length | :? ('T list) as a -> a.Length | :? ICollection<'T> as a -> a.Count - | _ -> - use e = source.GetEnumerator() - let mutable state = 0 + | _ -> + use e = source.GetEnumerator() + let mutable state = 0 while e.MoveNext() do - state <- state + 1; + state <- state + 1 state [] - let fold<'T,'State> f (x:'State) (source : seq<'T>) = + let fold<'T,'State> f (x:'State) (source : seq<'T>) = checkNonNull "source" source - use e = source.GetEnumerator() + use e = source.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable state = x + let mutable state = x while e.MoveNext() do state <- f.Invoke(state, e.Current) state [] - let fold2<'T1,'T2,'State> f (state:'State) (source1: seq<'T1>) (source2: seq<'T2>) = + let fold2<'T1,'T2,'State> f (state:'State) (source1: seq<'T1>) (source2: seq<'T2>) = checkNonNull "source1" source1 checkNonNull "source2" source2 - use e1 = source1.GetEnumerator() - use e2 = source2.GetEnumerator() + use e1 = source1.GetEnumerator() + use e2 = source2.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_,_>.Adapt(f) @@ -1161,19 +1132,19 @@ namespace Microsoft.FSharp.Collections state [] - let reduce f (source : seq<'T>) = + let reduce f (source : seq<'T>) = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let mutable state = e.Current + let mutable state = e.Current while e.MoveNext() do state <- f.Invoke(state, e.Current) state let fromGenerator f = mkSeq(fun () -> Generator.EnumerateFromGenerator (f())) let toGenerator (ie : seq<_>) = Generator.GenerateFromEnumerator (ie.GetEnumerator()) - + [] let replicate count x = #if FX_ATLEAST_40 @@ -1182,39 +1153,39 @@ namespace Microsoft.FSharp.Collections if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) seq { for _ in 1 .. count -> x } #endif - + [] - let append (source1: seq<'T>) (source2: seq<'T>) = + let append (source1: seq<'T>) (source2: seq<'T>) = checkNonNull "source1" source1 checkNonNull "source2" source2 fromGenerator(fun () -> Generator.bindG (toGenerator source1) (fun () -> toGenerator source2)) - + [] let collect f sources = map f sources |> concat [] - let compareWith (f:'T -> 'T -> int) (source1 : seq<'T>) (source2: seq<'T>) = + let compareWith (f:'T -> 'T -> int) (source1 : seq<'T>) (source2: seq<'T>) = checkNonNull "source1" source1 checkNonNull "source2" source2 use e1 = source1.GetEnumerator() use e2 = source2.GetEnumerator() let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) - let rec go () = - let e1ok = e1.MoveNext() - let e2ok = e2.MoveNext() + let rec go () = + let e1ok = e1.MoveNext() + let e2ok = e2.MoveNext() let c = if e1ok = e2ok then 0 else if e1ok then 1 else -1 if c <> 0 then c else - if not e1ok || not e2ok then 0 + if not e1ok || not e2ok then 0 else let c = f.Invoke(e1.Current, e2.Current) if c <> 0 then c else - go () + go () go() [] - let ofList (source : 'T list) = + let ofList (source : 'T list) = (source :> seq<'T>) [] @@ -1222,26 +1193,26 @@ namespace Microsoft.FSharp.Collections checkNonNull "source" source Microsoft.FSharp.Primitives.Basics.List.ofSeq source - // Create a new object to ensure underlying array may not be mutated by a backdoor cast + // Create a new object to ensure underlying array may not be mutated by a backdoor cast [] - let ofArray (source : 'T array) = + let ofArray (source : 'T array) = checkNonNull "source" source - mkSeq (fun () -> IEnumerator.ofArray source) - + mkSeq (fun () -> IEnumerator.ofArray source) + [] - let toArray (source : seq<'T>) = + let toArray (source : seq<'T>) = checkNonNull "source" source - match source with + match source with | :? ('T[]) as res -> (res.Clone() :?> 'T[]) | :? ('T list) as res -> List.toArray res - | :? ICollection<'T> as res -> - // Directly create an array and copy ourselves. + | :? ICollection<'T> as res -> + // Directly create an array and copy ourselves. // This avoids an extra copy if using ResizeArray in fallback below. let arr = Array.zeroCreateUnchecked res.Count res.CopyTo(arr, 0) arr - | _ -> - let res = ResizeArray<_>(source) + | _ -> + let res = ResizeArray<_>(source) res.ToArray() let foldArraySubRight (f:OptimizedClosures.FSharpFunc<'T,_,_>) (arr: 'T[]) start fin acc = @@ -1281,7 +1252,7 @@ namespace Microsoft.FSharp.Collections let truncate n (source: seq<'T>) = checkNonNull "source" source seq { let i = ref 0 - use ie = source.GetEnumerator() + use ie = source.GetEnumerator() while !i < n && ie.MoveNext() do i := !i + 1 yield ie.Current } @@ -1289,21 +1260,21 @@ namespace Microsoft.FSharp.Collections [] let pairwise (source: seq<'T>) = checkNonNull "source" source - seq { use ie = source.GetEnumerator() + seq { use ie = source.GetEnumerator() if ie.MoveNext() then let iref = ref ie.Current while ie.MoveNext() do - let j = ie.Current + let j = ie.Current yield (!iref, j) iref := j } [] - let scan<'T,'State> f (z:'State) (source : seq<'T>) = + let scan<'T,'State> f (z:'State) (source : seq<'T>) = checkNonNull "source" source let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) seq { let zref = ref z yield !zref - use ie = source.GetEnumerator() + use ie = source.GetEnumerator() while ie.MoveNext() do zref := f.Invoke(!zref, ie.Current) yield !zref } @@ -1327,11 +1298,11 @@ namespace Microsoft.FSharp.Collections res :> seq<_>) [] - let findIndex p (source:seq<_>) = + let findIndex p (source:seq<_>) = checkNonNull "source" source - use ie = source.GetEnumerator() - let rec loop i = - if ie.MoveNext() then + use ie = source.GetEnumerator() + let rec loop i = + if ie.MoveNext() then if p ie.Current then i else loop (i+1) @@ -1340,11 +1311,11 @@ namespace Microsoft.FSharp.Collections loop 0 [] - let tryFindIndex p (source:seq<_>) = + let tryFindIndex p (source:seq<_>) = checkNonNull "source" source - use ie = source.GetEnumerator() - let rec loop i = - if ie.MoveNext() then + use ie = source.GetEnumerator() + let rec loop i = + if ie.MoveNext() then if p ie.Current then Some i else loop (i+1) @@ -1364,10 +1335,11 @@ namespace Microsoft.FSharp.Collections // windowed : int -> seq<'T> -> seq<'T[]> [] - let windowed windowSize (source: seq<_>) = + let windowed windowSize (source: seq<_>) = checkNonNull "source" source - if windowSize <= 0 then invalidArg "windowSize" (SR.GetString(SR.inputMustBePositive)) - seq { + if windowSize <= 0 then invalidArgFmt "windowSize" "{0}\nwindowSize = {1}" + [|SR.GetString SR.inputMustBePositive; windowSize|] + seq { let arr = Array.zeroCreateUnchecked windowSize let r = ref (windowSize - 1) let i = ref 0 @@ -1387,7 +1359,7 @@ namespace Microsoft.FSharp.Collections } [] - let cache (source : seq<'T>) = + let cache (source : seq<'T>) = checkNonNull "source" source // Wrap a seq to ensure that it is enumerated just once and only as far as is necessary. // @@ -1403,12 +1375,12 @@ namespace Microsoft.FSharp.Collections // None = Unstarted. // Some(Some e) = Started. // Some None = Finished. - let oneStepTo i = + let oneStepTo i = // If possible, step the enumeration to prefix length i (at most one step). // Be speculative, since this could have already happened via another thread. if not (i < prefix.Count) then // is a step still required? // If not yet started, start it (create enumerator). - match !enumeratorR with + match !enumeratorR with | None -> enumeratorR := Some (Some (source.GetEnumerator())) | Some _ -> () match (!enumeratorR).Value with @@ -1418,12 +1390,12 @@ namespace Microsoft.FSharp.Collections enumerator.Dispose() // Move failed, dispose enumerator, enumeratorR := Some None // drop it and record finished. | None -> () - let result = - unfold (fun i -> + let result = + unfold (fun i -> // i being the next position to be returned // A lock is needed over the reads to prefix.Count since the list may be being resized // NOTE: we could change to a reader/writer lock here - lock enumeratorR (fun () -> + lock enumeratorR (fun () -> if i < prefix.Count then Some (prefix.[i],i+1) else @@ -1432,13 +1404,13 @@ namespace Microsoft.FSharp.Collections Some (prefix.[i],i+1) else None)) 0 - let cleanup() = - lock enumeratorR (fun () -> + let cleanup() = + lock enumeratorR (fun () -> prefix.Clear() - begin match !enumeratorR with - | Some (Some e) -> IEnumerator.dispose e; + begin match !enumeratorR with + | Some (Some e) -> IEnumerator.dispose e | _ -> () - end; + end enumeratorR := None) (new CachedSeq<_>(cleanup, result) :> seq<_>) @@ -1449,9 +1421,9 @@ namespace Microsoft.FSharp.Collections let cached = cache source2 source1 |> collect (fun x -> cached |> map (fun y -> x,y)) - [] + [] [] - let readonly (source:seq<_>) = + let readonly (source:seq<_>) = checkNonNull "source" source mkSeq (fun () -> source.GetEnumerator()) @@ -1466,7 +1438,7 @@ namespace Microsoft.FSharp.Collections let minimumBucketSize = 4 // Build the groupings - seq |> iter (fun v -> + seq |> iter (fun v -> let safeKey = keyf v let mutable prev = Unchecked.defaultof<_> match dict.TryGetValue (safeKey, &prev) with @@ -1476,16 +1448,16 @@ namespace Microsoft.FSharp.Collections dict.[safeKey] <- prev prev.Add v) - // Trim the size of each result group, don't trim very small buckets, as excessive work, and garbage for - // minimal gain + // Trim the size of each result group, don't trim very small buckets, as excessive work, and garbage for + // minimal gain dict |> iter (fun group -> if group.Value.Count > minimumBucketSize then group.Value.TrimExcess()) - - // Return the sequence-of-sequences. Don't reveal the + + // Return the sequence-of-sequences. Don't reveal the // internal collections: just reveal them as sequences dict |> map (fun group -> (getKey group.Key, readonly group.Value)) // We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance - let groupByValueType (keyf:'T->'Key) (seq:seq<'T>) = seq |> groupByImpl HashIdentity.Structural<'Key> keyf id + let groupByValueType (keyf:'T->'Key) (seq:seq<'T>) = seq |> groupByImpl HashIdentity.Structural<'Key> keyf id // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation let groupByRefType (keyf:'T->'Key) (seq:seq<'T>) = seq |> groupByImpl StructBox<'Key>.Comparer (fun t -> StructBox (keyf t)) (fun sb -> sb.Value) @@ -1519,16 +1491,16 @@ namespace Microsoft.FSharp.Collections [] let sortBy keyf source = checkNonNull "source" source - mkDelayedSeq (fun () -> - let array = source |> toArray + mkDelayedSeq (fun () -> + let array = source |> toArray Array.stableSortInPlaceBy keyf array array :> seq<_>) [] let sort source = checkNonNull "source" source - mkDelayedSeq (fun () -> - let array = source |> toArray + mkDelayedSeq (fun () -> + let array = source |> toArray Array.stableSortInPlace array array :> seq<_>) @@ -1558,7 +1530,7 @@ namespace Microsoft.FSharp.Collections let dict = Dictionary comparer // Build the groupings - source |> iter (fun v -> + source |> iter (fun v -> let safeKey = keyf v let mutable prev = Unchecked.defaultof<_> if dict.TryGetValue(safeKey, &prev) @@ -1568,7 +1540,7 @@ namespace Microsoft.FSharp.Collections dict |> map (fun group -> (getKey group.Key, group.Value)) // We avoid wrapping a StructBox, because under 64 JIT we get some "hard" tailcalls which affect performance - let countByValueType (keyf:'T->'Key) (seq:seq<'T>) = seq |> countByImpl HashIdentity.Structural<'Key> keyf id + let countByValueType (keyf:'T->'Key) (seq:seq<'T>) = seq |> countByImpl HashIdentity.Structural<'Key> keyf id // Wrap a StructBox around all keys in case the key type is itself a type using null as a representation let countByRefType (keyf:'T->'Key) (seq:seq<'T>) = seq |> countByImpl StructBox<'Key>.Comparer (fun t -> StructBox (keyf t)) (fun sb -> sb.Value) @@ -1586,66 +1558,66 @@ namespace Microsoft.FSharp.Collections else mkDelayedSeq (fun () -> countByRefType keyf source) [] - let inline sum (source: seq< (^a) >) : ^a = - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< (^a) > + let inline sum (source: seq< ^a>) : ^a = + use e = source.GetEnumerator() + let mutable acc = LanguagePrimitives.GenericZero< ^a> while e.MoveNext() do acc <- Checked.(+) acc e.Current acc [] - let inline sumBy (f : 'T -> ^U) (source: seq<'T>) : ^U = - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< (^U) > + let inline sumBy (f : 'T -> ^U) (source: seq<'T>) : ^U = + use e = source.GetEnumerator() + let mutable acc = LanguagePrimitives.GenericZero< ^U> while e.MoveNext() do acc <- Checked.(+) acc (f e.Current) acc [] - let inline average (source: seq< (^a) >) : ^a = + let inline average (source: seq< ^a>) : ^a = checkNonNull "source" source - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< (^a) > + use e = source.GetEnumerator() + let mutable acc = LanguagePrimitives.GenericZero< ^a> let mutable count = 0 while e.MoveNext() do acc <- Checked.(+) acc e.Current count <- count + 1 - if count = 0 then + if count = 0 then invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString - LanguagePrimitives.DivideByInt< (^a) > acc count + LanguagePrimitives.DivideByInt< ^a> acc count [] - let inline averageBy (f : 'T -> ^U) (source: seq< 'T >) : ^U = + let inline averageBy (f : 'T -> ^U) (source: seq< 'T >) : ^U = checkNonNull "source" source - use e = source.GetEnumerator() - let mutable acc = LanguagePrimitives.GenericZero< (^U) > + use e = source.GetEnumerator() + let mutable acc = LanguagePrimitives.GenericZero< ^U> let mutable count = 0 while e.MoveNext() do acc <- Checked.(+) acc (f e.Current) count <- count + 1 - if count = 0 then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString; - LanguagePrimitives.DivideByInt< (^U) > acc count - + if count = 0 then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString + LanguagePrimitives.DivideByInt< ^U> acc count + [] - let inline min (source: seq<_>) = + let inline min (source: seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString let mutable acc = e.Current while e.MoveNext() do - let curr = e.Current - if curr < acc then + let curr = e.Current + if curr < acc then acc <- curr acc [] - let inline minBy (f : 'T -> 'U) (source: seq<'T>) : 'T = + let inline minBy (f : 'T -> 'U) (source: seq<'T>) : 'T = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString let first = e.Current let mutable acc = f first let mutable accv = first @@ -1659,11 +1631,11 @@ namespace Microsoft.FSharp.Collections (* [] - let inline minValBy (f : 'T -> 'U) (source: seq<'T>) : 'U = + let inline minValBy (f : 'T -> 'U) (source: seq<'T>) : 'U = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then + invalidArg "source" InputSequenceEmptyString let first = e.Current let mutable acc = f first while e.MoveNext() do @@ -1675,24 +1647,24 @@ namespace Microsoft.FSharp.Collections *) [] - let inline max (source: seq<_>) = + let inline max (source: seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString let mutable acc = e.Current while e.MoveNext() do - let curr = e.Current - if curr > acc then + let curr = e.Current + if curr > acc then acc <- curr acc [] - let inline maxBy (f : 'T -> 'U) (source: seq<'T>) : 'T = + let inline maxBy (f : 'T -> 'U) (source: seq<'T>) : 'T = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then + invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString let first = e.Current let mutable acc = f first let mutable accv = first @@ -1707,11 +1679,11 @@ namespace Microsoft.FSharp.Collections (* [] - let inline maxValBy (f : 'T -> 'U) (source: seq<'T>) : 'U = + let inline maxValBy (f : 'T -> 'U) (source: seq<'T>) : 'U = checkNonNull "source" source - use e = source.GetEnumerator() - if not (e.MoveNext()) then - invalidArg "source" InputSequenceEmptyString; + use e = source.GetEnumerator() + if not (e.MoveNext()) then + invalidArg "source" InputSequenceEmptyString let first = e.Current let mutable acc = f first while e.MoveNext() do @@ -1723,27 +1695,28 @@ namespace Microsoft.FSharp.Collections *) [] - let takeWhile p (source: seq<_>) = + let takeWhile p (source: seq<_>) = checkNonNull "source" source - seq { use e = source.GetEnumerator() + seq { use e = source.GetEnumerator() let latest = ref Unchecked.defaultof<_> - while e.MoveNext() && (latest := e.Current; p !latest) do + while e.MoveNext() && (latest := e.Current; p !latest) do yield !latest } [] let skip count (source: seq<_>) = checkNonNull "source" source - seq { use e = source.GetEnumerator() - for _ in 1 .. count do - if not (e.MoveNext()) then - raise <| System.InvalidOperationException (SR.GetString(SR.notEnoughElements)) + seq { use e = source.GetEnumerator() + for x in 1 .. count do + if not (e.MoveNext()) then + invalidOpFmt "tried to skip {0} {1} past the end of the seq" + [|SR.GetString SR.notEnoughElements; x; (if x=1 then "element" else "elements")|] while e.MoveNext() do yield e.Current } [] - let skipWhile p (source: seq<_>) = + let skipWhile p (source: seq<_>) = checkNonNull "source" source - seq { use e = source.GetEnumerator() + seq { use e = source.GetEnumerator() let latest = ref (Unchecked.defaultof<_>) let ok = ref false while e.MoveNext() do @@ -1753,7 +1726,7 @@ namespace Microsoft.FSharp.Collections [] - let forall2 p (source1: seq<_>) (source2: seq<_>) = + let forall2 p (source1: seq<_>) (source2: seq<_>) = checkNonNull "source1" source1 checkNonNull "source2" source2 use e1 = source1.GetEnumerator() @@ -1764,9 +1737,9 @@ namespace Microsoft.FSharp.Collections ok <- p.Invoke(e1.Current, e2.Current) ok - + [] - let exists2 p (source1: seq<_>) (source2: seq<_>) = + let exists2 p (source1: seq<_>) (source2: seq<_>) = checkNonNull "source1" source1 checkNonNull "source2" source2 use e1 = source1.GetEnumerator() @@ -1780,22 +1753,22 @@ namespace Microsoft.FSharp.Collections [] let head (source : seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() + use e = source.GetEnumerator() if (e.MoveNext()) then e.Current else invalidArg "source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString [] let tryHead (source : seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() + use e = source.GetEnumerator() if (e.MoveNext()) then Some e.Current else None [] let tail (source: seq<'T>) = checkNonNull "source" source - seq { use e = source.GetEnumerator() - if not (e.MoveNext()) then + seq { use e = source.GetEnumerator() + if not (e.MoveNext()) then invalidArg "source" (SR.GetString(SR.notEnoughElements)) while e.MoveNext() do yield e.Current } @@ -1803,8 +1776,8 @@ namespace Microsoft.FSharp.Collections [] let last (source : seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() - if e.MoveNext() then + use e = source.GetEnumerator() + if e.MoveNext() then let mutable res = e.Current while (e.MoveNext()) do res <- e.Current res @@ -1814,8 +1787,8 @@ namespace Microsoft.FSharp.Collections [] let tryLast (source : seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() - if e.MoveNext() then + use e = source.GetEnumerator() + if e.MoveNext() then let mutable res = e.Current while (e.MoveNext()) do res <- e.Current Some res @@ -1825,10 +1798,10 @@ namespace Microsoft.FSharp.Collections [] let exactlyOne (source : seq<_>) = checkNonNull "source" source - use e = source.GetEnumerator() - if e.MoveNext() then - let v = e.Current - if e.MoveNext() then + use e = source.GetEnumerator() + if e.MoveNext() then + let v = e.Current + if e.MoveNext() then invalidArg "source" (SR.GetString(SR.inputSequenceTooLong)) else v @@ -1880,7 +1853,8 @@ namespace Microsoft.FSharp.Collections [] let chunkBySize chunkSize (source : seq<_>) = checkNonNull "source" source - if chunkSize <= 0 then invalidArg "chunkSize" (SR.GetString(SR.inputMustBePositive)) + if chunkSize <= 0 then invalidArgFmt "chunkSize" "{0}\nchunkSize = {1}" + [|SR.GetString SR.inputMustBePositive; chunkSize|] seq { use e = source.GetEnumerator() let nextChunk() = let res = Array.zeroCreateUnchecked chunkSize @@ -1899,6 +1873,7 @@ namespace Microsoft.FSharp.Collections [] let splitInto count source = checkNonNull "source" source - if count <= 0 then invalidArg "count" (SR.GetString(SR.inputMustBePositive)) + if count <= 0 then invalidArgFmt "count" "{0}\ncount = {1}" + [|SR.GetString SR.inputMustBePositive; count|] mkDelayedSeq (fun () -> source |> toArray |> Array.splitInto count :> seq<_>) diff --git a/src/fsharp/FSharp.Core/set.fs b/src/fsharp/FSharp.Core/set.fs index 3a37de100f6..7262ae45f24 100644 --- a/src/fsharp/FSharp.Core/set.fs +++ b/src/fsharp/FSharp.Core/set.fs @@ -285,6 +285,9 @@ namespace Microsoft.FSharp.Collections let filter comparer f s = filterAux comparer f s SetEmpty let rec diffAux comparer m acc = + match acc with + | SetEmpty -> acc + | _ -> match m with | SetNode(k,l,r,_) -> diffAux comparer l (diffAux comparer r (remove comparer k acc)) | SetOne(k) -> remove comparer k acc diff --git a/src/fsharp/FSharp.Core/string.fs b/src/fsharp/FSharp.Core/string.fs index a1848b1a220..18ead1299c0 100644 --- a/src/fsharp/FSharp.Core/string.fs +++ b/src/fsharp/FSharp.Core/string.fs @@ -38,14 +38,14 @@ namespace Microsoft.FSharp.Core [] let map (f: char -> char) (str:string) = let str = emptyIfNull str - let res = StringBuilder(str.Length) + let res = StringBuilder str.Length str |> iter (fun c -> res.Append(f c) |> ignore) res.ToString() [] let mapi (f: int -> char -> char) (str:string) = let str = emptyIfNull str - let res = StringBuilder(str.Length) + let res = StringBuilder str.Length let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f) str |> iteri (fun i c -> res.Append(f.Invoke(i, c)) |> ignore) res.ToString() @@ -53,32 +53,32 @@ namespace Microsoft.FSharp.Core [] let filter (f: char -> bool) (str:string) = let str = emptyIfNull str - let res = StringBuilder(str.Length) - str |> iter (fun c -> if f c then res.Append(c) |> ignore) + let res = StringBuilder str.Length + str |> iter (fun c -> if f c then res.Append c |> ignore) res.ToString() [] let collect (f: char -> string) (str:string) = let str = emptyIfNull str - let res = StringBuilder(str.Length) + let res = StringBuilder str.Length str |> iter (fun c -> res.Append(f c) |> ignore) res.ToString() [] let init (count:int) (initializer: int-> string) = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) - let res = StringBuilder(count) + if count < 0 then invalidArgInputMustBeNonNegative "count" count + let res = StringBuilder count for i = 0 to count - 1 do res.Append(initializer i) |> ignore res.ToString() [] let replicate (count:int) (str:string) = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) + if count < 0 then invalidArgInputMustBeNonNegative "count" count let str = emptyIfNull str - let res = StringBuilder(str.Length) + let res = StringBuilder str.Length for i = 0 to count - 1 do - res.Append(str) |> ignore + res.Append str |> ignore res.ToString() [] diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 080bc1405ae..eec92b5b07c 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -1335,7 +1335,7 @@ type CodeGenBuffer(m:range, member cgbuf.GetCurrentStack() = stack member cgbuf.AssertEmptyStack() = - if nonNil stack then + if not (List.isEmpty stack) then let msg = sprintf "stack flush didn't work, or extraneous expressions left on stack before stack restore, methodName = %s, stack = %+A, m = %s" methodName stack (stringOfRange m) System.Diagnostics.Debug.Assert(false, msg) warning(InternalError(msg,m)) @@ -1369,7 +1369,7 @@ type CodeGenBuffer(m:range, cgbuf.EnsureNopBetweenDebugPoints() let attr = GenILSourceMarker mgbuf.cenv.g src - assert(isSome(attr)) + assert(Option.isSome attr) let i = I_seqpoint (Option.get attr) codebuf.Add i // Save the first sequence point away to snap it to the top of the method @@ -1476,7 +1476,7 @@ type CodeGenBuffer(m:range, for kvp in codeLabelToCodeLabel -> (kvp.Key, lab2pc 0 kvp.Key) ] ), instrs, ResizeArray.toList exnSpecs, - isSome seqpoint + Option.isSome seqpoint module CG = let EmitInstr (cgbuf:CodeGenBuffer) pops pushes i = cgbuf.EmitInstr(pops,pushes,i) @@ -2567,7 +2567,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel = let mspec = mkILMethSpec (mspec.MethodRef, boxity,ilEnclArgTys,ilMethArgTys) // "Unit" return types on static methods become "void" - let mustGenerateUnitAfterCall = isNone returnTy + let mustGenerateUnitAfterCall = Option.isNone returnTy let ccallInfo = match valUseFlags with @@ -2577,7 +2577,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel = let isBaseCall = match valUseFlags with VSlotDirectCall -> true | _ -> false let isTailCall = - if isNil laterArgs && not isSelfInit then + if List.isEmpty laterArgs && not isSelfInit then let isDllImport = IsValRefIsDllImport cenv.g vref let hasByrefArg = mspec.FormalArgTypes |> ILList.exists (function ILType.Byref _ -> true | _ -> false) let makesNoCriticalTailcalls = vref.MakesNoCriticalTailcalls @@ -2628,8 +2628,8 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel = if cenv.opts.generateDebugSymbols && mustGenerateUnitAfterCall && (isTailCall = Normalcall) then CG.EmitInstrs cgbuf (pop 0) Push0 [ AI_nop ] - if isNil laterArgs then - assert isNil whereSaved + if List.isEmpty laterArgs then + assert List.isEmpty whereSaved // Generate the "unit" value if necessary CommitCallSequel cenv eenv m eenv.cloc cgbuf mustGenerateUnitAfterCall sequel else @@ -2656,7 +2656,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel = and CanTailcall (hasStructObjArg, ccallInfo, withinSEH, hasByrefArg, mustGenerateUnitAfterCall, isDllImport, isSelfInit, makesNoCriticalTailcalls, sequel) = // Can't tailcall with a struct object arg since it involves a byref // Can't tailcall with a .NET 2.0 generic constrained call since it involves a byref - if not hasStructObjArg && isNone ccallInfo && not withinSEH && not hasByrefArg && not isDllImport && not isSelfInit && not makesNoCriticalTailcalls && + if not hasStructObjArg && Option.isNone ccallInfo && not withinSEH && not hasByrefArg && not isDllImport && not isSelfInit && not makesNoCriticalTailcalls && // We can tailcall even if we need to generate "unit", as long as we're about to throw the value away anyway as par of the return. // We can tailcall if we don't need to generate "unit", as long as we're about to return. (match sequelIgnoreEndScopes sequel with @@ -3048,7 +3048,7 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel = errorR(InternalError(sprintf "%s: bad instruction: %A" s i,m)) let modFieldSpec fspec = - if isNil ilTyArgs then + if List.isEmpty ilTyArgs then fspec else {fspec with EnclosingType= @@ -3083,7 +3083,7 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel = // "Add an I_nop if this is an initonly field to make sure we never recognize it as an lvalue. See mkExprAddrOfExpr." | _ -> - if not (isNil tyargs) then err "Bad polymorphic IL instruction" + if not (List.isEmpty tyargs) then err "Bad polymorphic IL instruction" i) match ilAfterInst,args,sequel,ilReturnTys with @@ -3182,7 +3182,7 @@ and GenAsmCode cenv cgbuf eenv (il,tyargs,args,returnTys,m) sequel = CG.EmitInstrs cgbuf (pop args.Length) (Push ilReturnTys) ilAfterInst // If no return values were specified generate a "unit" - if isNil returnTys then + if List.isEmpty returnTys then GenUnitThenSequel cenv eenv m eenv.cloc cgbuf sequel else GenSequel cenv eenv.cloc cgbuf sequel @@ -3247,7 +3247,7 @@ and GenILCall cenv cgbuf eenv (virt,valu,newobj,valUseFlags,isDllImport,ilMethRe let isBaseCall = match valUseFlags with VSlotDirectCall -> true | _ -> false let ccallInfo = match valUseFlags with PossibleConstrainedCall ty -> Some ty | _ -> None let boxity = (if valu then AsValue else AsObject) - let mustGenerateUnitAfterCall = (isNil returnTys) + let mustGenerateUnitAfterCall = List.isEmpty returnTys let makesNoCriticalTailcalls = (newobj || not virt) // Don't tailcall for 'newobj', or 'call' to IL code let tail = CanTailcall(valu,ccallInfo,eenv.withinSEH,hasByrefArg,mustGenerateUnitAfterCall,isDllImport,false,makesNoCriticalTailcalls,sequel) @@ -3542,7 +3542,7 @@ and GenObjectExpr cenv cgbuf eenvouter expr (baseType,baseValOpt,basecall,overri let ilxCloSpec = cloinfo.cloSpec let ilCloFreeVars = cloinfo.cloILFreeVars let ilCloGenericFormals = cloinfo.cloILGenericParams - assert(isNil cloinfo.localTypeFuncDirectILGenericParams) + assert (List.isEmpty cloinfo.localTypeFuncDirectILGenericParams) let ilCloGenericActuals = cloinfo.cloSpec.GenericArgs let ilCloRetTy = cloinfo.cloILFormalRetTy let ilCloTypeRef = cloinfo.cloSpec.TypeRef @@ -4230,7 +4230,7 @@ and GenMatch cenv cgbuf eenv (spBind,_exprm,tree,targets,m,ty) sequel = // // In both cases, any instructions that come after this point will be falsely associated with the last branch of the control // prior to the join point. This is base, e.g. see FSharp 1.0 bug 5155 - if nonNil stackAfterJoin then + if not (List.isEmpty stackAfterJoin) then cgbuf.EmitStartOfHiddenCode() GenSequel cenv eenv.cloc cgbuf sequelAfterJoin @@ -4389,7 +4389,7 @@ and GenDecisionTreeSwitch cenv cgbuf inplabOpt stackAtTargets eenv e cases defau | Test.ArrayLength _ | Test.IsNull | Test.Const(Const.Zero) -> - if List.length cases <> 1 || isNone defaultTargetOpt then failwith "internal error: GenDecisionTreeSwitch: Test.IsInst/isnull/query" + if List.length cases <> 1 || Option.isNone defaultTargetOpt then failwith "internal error: GenDecisionTreeSwitch: Test.IsInst/isnull/query" let bi = match firstDiscrim with | Test.Const(Const.Zero) -> @@ -4564,7 +4564,7 @@ and GenLetRecBinds cenv cgbuf eenv (allBinds: Bindings,m) = let computeFixupsForOneRecursiveVar boundv forwardReferenceSet fixups selfv access set e = match e with | Expr.Lambda _ | Expr.TyLambda _ | Expr.Obj _ -> - let isLocalTypeFunc = (isSome selfv && (IsNamedLocalTypeFuncVal cenv.g (Option.get selfv) e)) + let isLocalTypeFunc = Option.isSome selfv && (IsNamedLocalTypeFuncVal cenv.g (Option.get selfv) e) let selfv = (match e with Expr.Obj _ -> None | _ when isLocalTypeFunc -> None | _ -> Option.map mkLocalValRef selfv) let clo,_,eenvclo = GetIlxClosureInfo cenv m isLocalTypeFunc selfv {eenv with letBoundVars=(mkLocalValRef boundv)::eenv.letBoundVars} e clo.cloFreeVars |> List.iter (fun fv -> @@ -5019,8 +5019,7 @@ and GenEventForProperty cenv eenvForMeth (mspec:ILMethodSpec) (v:Val) ilAttrsTha and ComputeFlagFixupsForMemberBinding cenv (v:Val,memberInfo:ValMemberInfo) = - - if isNil memberInfo.ImplementedSlotSigs then + if List.isEmpty memberInfo.ImplementedSlotSigs then [fixupVirtualSlotFlags] else memberInfo.ImplementedSlotSigs |> List.map (fun slotsig -> @@ -5031,15 +5030,15 @@ and ComputeFlagFixupsForMemberBinding cenv (v:Val,memberInfo:ValMemberInfo) = let useMethodImpl = // REVIEW: it would be good to get rid of this special casing of Compare and GetHashCode during code generation let isCompare = - (isSome tcref.GeneratedCompareToValues && typeEquiv cenv.g oty cenv.g.mk_IComparable_ty) || - (isSome tcref.GeneratedCompareToValues && tyconRefEq cenv.g cenv.g.system_GenericIComparable_tcref otcref) + (Option.isSome tcref.GeneratedCompareToValues && typeEquiv cenv.g oty cenv.g.mk_IComparable_ty) || + (Option.isSome tcref.GeneratedCompareToValues && tyconRefEq cenv.g cenv.g.system_GenericIComparable_tcref otcref) let isGenericEquals = - (isSome tcref.GeneratedHashAndEqualsWithComparerValues && tyconRefEq cenv.g cenv.g.system_GenericIEquatable_tcref otcref) + (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && tyconRefEq cenv.g cenv.g.system_GenericIEquatable_tcref otcref) let isStructural = - (isSome tcref.GeneratedCompareToWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralComparable_ty) || - (isSome tcref.GeneratedHashAndEqualsWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralEquatable_ty) + (Option.isSome tcref.GeneratedCompareToWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralComparable_ty) || + (Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues && typeEquiv cenv.g oty cenv.g.mk_IStructuralEquatable_ty) isInterfaceTy cenv.g oty && not isCompare && not isStructural && not isGenericEquals @@ -5118,7 +5117,7 @@ and GenMethodForBinding let hasPreserveSigNamedArg,ilMethodBody,_hasDllImport = match TryFindFSharpAttributeOpt cenv.g cenv.g.attrib_DllImportAttribute v.Attribs with | Some (Attrib(_,_,[ AttribStringArg(dll) ],namedArgs,_,_,m)) -> - if nonNil tps then error(Error(FSComp.SR.ilSignatureForExternalFunctionContainsTypeParameters(),m)) + if not (List.isEmpty tps) then error(Error(FSComp.SR.ilSignatureForExternalFunctionContainsTypeParameters(),m)) let hasPreserveSigNamedArg, mbody = GenPInvokeMethod (v.CompiledName,dll,namedArgs) hasPreserveSigNamedArg, mbody, true @@ -5212,13 +5211,13 @@ and GenMethodForBinding let ilMethTypars = ilTypars |> List.drop mspec.EnclosingType.GenericArgs.Length if memberInfo.MemberFlags.MemberKind = MemberKind.Constructor then - assert (isNil ilMethTypars) + assert (List.isEmpty ilMethTypars) let mdef = mkILCtor (access,ilParams,ilMethodBody) let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) } EmitTheMethodDef mdef elif memberInfo.MemberFlags.MemberKind = MemberKind.ClassConstructor then - assert (isNil ilMethTypars) + assert (List.isEmpty ilMethTypars) let mdef = mkILClassCtor ilMethodBody let mdef = { mdef with CustomAttrs= mkILCustomAttrs (ilAttrsThatGoOnPrimaryItem @ sourceNameAttribs @ ilAttrsCompilerGenerated) } EmitTheMethodDef mdef @@ -5258,7 +5257,7 @@ and GenMethodForBinding match memberInfo.MemberFlags.MemberKind with | (MemberKind.PropertySet | MemberKind.PropertyGet) -> - if nonNil ilMethTypars then + if not (List.isEmpty ilMethTypars) then error(InternalError("A property may not be more generic than the enclosing type - constrain the polymorphism in the expression",v.Range)) // Check if we're compiling the property as a .NET event @@ -5408,7 +5407,7 @@ and GenSetStorage m cgbuf storage = and CommitGetStorageSequel cenv cgbuf eenv m typ localCloInfo storeSequel = match localCloInfo,storeSequel with | Some {contents =NamedLocalIlxClosureInfoGenerator _cloinfo},_ -> error(InternalError("Unexpected generator",m)) - | Some {contents =NamedLocalIlxClosureInfoGenerated cloinfo},Some (tyargs,args,m,sequel) when nonNil tyargs -> + | Some {contents =NamedLocalIlxClosureInfoGenerated cloinfo},Some (tyargs,args,m,sequel) when not (List.isEmpty tyargs) -> let actualRetTy = GenNamedLocalTyFuncCall cenv cgbuf eenv typ cloinfo tyargs m CommitGetStorageSequel cenv cgbuf eenv m actualRetTy None (Some ([],args,m,sequel)) | _, None -> () @@ -5451,7 +5450,7 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (typ,ilTy) storage storeSequel = GenLambda cenv cgbuf eenv false None expr Continue | Some (tyargs',args,m,sequel) -> let specializedExpr = - if isNil args && isNil tyargs' then failwith ("non-lambda at use of method " + mspec.Name) + if List.isEmpty args && List.isEmpty tyargs' then failwith ("non-lambda at use of method " + mspec.Name) MakeApplicationAndBetaReduce cenv.g (expr,exprty,[tyargs'],args,m) GenExpr cenv cgbuf eenv SPSuppress specializedExpr sequel @@ -5498,7 +5497,7 @@ and AllocLocalVal cenv cgbuf v eenv repr scopeMarks = let repr,eenv = let ty = v.Type if isUnitTy cenv.g ty && not v.IsMutable then Null,eenv - elif isSome repr && IsNamedLocalTypeFuncVal cenv.g v (Option.get repr) then + elif Option.isSome repr && IsNamedLocalTypeFuncVal cenv.g v (Option.get repr) then (* known, named, non-escaping type functions *) let cloinfoGenerate eenv = let eenvinner = @@ -5828,7 +5827,7 @@ and GenTopImpl cenv mgbuf mainInfoOpt eenv (TImplFile(qname, _, mexpr, hasExplic cenv.optimizeDuringCodeGen <- optimizeDuringCodeGen // This is used to point the inner classes back to the startup module for initialization purposes - let isFinalFile = isSome mainInfoOpt + let isFinalFile = Option.isSome mainInfoOpt let initClassCompLoc = CompLocForInitClass eenv.cloc let initClassTy = mkILTyForCompLoc initClassCompLoc @@ -6111,8 +6110,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = // HOWEVER, if the type doesn't override Object.Equals already. let augmentOverrideMethodDefs = - (if isNone tycon.GeneratedCompareToValues && - isNone tycon.GeneratedHashAndEqualsValues && + (if Option.isNone tycon.GeneratedCompareToValues && + Option.isNone tycon.GeneratedHashAndEqualsValues && tycon.HasInterface cenv.g cenv.g.mk_IComparable_ty && not (tycon.HasOverride cenv.g "Equals" [cenv.g.obj_ty]) && not tycon.IsFSharpInterfaceTycon @@ -6175,7 +6174,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = | None -> None | Some memberInfo -> match name, memberInfo.MemberFlags.MemberKind with - | ("Item" | "op_IndexedLookup"), (MemberKind.PropertyGet | MemberKind.PropertySet) when nonNil (ArgInfosOfPropertyVal cenv.g vref.Deref) -> + | ("Item" | "op_IndexedLookup"), (MemberKind.PropertyGet | MemberKind.PropertySet) when not (List.isEmpty (ArgInfosOfPropertyVal cenv.g vref.Deref)) -> Some( mkILCustomAttribute cenv.g.ilg (mkILTyRef (cenv.g.ilg.traits.ScopeRef,"System.Reflection.DefaultMemberAttribute"),[cenv.g.ilg.typ_String],[ILAttribElem.String(Some(name))],[]) ) | _ -> None) |> Option.toList @@ -6185,7 +6184,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = // DebugDisplayAttribute gets copied to the subtypes generated as part of DU compilation let debugDisplayAttrs,normalAttrs = tycon.Attribs |> List.partition (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_DebuggerDisplayAttribute) let securityAttrs,normalAttrs = normalAttrs |> List.partition (fun a -> IsSecurityAttribute cenv.g cenv.amap cenv.casApplied a m) - let generateDebugDisplayAttribute = not cenv.g.compilingFslib && tycon.IsUnionTycon && isNil debugDisplayAttrs + let generateDebugDisplayAttribute = not cenv.g.compilingFslib && tycon.IsUnionTycon && List.isEmpty debugDisplayAttrs let generateDebugProxies = (not (tyconRefEq cenv.g tcref cenv.g.unit_tcr_canon) && not (HasFSharpAttribute cenv.g cenv.g.attrib_DebuggerTypeProxyAttribute tycon.Attribs)) @@ -6699,7 +6698,7 @@ and GenExnDef cenv mgbuf eenv m (exnc:Tycon) = // In compiled code, all exception types get a parameterless constructor for use with XML serialization // This does default-initialization of all fields let ilCtorDefNoArgs = - if nonNil fieldNamesAndTypes then + if not (List.isEmpty fieldNamesAndTypes) then [ mkILSimpleStorageCtor(None, Some cenv.g.ilg.tspec_Exception, ilThisTy, [], reprAccess) ] else [] diff --git a/src/fsharp/InfoReader.fs b/src/fsharp/InfoReader.fs index 7afd9eefdc2..f0697622b67 100644 --- a/src/fsharp/InfoReader.fs +++ b/src/fsharp/InfoReader.fs @@ -280,13 +280,13 @@ type InfoReader(g:TcGlobals, amap:Import.ImportMap) = let einfos = ComputeImmediateIntrinsicEventsOfType (optFilter,ad) m typ let rfinfos = GetImmediateIntrinsicRecdOrClassFieldsOfType (optFilter,ad) m typ match acc with - | Some(MethodItem(inheritedMethSets)) when nonNil minfos -> Some(MethodItem (minfos::inheritedMethSets)) - | _ when nonNil minfos -> Some(MethodItem ([minfos])) - | Some(PropertyItem(inheritedPropSets)) when nonNil pinfos -> Some(PropertyItem(pinfos::inheritedPropSets)) - | _ when nonNil pinfos -> Some(PropertyItem([pinfos])) - | _ when nonNil finfos -> Some(ILFieldItem(finfos)) - | _ when nonNil einfos -> Some(EventItem(einfos)) - | _ when nonNil rfinfos -> + | Some(MethodItem(inheritedMethSets)) when not (List.isEmpty minfos) -> Some(MethodItem (minfos::inheritedMethSets)) + | _ when not (List.isEmpty minfos) -> Some(MethodItem ([minfos])) + | Some(PropertyItem(inheritedPropSets)) when not (List.isEmpty pinfos) -> Some(PropertyItem(pinfos::inheritedPropSets)) + | _ when not (List.isEmpty pinfos) -> Some(PropertyItem([pinfos])) + | _ when not (List.isEmpty finfos) -> Some(ILFieldItem(finfos)) + | _ when not (List.isEmpty einfos) -> Some(EventItem(einfos)) + | _ when not (List.isEmpty rfinfos) -> match rfinfos with | [single] -> Some(RecdFieldItem(single)) | _ -> failwith "Unexpected multiple fields with the same name" // Because an explicit name (i.e., nm) was supplied, there will be only one element at most. diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs index 40bf6bbb8a8..447896a1a7e 100644 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs @@ -201,7 +201,7 @@ module Pass1_DetermineTLRAndArities = let nFormals = vss.Length let nMaxApplied = GetMaxNumArgsAtUses xinfo f let arity = Operators.min nFormals nMaxApplied - if atTopLevel || arity<>0 || nonNil tps then Some (f,arity) + if atTopLevel || arity<>0 || not (List.isEmpty tps) then Some (f,arity) else None /// Check if f involves any value recursion (so can skip those). @@ -935,7 +935,7 @@ module Pass4_RewriteAssembly = /// collect Top* repr bindings - if needed... #if TLR_LIFT let LiftTopBinds isRec _penv z binds = - let isTopBind (bind: Binding) = isSome bind.Var.ValReprInfo + let isTopBind (bind: Binding) = Option.isSome bind.Var.ValReprInfo let topBinds,otherBinds = FlatList.partition isTopBind binds let liftTheseBindings = !liftTLR && // lifting enabled @@ -1087,7 +1087,7 @@ module Pass4_RewriteAssembly = let args = aenvExprs @ args mkApps penv.g ((exprForVal m fHat, fHat.Type),[tys],args,m) (* change, direct fHat call with closure (reqdTypars,aenvs) *) | _ -> - if isNil tys && isNil args then + if List.isEmpty tys && List.isEmpty args then fx else Expr.App (fx,fty,tys,args,m) (* no change, f is expr *) diff --git a/src/fsharp/LexFilter.fs b/src/fsharp/LexFilter.fs index 5ef87ac8f58..19f84669aaa 100755 --- a/src/fsharp/LexFilter.fs +++ b/src/fsharp/LexFilter.fs @@ -1153,7 +1153,7 @@ type LexFilterImpl (lightSyntaxStatus:LightSyntaxStatus, compilingFsLib, lexer, // Balancing rule. Every 'done' terminates all surrounding blocks up to a CtxtDo, and will be swallowed by // terminating the corresponding CtxtDo in the rule below. let tokenForcesHeadContextClosure token stack = - nonNil stack && + not (List.isEmpty stack) && match token with | Parser.EOF _ -> true | SEMICOLON_SEMICOLON -> not (tokenBalancesHeadContext token stack) diff --git a/src/fsharp/LowerCallsAndSeqs.fs b/src/fsharp/LowerCallsAndSeqs.fs index 34289568ad8..24542ecf091 100644 --- a/src/fsharp/LowerCallsAndSeqs.fs +++ b/src/fsharp/LowerCallsAndSeqs.fs @@ -386,7 +386,7 @@ let LowerSeqExpr g amap overallExpr = let tgl = targets |> Array.map (fun (TTarget(_vs,e,_spTarget)) -> Lower false isTailCall noDisposeContinuationLabel currentDisposeContinuationLabel e) |> Array.toList // LIMITATION: non-trivial pattern matches involving or-patterns or active patterns where bindings can't be // transferred to the r.h.s. are not yet compiled. - if tgl |> List.forall isSome then + if tgl |> List.forall Option.isSome then let tgl = List.map Option.get tgl let labs = tgl |> List.collect (fun res -> res.labels) let stateVars = tgl |> List.collect (fun res -> res.stateVars) @@ -400,8 +400,8 @@ let LowerSeqExpr g amap overallExpr = gtg,dispose,checkDispose) |> List.unzip3 let generate = primMkMatch (spBind,exprm,pt,Array.ofList gtgs,m,ty) - let dispose = if isNil disposals then mkUnit g m else List.reduce (mkCompGenSequential m) disposals - let checkDispose = if isNil checkDisposes then mkFalse g m else List.reduce (mkCompGenSequential m) checkDisposes + let dispose = if List.isEmpty disposals then mkUnit g m else List.reduce (mkCompGenSequential m) disposals + let checkDispose = if List.isEmpty checkDisposes then mkFalse g m else List.reduce (mkCompGenSequential m) checkDisposes generate,dispose,checkDispose) labels=labs stateVars = stateVars diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index d00e2e217f6..6941a888938 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -145,7 +145,7 @@ let AdjustCalledArgType (infoReader:InfoReader) isConstraint (calledArg: CalledA let calledArgTy = let adjustDelegateTy calledTy = let (SigOfFunctionForDelegate(_,delArgTys,_,fty)) = GetSigOfFunctionForDelegate infoReader calledTy m AccessibleFromSomeFSharpCode - let delArgTys = (if isNil delArgTys then [g.unit_ty] else delArgTys) + let delArgTys = if List.isEmpty delArgTys then [g.unit_ty] else delArgTys if (fst (stripFunTy g callerArgTy)).Length = delArgTys.Length then fty else calledArgTy @@ -388,11 +388,11 @@ type CalledMeth<'T> member x.NumArgSets = x.ArgSets.Length - member x.HasOptArgs = nonNil x.UnnamedCalledOptArgs - member x.HasOutArgs = nonNil x.UnnamedCalledOutArgs + member x.HasOptArgs = not (List.isEmpty x.UnnamedCalledOptArgs) + member x.HasOutArgs = not (List.isEmpty x.UnnamedCalledOutArgs) member x.UsesParamArrayConversion = x.ArgSets |> List.exists (fun argSet -> argSet.ParamArrayCalledArgOpt.IsSome) member x.ParamArrayCalledArgOpt = x.ArgSets |> List.tryPick (fun argSet -> argSet.ParamArrayCalledArgOpt) - member x.ParamArrayCallerArgs = x.ArgSets |> List.tryPick (fun argSet -> if isSome argSet.ParamArrayCalledArgOpt then Some argSet.ParamArrayCallerArgs else None ) + member x.ParamArrayCallerArgs = x.ArgSets |> List.tryPick (fun argSet -> if Option.isSome argSet.ParamArrayCalledArgOpt then Some argSet.ParamArrayCallerArgs else None ) member x.ParamArrayElementType = assert (x.UsesParamArrayConversion) x.ParamArrayCalledArgOpt.Value.CalledArgumentType |> destArrayTy x.amap.g @@ -401,7 +401,7 @@ type CalledMeth<'T> member x.NumCalledTyArgs = x.CalledTyArgs.Length member x.NumCallerTyArgs = x.CallerTyArgs.Length - member x.AssignsAllNamedArgs = isNil x.UnassignedNamedArgs + member x.AssignsAllNamedArgs = List.isEmpty x.UnassignedNamedArgs member x.HasCorrectArity = (x.NumCalledTyArgs = x.NumCallerTyArgs) && @@ -533,11 +533,11 @@ let TakeObjAddrForMethodCall g amap (minfo:MethInfo) isMutable m objArgs f = match objArgs with | [objArgExpr] -> let objArgTy = tyOfExpr g objArgExpr - let wrap,objArgExpr' = mkExprAddrOfExpr g mustTakeAddress (isSome ccallInfo) isMutable objArgExpr None m + let wrap,objArgExpr' = mkExprAddrOfExpr g mustTakeAddress (Option.isSome ccallInfo) isMutable objArgExpr None m // Extension members and calls to class constraints may need a coercion for their object argument let objArgExpr' = - if isNone ccallInfo && // minfo.IsExtensionMember && minfo.IsStruct && + if Option.isNone ccallInfo && // minfo.IsExtensionMember && minfo.IsStruct && not (TypeDefinitelySubsumesTypeNoCoercion 0 g amap m minfo.EnclosingType objArgTy) then mkCoerceExpr(objArgExpr',minfo.EnclosingType,m,objArgTy) else @@ -775,7 +775,7 @@ let BuildNewDelegateExpr (eventInfoOpt:EventInfo option, g, amap, delegateTy, in // Try to pull apart an explicit lambda and use it directly // Don't do this in the case where we're adjusting the arguments of a function used to build a .NET-compatible event handler let lambdaContents = - if isSome eventInfoOpt then + if Option.isSome eventInfoOpt then None else tryDestTopLambda g amap topValInfo (f, fty) @@ -796,7 +796,7 @@ let BuildNewDelegateExpr (eventInfoOpt:EventInfo option, g, amap, delegateTy, in | h :: _ when not (isObjTy g h.Type) -> error(nonStandardEventError einfo.EventName m) | h :: t -> [exprForVal m h; mkRefTupledVars g m t] | None -> - if isNil delArgTys then [mkUnit g m] else List.map (exprForVal m) delArgVals + if List.isEmpty delArgTys then [mkUnit g m] else List.map (exprForVal m) delArgVals mkApps g ((f,fty),[],args,m) delArgVals,expr diff --git a/src/fsharp/MethodOverrides.fs b/src/fsharp/MethodOverrides.fs index cc210ade4cb..b446ea5c06d 100644 --- a/src/fsharp/MethodOverrides.fs +++ b/src/fsharp/MethodOverrides.fs @@ -407,7 +407,7 @@ module DispatchSlotChecking = // Check that, for each implemented type, at least one implemented type is implied. This is enough to capture // duplicates. for (_i, reqdTy, m, impliedTys) in reqdTyInfos do - if isInterfaceTy g reqdTy && isNil impliedTys then + if isInterfaceTy g reqdTy && List.isEmpty impliedTys then errorR(Error(FSComp.SR.typrelDuplicateInterface(),m)) // Check that no interface type is implied twice @@ -418,7 +418,7 @@ module DispatchSlotChecking = if i > j then let overlap = ListSet.intersect (TypesFeasiblyEquiv 0 g amap reqdTyRange) impliedTys impliedTys2 overlap |> List.iter (fun overlappingTy -> - if nonNil(GetImmediateIntrinsicMethInfosOfType (None,AccessibleFromSomewhere) g amap reqdTyRange overlappingTy |> List.filter (fun minfo -> minfo.IsVirtual)) then + if not (List.isEmpty (GetImmediateIntrinsicMethInfosOfType (None,AccessibleFromSomewhere) g amap reqdTyRange overlappingTy |> List.filter (fun minfo -> minfo.IsVirtual))) then errorR(Error(FSComp.SR.typrelNeedExplicitImplementation(NicePrint.minimalStringOfType denv (List.head overlap)),reqdTyRange))) // Get the SlotImplSet for each implemented type @@ -605,8 +605,8 @@ module DispatchSlotChecking = // Modify map the slotsig so it is in terms of the type parameters for the overriding method let slotsig = ReparentSlotSigToUseMethodTypars g m overrideBy slotsig - // Record the slotsig via mutation - yield slotsig ] + // Record the slotsig via mutation + yield slotsig ] //if mustOverrideSomething reqdTy overrideBy then // assert nonNil overridenForThisSlotImplSet yield! overridenForThisSlotImplSet ] @@ -634,7 +634,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader:InfoReader, nenv, #if EXTENSIONTYPING not tycon.IsProvidedGeneratedTycon && #endif - isNone tycon.GeneratedCompareToValues && + Option.isNone tycon.GeneratedCompareToValues && tycon.HasInterface g g.mk_IComparable_ty && not (tycon.HasOverride g "Equals" [g.obj_ty]) && not tycon.IsFSharpInterfaceTycon @@ -657,7 +657,7 @@ let FinalTypeDefinitionChecksAtEndOfInferenceScope (infoReader:InfoReader, nenv, let hasExplicitObjectGetHashCode = tycon.HasOverride g "GetHashCode" [] let hasExplicitObjectEqualsOverride = tycon.HasOverride g "Equals" [g.obj_ty] - if (isSome tycon.GeneratedHashAndEqualsWithComparerValues) && + if (Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues) && (hasExplicitObjectGetHashCode || hasExplicitObjectEqualsOverride) then errorR(Error(FSComp.SR.typrelExplicitImplementationOfGetHashCodeOrEquals(tycon.DisplayName),m)) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs old mode 100755 new mode 100644 index 293a71a58d6..bb6ad631ea0 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -70,12 +70,12 @@ let UnionCaseRefsInModuleOrNamespace (modref:ModuleOrNamespaceRef) = /// Try to find a type with a union case of the given name let TryFindTypeWithUnionCase (modref:ModuleOrNamespaceRef) (id: Ident) = modref.ModuleOrNamespaceType.AllEntities - |> QueueList.tryFind (fun tycon -> tycon.GetUnionCaseByName id.idText |> isSome) + |> QueueList.tryFind (fun tycon -> tycon.GetUnionCaseByName id.idText |> Option.isSome) /// Try to find a type with a record field of the given name let TryFindTypeWithRecdField (modref:ModuleOrNamespaceRef) (id: Ident) = modref.ModuleOrNamespaceType.AllEntities - |> QueueList.tryFind (fun tycon -> tycon.GetFieldByName id.idText |> isSome) + |> QueueList.tryFind (fun tycon -> tycon.GetFieldByName id.idText |> Option.isSome) /// Get the active pattern elements defined by a given value, if any let ActivePatternElemsOfValRef vref = @@ -1662,14 +1662,14 @@ let private ResolveObjectConstructorPrim (ncenv:NameResolver) edenv resInfo m ad success (resInfo,Item.DelegateCtor typ) else let ctorInfos = GetIntrinsicConstructorInfosOfType ncenv.InfoReader m typ - if isInterfaceTy g typ && isNil ctorInfos then + if isInterfaceTy g typ && List.isEmpty ctorInfos then success (resInfo, Item.FakeInterfaceCtor typ) else let defaultStructCtorInfo = if (isStructTy g typ && not (isRecdTy g typ) && not (isUnionTy g typ) && not(ctorInfos |> List.exists (fun x -> x.IsNullary))) then [DefaultStructCtor(g,typ)] else [] - if (isNil defaultStructCtorInfo && isNil ctorInfos) || not (isAppTy g typ) then + if (List.isEmpty defaultStructCtorInfo && List.isEmpty ctorInfos) || not (isAppTy g typ) then raze (Error(FSComp.SR.nrNoConstructorsAvailableForType(NicePrint.minimalStringOfType edenv typ),m)) else let ctorInfos = ctorInfos |> List.filter (IsMethInfoAccessible amap m ad) @@ -1838,7 +1838,7 @@ let DecodeFSharpEvent (pinfos:PropInfo list) ad g (ncenv:NameResolver) m = | _ -> // FOUND PROPERTY-AS-EVENT BUT DIDN'T FIND CORRESPONDING ADD/REMOVE METHODS Some(Item.Property (nm,pinfos)) - | pinfo::_ when nonNil pinfos -> + | pinfo::_ when not (List.isEmpty pinfos) -> let nm = CoreDisplayName(pinfo) Some(Item.Property (nm,pinfos)) | _ -> @@ -1894,20 +1894,19 @@ let rec ResolveLongIdentInTypePrim (ncenv:NameResolver) nenv lookupKind (resInfo success(resInfo,Item.RecdField(rfinfo),rest) | _ -> let pinfos = ExtensionPropInfosOfTypeInScope ncenv.InfoReader nenv (optFilter, ad) m typ - if nonNil pinfos && (match lookupKind with LookupKind.Expr -> true | _ -> false) then + if not (List.isEmpty pinfos) && (match lookupKind with LookupKind.Expr -> true | _ -> false) then success (resInfo,Item.Property (nm,pinfos),rest) else - let minfos = ExtensionMethInfosOfTypeInScope ncenv.InfoReader nenv optFilter m typ - if nonNil minfos && (match lookupKind with LookupKind.Expr -> true | _ -> false) then + if not (List.isEmpty minfos) && (match lookupKind with LookupKind.Expr -> true | _ -> false) then success (resInfo,Item.MakeMethGroup (nm,minfos),rest) elif isTyparTy g typ then raze (IndeterminateType(unionRanges m id.idRange)) else raze (UndefinedName (depth,FSComp.SR.undefinedNameFieldConstructorOrMember, id,NoPredictions)) let nestedSearchAccessible = - let nestedTypes = GetNestedTypesOfType (ad, ncenv, Some nm, (if isNil rest then typeNameResInfo.StaticArgsInfo else TypeNameResolutionStaticArgsInfo.Indefinite), true, m) typ - if isNil rest then - if isNil nestedTypes then + let nestedTypes = GetNestedTypesOfType (ad, ncenv, Some nm, (if List.isEmpty rest then typeNameResInfo.StaticArgsInfo else TypeNameResolutionStaticArgsInfo.Indefinite), true, m) typ + if List.isEmpty rest then + if List.isEmpty nestedTypes then NoResultsOrUsefulErrors else match typeNameResInfo.ResolutionFlag with @@ -1981,9 +1980,9 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeN // Something in a type? let tyconSearch = - let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, ad, id.idText, (if isNil rest then typeNameResInfo.StaticArgsInfo else TypeNameResolutionStaticArgsInfo.Indefinite), modref) + let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, ad, id.idText, (if List.isEmpty rest then typeNameResInfo.StaticArgsInfo else TypeNameResolutionStaticArgsInfo.Indefinite), modref) let tcrefs = tcrefs |> List.map (fun tcref -> (resInfo,tcref)) - if nonNil rest then + if not (List.isEmpty rest) then let tcrefs = CheckForTypeLegitimacyAndMultipleGenericTypeAmbiguities (tcrefs, TypeNameResolutionInfo (ResolveTypeNamesToTypeRefs,TypeNameResolutionStaticArgsInfo.Indefinite), PermitDirectReferenceToGeneratedType.No, unionRanges m id.idRange) ResolveLongIdentInTyconRefs ncenv nenv LookupKind.Expr (depth+1) m ad rest typeNameResInfo id.idRange tcrefs // Check if we've got some explicit type arguments @@ -2003,7 +2002,7 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeN // Something in a sub-namespace or sub-module let moduleSearch = - if (nonNil rest) then + if not (List.isEmpty rest) then match mty.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> let resInfo = resInfo.AddEntity(id.idRange,submodref) @@ -2014,8 +2013,15 @@ let rec ResolveExprLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv (typeN else NoResultsOrUsefulErrors - AtMostOneResult id.idRange ( tyconSearch +++ moduleSearch +++ raze (UndefinedName(depth,FSComp.SR.undefinedNameValueConstructorNamespaceOrType,id,NoPredictions))) + match tyconSearch +++ moduleSearch with + | Result [] -> + let predictedPossibleTypes = + modref.ModuleOrNamespaceType.AllEntities + |> Seq.map (fun e -> e.DisplayName) + |> Set.ofSeq + raze (UndefinedName(depth,FSComp.SR.undefinedNameValueConstructorNamespaceOrType,id,predictedPossibleTypes)) + | results -> AtMostOneResult id.idRange results /// An identifier has resolved to a type name in an expression (corresponding to one or more TyconRefs). /// Return either a set of constructors (later refined by overload resolution), or a set of TyconRefs. @@ -2195,13 +2201,13 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num let tcrefs = tcrefs |> List.map (fun tcref -> (resInfo,tcref)) let tyconSearch = match lid with - | _tn:: rest when nonNil rest -> + | _tn:: rest when not (List.isEmpty rest) -> ResolveLongIdentInTyconRefs (ncenv:NameResolver) nenv LookupKind.Pattern (depth+1) m ad rest numTyArgsOpt id.idRange tcrefs | _ -> NoResultsOrUsefulErrors // Constructor of a type? let ctorSearch = - if isNil rest then + if List.isEmpty rest then tcrefs |> List.map (fun (resInfo,tcref) -> (resInfo,FreshenTycon ncenv m tcref)) |> CollectResults (fun (resInfo,typ) -> ResolveObjectConstructorPrim ncenv nenv.eDisplayEnv resInfo id.idRange ad typ) @@ -2211,7 +2217,7 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv:NameResolver) nenv num // Something in a sub-namespace or sub-module or nested-type let moduleSearch = - if nonNil rest then + if not (List.isEmpty rest) then match mty.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> let resInfo = resInfo.AddEntity(id.idRange,submodref) @@ -2261,7 +2267,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv:NameResolver) fullyQualified war (ResolvePatternLongIdentInModuleOrNamespace ncenv nenv numTyArgsOpt ad) let tyconSearch ad = match lid with - | tn:: rest when nonNil rest -> + | tn :: rest when not (List.isEmpty rest) -> let tcrefs = LookupTypeNameInEnvNoArity fullyQualified tn.idText nenv let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty,tcref)) ResolveLongIdentInTyconRefs ncenv nenv LookupKind.Pattern 1 tn.idRange ad rest numTyArgsOpt tn.idRange tcrefs @@ -2274,7 +2280,7 @@ let rec ResolvePatternLongIdentPrim sink (ncenv:NameResolver) fullyQualified war ForceRaise (AtMostOneResult m (tyconSearch AccessibleFromSomeFSharpCode +++ moduleSearch AccessibleFromSomeFSharpCode)) ResolutionInfo.SendToSink(sink,ncenv,nenv,ItemOccurence.Use,ad,resInfo,ResultTyparChecker(fun () -> true)) - if nonNil rest then error(Error(FSComp.SR.nrIsNotConstructorOrLiteral(),(List.head rest).idRange)) + if not (List.isEmpty rest) then error(Error(FSComp.SR.nrIsNotConstructorOrLiteral(),(List.head rest).idRange)) res @@ -2294,7 +2300,7 @@ let ResolvePatternLongIdent sink (ncenv:NameResolver) warnOnUpper newDef m ad ne // X.ListEnumerator // does not resolve // let ResolveNestedTypeThroughAbbreviation (ncenv:NameResolver) (tcref: TyconRef) m = - if tcref.IsTypeAbbrev && tcref.Typars(m).IsEmpty && isAppTy ncenv.g tcref.TypeAbbrev.Value && isNil (argsOfAppTy ncenv.g tcref.TypeAbbrev.Value) then + if tcref.IsTypeAbbrev && tcref.Typars(m).IsEmpty && isAppTy ncenv.g tcref.TypeAbbrev.Value && List.isEmpty (argsOfAppTy ncenv.g tcref.TypeAbbrev.Value) then tcrefOfAppTy ncenv.g tcref.TypeAbbrev.Value else tcref @@ -2479,7 +2485,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re // search for type-qualified names, e.g. { Microsoft.FSharp.Core.Ref.contents = 1 } let tyconSearch = match lid with - | _tn:: rest when nonNil rest -> + | _tn:: rest when not (List.isEmpty rest) -> let tcrefs = LookupTypeNameInEntityMaybeHaveArity (ncenv.amap, id.idRange, ad, id.idText, TypeNameResolutionStaticArgsInfo.Indefinite, modref) let tcrefs = tcrefs |> List.map (fun tcref -> (ResolutionInfo.Empty,tcref)) let tyconSearch = ResolveLongIdentInTyconRefs ncenv nenv LookupKind.RecdField (depth+1) m ad rest typeNameResInfo id.idRange tcrefs @@ -2490,7 +2496,7 @@ let rec ResolveFieldInModuleOrNamespace (ncenv:NameResolver) nenv ad (resInfo:Re NoResultsOrUsefulErrors // search for names in nested modules, e.g. { Microsoft.FSharp.Core.contents = 1 } let modulSearch = - if nonNil rest then + if not (List.isEmpty rest) then match modref.ModuleOrNamespaceType.ModulesAndNamespacesByDemangledName.TryFind(id.idText) with | Some(AccessibleEntityRef ncenv.amap m ad modref submodref) -> let resInfo = resInfo.AddEntity(id.idRange,submodref) @@ -2579,7 +2585,7 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields = match ncenv.InfoReader.TryFindRecdOrClassFieldInfoOfType(id.idText,m,typ) with | Some (RecdFieldInfo(_,rfref)) -> [ResolutionInfo.Empty, FieldResolution(rfref,false)] | None -> - let typeName = NicePrint.minimalStringOfType nenv.eDisplayEnv typ + let typeName = NicePrint.minimalStringOfType nenv.eDisplayEnv typ if isRecdTy g typ then // record label doesn't belong to record type -> predict other labels of same record error(Error(SuggestOtherLabelsOfSameRecordType nenv typeName id allFields,m)) @@ -2604,7 +2610,7 @@ let ResolveFieldPrim (ncenv:NameResolver) nenv ad typ (mp,id:Ident) allFields = ResolveLongIndentAsModuleOrNamespaceThen ncenv.amap m OpenQualified nenv ad lid (ResolveFieldInModuleOrNamespace ncenv nenv ad) let resInfo,item,rest = ForceRaise (AtMostOneResult m (modulSearch ad +++ tyconSearch ad +++ modulSearch AccessibleFromSomeFSharpCode +++ tyconSearch AccessibleFromSomeFSharpCode)) - if nonNil rest then errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange)) + if not (List.isEmpty rest) then errorR(Error(FSComp.SR.nrInvalidFieldLabel(),(List.head rest).idRange)) [(resInfo,item)] let ResolveField sink ncenv nenv ad typ (mp,id) allFields = @@ -2676,7 +2682,7 @@ let FilterMethodGroups (ncenv:NameResolver) itemRange item staticOnly = match item with | Item.MethodGroup(nm, minfos, orig) -> let minfos = minfos |> List.filter (fun minfo -> - staticOnly = (minfo.GetObjArgTypes(ncenv.amap, itemRange, minfo.FormalMethodInst) |> isNil)) + staticOnly = List.isEmpty (minfo.GetObjArgTypes(ncenv.amap, itemRange, minfo.FormalMethodInst))) Item.MethodGroup(nm, minfos, orig) | item -> item diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs index d82a11dc550..8813410143e 100755 --- a/src/fsharp/NicePrint.fs +++ b/src/fsharp/NicePrint.fs @@ -291,7 +291,7 @@ module private PrintIL = let layoutSetterType (setterRef:ILMethodRef) = let argTypes = setterRef.ArgTypes |> ILList.toList - if isNil argTypes then + if List.isEmpty argTypes then emptyL // shouldn't happen else let frontArgs, lastArg = List.frontAndBack argTypes @@ -1003,7 +1003,7 @@ module private PrintTypes = | _ -> let tpcsL = layoutConstraintsWithInfo denv env tpcs let coreL = sepListL (sepL ",") (List.map (layoutTyparRefWithInfo denv env) typars) - (if prefix || nonNil(tpcs) then nmL ^^ angleL (coreL --- tpcsL) else bracketL coreL --- nmL) + (if prefix || not (List.isEmpty tpcs) then nmL ^^ angleL (coreL --- tpcsL) else bracketL coreL --- nmL) let layoutTyparConstraint denv typars = @@ -1038,7 +1038,7 @@ module private PrintTypes = PrettyTypes.NewPrettyTypars memberToParentInst methTypars methTyparNames let retTy = instType allTyparInst retTy - let argInfos = argInfos |> List.map (fun infos -> if isNil infos then [(denv.g.unit_ty,ValReprInfo.unnamedTopArg1)] else infos |> List.map (map1Of2 (instType allTyparInst))) + let argInfos = argInfos |> List.map (fun infos -> if List.isEmpty infos then [(denv.g.unit_ty,ValReprInfo.unnamedTopArg1)] else infos |> List.map (map1Of2 (instType allTyparInst))) // Also format dummy types corresponding to any type variables on the container to make sure they // aren't chosen as names for displayed variables. @@ -1105,7 +1105,7 @@ module private PrintTastMemberOrVals = stat ++ newL ^^ wordL ":" ^^ tauL | MemberKind.PropertyGetSet -> stat | MemberKind.PropertyGet -> - if isNil argInfos then + if List.isEmpty argInfos then // use error recovery because intellisense on an incomplete file will show this errorR(Error(FSComp.SR.tastInvalidFormForPropertyGetter(),v.Id.idRange)); stat --- wordL v.PropertyName --- wordL "with get" @@ -1117,15 +1117,15 @@ module private PrintTastMemberOrVals = let niceMethodTypars,tauL = layoutMemberType denv v argInfos rty let nameL = mkNameL niceMethodTypars v.PropertyName - stat --- (nameL ^^ wordL ":" ^^ (if isNil argInfos then tauL else tauL --- wordL "with get")) + stat --- (nameL ^^ wordL ":" ^^ (if List.isEmpty argInfos then tauL else tauL --- wordL "with get")) | MemberKind.PropertySet -> - if argInfos.Length <> 1 || isNil argInfos.Head then + if argInfos.Length <> 1 || List.isEmpty argInfos.Head then // use error recovery because intellisense on an incomplete file will show this errorR(Error(FSComp.SR.tastInvalidFormForPropertySetter(),v.Id.idRange)); stat --- wordL v.PropertyName --- wordL "with set" else let argInfos,valueInfo = List.frontAndBack argInfos.Head - let niceMethodTypars,tauL = layoutMemberType denv v (if isNil argInfos then [] else [argInfos]) (fst valueInfo) + let niceMethodTypars,tauL = layoutMemberType denv v (if List.isEmpty argInfos then [] else [argInfos]) (fst valueInfo) let nameL = mkNameL niceMethodTypars v.PropertyName stat --- (nameL ^^ wordL ":" ^^ (tauL --- wordL "with set")) @@ -1606,7 +1606,7 @@ module private TastDefinitionPrinting = iimplsLs,adhocCtorsLs,adhocInstanceLs,adhocStaticLs let memberLs = memberImplementLs @ memberCtorLs @ memberInstanceLs @ memberStaticLs let addMembersAsWithEnd reprL = - if isNil memberLs then reprL + if List.isEmpty memberLs then reprL elif simplified then reprL @@ aboveListL memberLs else reprL @@ (wordL "with" @@-- aboveListL memberLs) @@ wordL "end" @@ -1619,7 +1619,7 @@ module private TastDefinitionPrinting = | TAsmRepr _ | TMeasureableRepr _ | TILObjectRepr _ -> - let brk = nonNil memberLs || breakTypeDefnEqn repr + let brk = not (List.isEmpty memberLs) || breakTypeDefnEqn repr let rhsL = let addReprAccessL l = layoutAccessibility denv tycon.TypeReprAccessibility l let denv = denv.AddAccessibility tycon.TypeReprAccessibility @@ -1655,7 +1655,7 @@ module private TastDefinitionPrinting = | _ -> [] let vsprs = tycon.MembersOfFSharpTyconSorted - |> List.filter (fun v -> isNil (Option.get v.MemberInfo).ImplementedSlotSigs) + |> List.filter (fun v -> List.isEmpty (Option.get v.MemberInfo).ImplementedSlotSigs) |> List.filter (fun v -> v.IsDispatchSlot) |> List.map (fun vref -> PrintTastMemberOrVals.layoutValOrMember denv vref.Deref) let staticValsLs = @@ -1671,7 +1671,7 @@ module private TastDefinitionPrinting = None else let alldecls = applyMaxMembers denv.maxMembers alldecls - let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> isNil alldecls | _ -> false + let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> List.isEmpty alldecls | _ -> false if emptyMeasure then None else let declsL = aboveListL alldecls let declsL = match start with Some s -> (wordL s @@-- declsL) @@ wordL "end" | None -> declsL @@ -1745,7 +1745,7 @@ module private InferredSigPrinting = let rec isConcreteNamespace x = match x with | TMDefRec(_,tycons,mbinds,_) -> - nonNil tycons || (mbinds |> List.exists (function ModuleOrNamespaceBinding.Binding _ -> true | ModuleOrNamespaceBinding.Module(x,_) -> not x.IsNamespace)) + not (List.isEmpty tycons) || (mbinds |> List.exists (function ModuleOrNamespaceBinding.Binding _ -> true | ModuleOrNamespaceBinding.Module(x,_) -> not x.IsNamespace)) | TMDefLet _ -> true | TMDefDo _ -> true | TMDefs defs -> defs |> List.exists isConcreteNamespace @@ -1758,7 +1758,7 @@ module private InferredSigPrinting = and imdefsL denv x = aboveListL (x |> List.map (imdefL denv)) and imdefL denv x = - let filterVal (v:Val) = not v.IsCompilerGenerated && isNone v.MemberInfo + let filterVal (v:Val) = not v.IsCompilerGenerated && Option.isNone v.MemberInfo let filterExtMem (v:Val) = v.IsExtensionMember match x with | TMDefRec(_,tycons,mbinds,_) -> @@ -1797,7 +1797,7 @@ module private InferredSigPrinting = if showHeader then // OK, we're not in F# Interactive // Check if this is an outer module with no namespace - if isNil outerPath then + if List.isEmpty outerPath then // If so print a "module" declaration (wordL "module" ^^ nmL) @@ basic else @@ -1836,7 +1836,7 @@ module private PrintData = elif denv.g.unionCaseRefEq c denv.g.cons_ucref then let rec strip = function (Expr.Op (TOp.UnionCase _,_,[h;t],_)) -> h::strip t | _ -> [] listL (dataExprL denv) (strip expr) - elif isNil(args) then + elif List.isEmpty args then wordL c.CaseName else (wordL c.CaseName ++ bracketL (commaListL (dataExprsL denv args))) diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 95634eec40f..9bb4ba0ecde 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -485,7 +485,7 @@ let BindInternalValsToUnknown cenv vs env = let BindTypeVar tyv typeinfo env = { env with typarInfos= (tyv,typeinfo)::env.typarInfos } let BindTypeVarsToUnknown (tps:Typar list) env = - if isNil tps then env else + if List.isEmpty tps then env else // The optimizer doesn't use the type values it could track. // However here we mutate to provide better names for generalized type parameters // The names chosen are 'a', 'b' etc. These are also the compiled names in the IL code @@ -933,36 +933,33 @@ let mkAssemblyCodeValueInfo g instrs argvals tys = let [] localVarSize = 1 -let rec AddTotalSizesAux acc l = match l with [] -> acc | h::t -> AddTotalSizesAux (h.TotalSize + acc) t -let AddTotalSizes l = AddTotalSizesAux 0 l +let inline AddTotalSizes l = l |> List.sumBy (fun x -> x.TotalSize) +let inline AddFunctionSizes l = l |> List.sumBy (fun x -> x.FunctionSize) -let rec AddFunctionSizesAux acc l = match l with [] -> acc | h::t -> AddFunctionSizesAux (h.FunctionSize + acc) t -let AddFunctionSizes l = AddFunctionSizesAux 0 l - -let AddTotalSizesFlat l = l |> FlatList.sumBy (fun x -> x.TotalSize) -let AddFunctionSizesFlat l = l |> FlatList.sumBy (fun x -> x.FunctionSize) +let inline AddTotalSizesFlat l = l |> FlatList.sumBy (fun x -> x.TotalSize) +let inline AddFunctionSizesFlat l = l |> FlatList.sumBy (fun x -> x.FunctionSize) //------------------------------------------------------------------------- // opt list/array combinators - zipping (_,_) return type //------------------------------------------------------------------------- -let rec OrEffects l = match l with [] -> false | h::t -> h.HasEffect || OrEffects t -let OrEffectsFlat l = FlatList.exists (fun x -> x.HasEffect) l +let inline OrEffects l = List.exists (fun x -> x.HasEffect) l +let inline OrEffectsFlat l = FlatList.exists (fun x -> x.HasEffect) l -let rec OrTailcalls l = match l with [] -> false | h::t -> h.MightMakeCriticalTailcall || OrTailcalls t -let OrTailcallsFlat l = FlatList.exists (fun x -> x.MightMakeCriticalTailcall) l +let inline OrTailcalls l = List.exists (fun x -> x.MightMakeCriticalTailcall) l +let inline OrTailcallsFlat l = FlatList.exists (fun x -> x.MightMakeCriticalTailcall) l let rec OptimizeListAux f l acc1 acc2 = match l with | [] -> List.rev acc1, List.rev acc2 | (h ::t) -> - let (x1,x2) = f h + let (x1,x2) = f h OptimizeListAux f t (x1::acc1) (x2::acc2) let OptimizeList f l = OptimizeListAux f l [] [] let OptimizeFlatList f l = l |> FlatList.map f |> FlatList.unzip -let NoExprs : (Expr list * list>)= [],[] +let NoExprs : (Expr list * list>) = [],[] let NoFlatExprs : (FlatExprs * FlatList>) = FlatList.empty, FlatList.empty //------------------------------------------------------------------------- @@ -1090,8 +1087,8 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue = match ivalue with // Check for escaping value. Revert to old info if possible | ValValue (VRefLocal v2,detail) when - (nonNil boundVars && List.exists (valEq v2) boundVars) || - (nonNil boundTyVars && + (not (List.isEmpty boundVars) && List.exists (valEq v2) boundVars) || + (not (List.isEmpty boundTyVars) && let ftyvs = freeInVal CollectTypars v2 List.exists (Zset.memberOf ftyvs.FreeTypars) boundTyVars) -> @@ -1104,9 +1101,9 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue = // Check for escape in lambda | CurriedLambdaValue (_,_,_,expr,_) | ConstExprValue(_,expr) when - (let fvs = freeInExpr (if isNil boundTyVars then CollectLocals else CollectTyparsAndLocals) expr - (nonNil boundVars && List.exists (Zset.memberOf fvs.FreeLocals) boundVars) || - (nonNil boundTyVars && List.exists (Zset.memberOf fvs.FreeTyvars.FreeTypars) boundTyVars) || + (let fvs = freeInExpr (if List.isEmpty boundTyVars then CollectLocals else CollectTyparsAndLocals) expr + (not (List.isEmpty boundVars) && List.exists (Zset.memberOf fvs.FreeLocals) boundVars) || + (not (List.isEmpty boundTyVars) && List.exists (Zset.memberOf fvs.FreeTyvars.FreeTypars) boundTyVars) || (fvs.UsesMethodLocalConstructs )) -> // Trimming lambda @@ -1114,7 +1111,7 @@ let AbstractExprInfoByVars (boundVars:Val list,boundTyVars) ivalue = // Check for escape in generic constant | ConstValue(_,ty) when - (nonNil boundTyVars && + (not (List.isEmpty boundTyVars) && (let ftyvs = freeInType CollectTypars ty List.exists (Zset.memberOf ftyvs.FreeTypars) boundTyVars)) -> UnknownValue @@ -1213,7 +1210,7 @@ let IsTyFuncValRefExpr = function let rec IsSmallConstExpr x = match x with | Expr.Val (v,_,_m) -> not v.IsMutable - | Expr.App(fe,_,_tyargs,args,_) -> isNil(args) && not (IsTyFuncValRefExpr fe) && IsSmallConstExpr fe + | Expr.App(fe,_,_tyargs,args,_) -> List.isEmpty args && not (IsTyFuncValRefExpr fe) && IsSmallConstExpr fe | _ -> false let ValueOfExpr expr = @@ -1228,7 +1225,7 @@ let ValueOfExpr expr = let ValueIsUsedOrHasEffect cenv fvs (b:Binding,binfo) = let v = b.Var not (cenv.settings.EliminateUnusedBindings()) || - isSome v.MemberInfo || + Option.isSome v.MemberInfo || binfo.HasEffect || v.IsFixed || Zset.contains v (fvs()) @@ -1601,7 +1598,7 @@ let rec tryRewriteToSeqCombinators g (e: Expr) = // match --> match | Expr.Match (spBind,exprm,pt,targets,m,_ty) -> let targets = targets |> Array.map (fun (TTarget(vs,e,spTarget)) -> match tryRewriteToSeqCombinators g e with None -> None | Some e -> Some(TTarget(vs,e,spTarget))) - if targets |> Array.forall isSome then + if targets |> Array.forall Option.isSome then let targets = targets |> Array.map Option.get let ty = targets |> Array.pick (fun (TTarget(_,e,_)) -> Some(tyOfExpr g e)) Some (Expr.Match (spBind,exprm,pt,targets,m,ty)) @@ -2289,7 +2286,7 @@ and CanDevirtualizeApplication cenv v vref ty args = && not (IsUnionTypeWithNullAsTrueValue cenv.g (fst(StripToNominalTyconRef cenv ty)).Deref) // If we de-virtualize an operation on structs then we have to take the address of the object argument // Hence we have to actually have the object argument available to us, - && (not (isStructTy cenv.g ty) || nonNil args) + && (not (isStructTy cenv.g ty) || not (List.isEmpty args)) and TakeAddressOfStructArgumentIfNeeded cenv (vref:ValRef) ty args m = if vref.IsInstanceMember && isStructTy cenv.g ty then @@ -2309,7 +2306,7 @@ and TakeAddressOfStructArgumentIfNeeded cenv (vref:ValRef) ty args m = and DevirtualizeApplication cenv env (vref:ValRef) ty tyargs args m = let wrap,args = TakeAddressOfStructArgumentIfNeeded cenv vref ty args m - let transformedExpr = wrap (MakeApplicationAndBetaReduce cenv.g (exprForValRef m vref,vref.Type,(if isNil tyargs then [] else [tyargs]),args,m)) + let transformedExpr = wrap (MakeApplicationAndBetaReduce cenv.g (exprForValRef m vref,vref.Type,(if List.isEmpty tyargs then [] else [tyargs]),args,m)) OptimizeExpr cenv env transformedExpr @@ -2502,7 +2499,7 @@ and TryDevirtualizeApplication cenv env (f,tyargs,args,m) = // Don't fiddle with 'methodhandleof' calls - just remake the application | Expr.Val(vref,_,_),_,_ when valRefEq cenv.g vref cenv.g.methodhandleof_vref -> - Some( MakeApplicationAndBetaReduce cenv.g (exprForValRef m vref,vref.Type,(if isNil tyargs then [] else [tyargs]),args,m), + Some( MakeApplicationAndBetaReduce cenv.g (exprForValRef m vref,vref.Type,(if List.isEmpty tyargs then [] else [tyargs]),args,m), { TotalSize=1 FunctionSize=1 HasEffect=false @@ -2516,7 +2513,6 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li // Considering inlining app match finfo.Info with | StripLambdaValue (lambdaId,arities,size,f2,f2ty) when - (// Considering inlining lambda cenv.optimizing && cenv.settings.InlineLambdas () && @@ -2524,7 +2520,7 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li // Don't inline recursively! not (Zset.contains lambdaId env.dontInline) && (// Check the number of argument groups is enough to saturate the lambdas of the target. - (if tyargs |> List.filter (fun t -> match t with TType_measure _ -> false | _ -> true) |> isNil then 0 else 1) + args.Length = arities && + (if tyargs |> List.exists (fun t -> match t with TType_measure _ -> false | _ -> true) then 1 else 0) + args.Length = arities && (// Enough args (if size > cenv.settings.lambdaInlineThreshold + args.Length then // Not inlining lambda near, size too big @@ -2599,7 +2595,7 @@ and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) = let shapes = match f0' with - | Expr.Val(vref,_,_) when isSome vref.ValReprInfo -> + | Expr.Val(vref,_,_) when Option.isSome vref.ValReprInfo -> let (ValReprInfo(_kinds,detupArgsL,_)) = Option.get vref.ValReprInfo let nargs = (args.Length) let nDetupArgsL = detupArgsL.Length @@ -2665,7 +2661,7 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety = match e with | Expr.Lambda (lambdaId,_,_,_,_,m,_) | Expr.TyLambda(lambdaId,_,_,m,_) -> - let isTopLevel = isSome vspec && vspec.Value.IsCompiledAsTopLevel + let isTopLevel = Option.isSome vspec && vspec.Value.IsCompiledAsTopLevel let tps,ctorThisValOpt,baseValOpt,vsl,body,bodyty = IteratedAdjustArityOfLambda cenv.g cenv.amap topValInfo e let env = { env with functionVal = (match vspec with None -> None | Some v -> Some (v,topValInfo)) } let env = Option.foldBack (BindInternalValToUnknown cenv) ctorThisValOpt env @@ -2676,7 +2672,7 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety = let body',bodyinfo = OptimizeExpr cenv env body let expr' = mkMemberLambdas m tps ctorThisValOpt baseValOpt vsl (body',bodyty) let arities = vsl.Length - let arities = if isNil tps then arities else 1+arities + let arities = if List.isEmpty tps then arities else 1+arities let bsize = bodyinfo.TotalSize /// Set the flag on the value indicating that direct calls can avoid a tailcall (which are expensive on .NET x86) @@ -2943,7 +2939,7 @@ and OptimizeBinding cenv isRec env (TBind(v,e,spBind)) = else env let repr',einfo = - let env = if v.IsCompilerGenerated && isSome env.latestBoundId then env else {env with latestBoundId=Some v.Id} + let env = if v.IsCompilerGenerated && Option.isSome env.latestBoundId then env else {env with latestBoundId=Some v.Id} let cenv = if v.InlineInfo = ValInline.PseudoVal then { cenv with optimizing=false} else cenv let e',einfo = OptimizeLambdas (Some v) cenv env (InferArityOfExprBinding cenv.g v e) e v.Type let size = localVarSize diff --git a/src/fsharp/PatternMatchCompilation.fs b/src/fsharp/PatternMatchCompilation.fs index 90e00637fb0..408fe031c2f 100644 --- a/src/fsharp/PatternMatchCompilation.fs +++ b/src/fsharp/PatternMatchCompilation.fs @@ -102,7 +102,7 @@ type SubExprOfInput = let BindSubExprOfInput g amap gtps (PBind(v,tyscheme)) m (SubExpr(accessf,(ve2,v2))) = let e' = - if isNil gtps then + if List.isEmpty gtps then accessf [] ve2 else let tyargs = @@ -126,7 +126,7 @@ let BindSubExprOfInput g amap gtps (PBind(v,tyscheme)) m (SubExpr(accessf,(ve2,v v,mkGenericBindRhs g m [] tyscheme e' let GetSubExprOfInput g (gtps,tyargs,tinst) (SubExpr(accessf,(ve2,v2))) = - if isNil gtps then accessf [] ve2 else + if List.isEmpty gtps then accessf [] ve2 else accessf tinst (mkApps g ((ve2,v2.Type),[tyargs],[],v2.Range)) //--------------------------------------------------------------------------- @@ -505,7 +505,7 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = // 'isinst' tests where we have stored the result of the 'isinst' in a variable // In this case the 'expr' already holds the result of the 'isinst' test. - | (TCase(Test.IsInst _,success)):: edges, dflt when isSome inpExprOpt -> + | (TCase(Test.IsInst _,success)):: edges, dflt when Option.isSome inpExprOpt -> TDSwitch(expr,[TCase(Test.IsNull,BuildSwitch None g expr edges dflt m)],Some success,m) // isnull and isinst tests @@ -519,7 +519,7 @@ let rec BuildSwitch inpExprOpt g expr edges dflt m = | [TCase(ListEmptyDiscrim g tinst, emptyCase)], Some consCase | [TCase(ListEmptyDiscrim g _, emptyCase); TCase(ListConsDiscrim g tinst, consCase)], None | [TCase(ListConsDiscrim g tinst, consCase); TCase(ListEmptyDiscrim g _, emptyCase)], None - when isSome inpExprOpt -> + when Option.isSome inpExprOpt -> TDSwitch(expr, [TCase(Test.IsNull, emptyCase)], Some consCase, m) #endif @@ -792,7 +792,7 @@ let CompilePatternBasic // For each case, recursively compile the residue decision trees that result if that case successfully matches let simulSetOfCases, _ = CompileSimultaneousSet frontiers path refuted subexpr simulSetOfEdgeDiscrims inpExprOpt - assert (nonNil(simulSetOfCases)) + assert (not (List.isEmpty simulSetOfCases)) // Work out what the default/fall-through tree looks like, is any // Check if match is complete, if so optimize the default case away. @@ -873,7 +873,7 @@ let CompilePatternBasic | EdgeDiscrim(_i',(Test.IsInst (_srcty,tgty)),m) :: _rest (* check we can use a simple 'isinst' instruction *) - when canUseTypeTestFast g tgty && isNil topgtvs -> + when canUseTypeTestFast g tgty && List.isEmpty topgtvs -> let v,vexp = mkCompGenLocal m "typeTestResult" tgty if topv.IsMemberOrModuleBinding then @@ -884,7 +884,7 @@ let CompilePatternBasic // Any match on a struct union must take the address of its input | EdgeDiscrim(_i',(Test.UnionCase (ucref, _)),_) :: _rest - when (isNil topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon) -> + when List.isEmpty topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon -> let argexp = GetSubExprOfInput subexpr let vOpt,addrexp = mkExprAddrOfExprAux g true false NeverMutates argexp None matchm @@ -903,7 +903,7 @@ let CompilePatternBasic | [EdgeDiscrim(_, ListConsDiscrim g tinst, m)] | [EdgeDiscrim(_, ListEmptyDiscrim g tinst, m)] (* check we can use a simple 'isinst' instruction *) - when isNil topgtvs -> + when List.isEmpty topgtvs -> let ucaseTy = (mkProvenUnionCaseTy g.cons_ucref tinst) let v,vexp = mkCompGenLocal m "unionTestResult" ucaseTy @@ -917,7 +917,7 @@ let CompilePatternBasic // Active pattern matches: create a variable to hold the results of executing the active pattern. | (EdgeDiscrim(_,(Test.ActivePatternCase(pexp,resTys,_,_,apinfo)),m) :: _) -> - if nonNil topgtvs then error(InternalError("Unexpected generalized type variables when compiling an active pattern",m)) + if not (List.isEmpty topgtvs) then error(InternalError("Unexpected generalized type variables when compiling an active pattern",m)) let rty = apinfo.ResultType g m resTys let v,vexp = mkCompGenLocal m "activePatternResult" rty if topv.IsMemberOrModuleBinding then @@ -954,7 +954,7 @@ let CompilePatternBasic #if OPTIMIZE_LIST_MATCHING isNone inpExprOpt && #endif - (isNil topgtvs && + (List.isEmpty topgtvs && not topv.IsMemberOrModuleBinding && not ucref.Tycon.IsStructRecordOrUnionTycon && ucref.UnionCase.RecdFields.Length >= 1 && diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 1bb13f613ad..9926771ffce 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -149,7 +149,7 @@ let BindTypar env (tp:Typar) = let BindTypars g env (tps:Typar list) = let tps = NormalizeDeclaredTyparsForEquiRecursiveInference g tps - if isNil tps then env else + if List.isEmpty tps then env else // Here we mutate to provide better names for generalized type parameters let nms = PrettyTypes.PrettyTyparNames (fun _ -> true) env.boundTyparNames tps (tps,nms) ||> List.iter2 (fun tp nm -> @@ -951,13 +951,13 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | Some membInfo -> testHookMemberBody membInfo body // Check escapes in the body. Allow access to protected things within members. - let freesOpt = CheckEscapes cenv (isSome memInfo) m syntacticArgs body + let freesOpt = CheckEscapes cenv (Option.isSome memInfo) m syntacticArgs body // no reraise under lambda expression CheckNoReraise cenv freesOpt body // Check the body of the lambda - if (nonNil tps || nonNil vsl) && isTop && not cenv.g.compilingFslib && isByrefTy cenv.g bodyty then + if (not (List.isEmpty tps) || not (List.isEmpty vsl)) && isTop && not cenv.g.compilingFslib && isByrefTy cenv.g bodyty then // allow byref to occur as return position for byref-typed top level function or method CheckExprPermitByrefReturn cenv env body else @@ -965,7 +965,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check byref return types if cenv.reportErrors then - if (not inlined && (isNil tps && isNil vsl)) || not isTop then + if (not inlined && (List.isEmpty tps && List.isEmpty vsl)) || not isTop then CheckForByrefLikeType cenv env bodyty (fun () -> errorR(Error(FSComp.SR.chkFirstClassFuncNoByref(), m))) @@ -1091,7 +1091,7 @@ and CheckAttribArgExpr cenv env expr = errorR (Error (FSComp.SR.chkInvalidCustAttrVal(), expr.Range)) and CheckAttribs cenv env (attribs: Attribs) = - if isNil attribs then () else + if List.isEmpty attribs then () else let tcrefs = [ for (Attrib(tcref,_,_,_,_,_,m)) in attribs -> (tcref,m) ] // Check for violations of allowMultiple = false @@ -1133,7 +1133,7 @@ and AdjustAccess isHidden (cpath: unit -> CompilationPath) access = access and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = - let isTop = isSome bind.Var.ValReprInfo + let isTop = Option.isSome bind.Var.ValReprInfo //printfn "visiting %s..." v.DisplayName // Check that active patterns don't have free type variables in their result @@ -1169,7 +1169,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = CheckForByrefLikeType cenv env v.Type (fun () -> errorR(Error(FSComp.SR.chkNoByrefAsTopValue(),v.Range))) | _ -> () - if isSome v.PublicPath then + if Option.isSome v.PublicPath then if // Don't support implicit [] on generated members, except the implicit members // for 'let' bound functions in classes. @@ -1206,7 +1206,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = let qscope = QuotationTranslator.QuotationGenerationScope.Create (cenv.g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.Yes) QuotationTranslator.ConvExprPublic qscope env taue |> ignore let _,_,argExprs = qscope.Close() - if nonNil argExprs then + if not (List.isEmpty argExprs) then errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), v.Range)) QuotationTranslator.ConvMethodBase qscope env (v.CompiledName, v) |> ignore with diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs index 1037acc09ea..fbae5b3746d 100644 --- a/src/fsharp/QuotationTranslator.fs +++ b/src/fsharp/QuotationTranslator.fs @@ -345,7 +345,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. // Simple applications | Expr.App(f,_fty,tyargs,args,m) -> - if nonNil tyargs then wfail(Error(FSComp.SR.crefQuotationsCantContainGenericExprs(), m)) + if not (List.isEmpty tyargs) then wfail(Error(FSComp.SR.crefQuotationsCantContainGenericExprs(), m)) List.fold (fun fR arg -> QP.mkApp (fR,ConvExpr cenv env arg)) (ConvExpr cenv env f) args // REVIEW: what is the quotation view of literals accessing enumerations? Currently they show up as integers. @@ -729,7 +729,7 @@ and private ConvValRefCore holeOk cenv env m (vref:ValRef) tyargs = let e = env.substVals.[v] ConvExpr cenv env e elif env.vs.ContainsVal v then - if nonNil tyargs then wfail(InternalError("ignoring generic application of local quoted variable",m)) + if not (List.isEmpty tyargs) then wfail(InternalError("ignoring generic application of local quoted variable",m)) QP.mkVar(env.vs.[v]) elif v.BaseOrThisInfo = CtorThisVal && cenv.isReflectedDefinition = IsReflectedDefinition.Yes then QP.mkThisVar(ConvType cenv env m v.Type) diff --git a/src/fsharp/SignatureConformance.fs b/src/fsharp/SignatureConformance.fs index 3d8a863faa5..55a573d1e9a 100644 --- a/src/fsharp/SignatureConformance.fs +++ b/src/fsharp/SignatureConformance.fs @@ -626,7 +626,7 @@ let rec CheckNamesOfModuleOrNamespaceContents denv (implModRef:ModuleOrNamespace let fx = fxs.Head errorR(RequiredButNotSpecified(denv,implModRef,"value",(fun os -> // In the case of missing members show the full required enclosing type and signature - if isSome fx.MemberInfo then + if Option.isSome fx.MemberInfo then NicePrint.outputQualifiedValOrMember denv os fx else Printf.bprintf os "%s" fx.DisplayName),m)); false) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 83a80cb4152..8e5ddb25045 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -954,7 +954,7 @@ let unionCaseRefOrder = let mkFunTy d r = TType_fun (d,r) let (-->) d r = mkFunTy d r let mkForallTy d r = TType_forall (d,r) -let tryMkForallTy d r = if isNil d then r else mkForallTy d r +let tryMkForallTy d r = if List.isEmpty d then r else mkForallTy d r let (+->) d r = tryMkForallTy d r let mkIteratedFunTy dl r = List.foldBack (-->) dl r @@ -1376,7 +1376,7 @@ let applyTys g functy (tyargs,argtys) = let formalApplyTys g functy (tyargs,args) = reduceIteratedFunTy g - (if isNil tyargs then functy else snd (destForallTy g functy)) + (if List.isEmpty tyargs then functy else snd (destForallTy g functy)) args let rec stripFunTyN g n ty = @@ -1411,7 +1411,7 @@ let GetTopTauTypeInFSharpForm g (curriedArgInfos: ArgReprInfo list list) tau m = argtysl,rty let destTopForallTy g (ValReprInfo (ntps,_,_)) ty = - let tps,tau = (if isNil ntps then [],ty else tryDestForallTy g ty) + let tps,tau = (if List.isEmpty ntps then [],ty else tryDestForallTy g ty) #if CHECKED if tps.Length <> kinds.Length then failwith (sprintf "destTopForallTy: internal error, #tps = %d, #ntps = %d" (List.length tps) ntps); #endif @@ -1426,7 +1426,7 @@ let GetTopValTypeInFSharpForm g (ValReprInfo(_,argInfos,retInfo) as topValInfo) let IsCompiledAsStaticProperty g (v:Val) = - (isSome v.ValReprInfo && + (Option.isSome v.ValReprInfo && match GetTopValTypeInFSharpForm g v.ValReprInfo.Value v.Type v.Range with | [],[], _,_ when not v.IsMember -> true | _ -> false) @@ -1650,7 +1650,7 @@ let actualReturnTyOfSlotSig parentTyInst methTyInst (TSlotSig(_,_,parentFormalTy Option.map (instType (parentTyInst @ methTyInst)) formalRetTy let slotSigHasVoidReturnTy (TSlotSig(_,_,_,_,_,formalRetTy)) = - isNone formalRetTy + Option.isNone formalRetTy let returnTyOfMethod g (TObjExprMethod((TSlotSig(_,parentTy,_,_,_,_) as ss),_,methFormalTypars,_,_,_)) = let tinst = argsOfAppTy g parentTy @@ -2547,7 +2547,7 @@ let trimPathByDisplayEnv denv path = else None match List.tryPick findOpenedNamespace (denv.openTopPathsSorted.Force()) with | Some s -> s - | None -> if isNil path then "" else textOfPath path + "." + | None -> if List.isEmpty path then "" else textOfPath path + "." let superOfTycon g (tycon:Tycon) = @@ -3163,14 +3163,14 @@ module DebugPrint = begin |> List.filter (fun v -> not v.IsDispatchSlot) |> List.filter (fun v -> not v.Deref.IsClassConstructor) // Don't print individual methods forming interface implementations - these are currently never exported - |> List.filter (fun v -> isNil (Option.get v.MemberInfo).ImplementedSlotSigs) + |> List.filter (fun v -> List.isEmpty (Option.get v.MemberInfo).ImplementedSlotSigs) let iimpls = match tycon.TypeReprInfo with | TFSharpObjectRepr r when (match r.fsobjmodel_kind with TTyconInterface -> true | _ -> false) -> [] | _ -> tycon.ImmediateInterfacesOfFSharpTycon let iimpls = iimpls |> List.filter (fun (_,compgen,_) -> not compgen) // if TTyconInterface, the iimpls should be printed as inheritted interfaces - if (isNil adhoc && isNil iimpls) + if List.isEmpty adhoc && List.isEmpty iimpls then emptyL else let iimplsLs = iimpls |> List.map (fun (ty,_,_) -> wordL "interface" --- typeL ty) @@ -3224,7 +3224,7 @@ module DebugPrint = begin |> List.map (fun vref -> vspecAtBindL vref.Deref) let vals = tycon.TrueFieldsAsList |> List.map (fun f -> (if f.IsStatic then wordL "static" else emptyL) ^^ wordL "val" ^^ layoutRecdField f) let alldecls = inherits @ vsprs @ vals - let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> isNil alldecls | _ -> false + let emptyMeasure = match tycon.TypeOrMeasureKind with TyparKind.Measure -> List.isEmpty alldecls | _ -> false if emptyMeasure then emptyL else (wordL start @@-- aboveListL alldecls) @@ wordL "end" | TUnionRepr _ -> tycon.UnionCasesAsList |> layoutUnionCases |> aboveListL | TAsmRepr _ -> wordL "(# ... #)" @@ -3934,7 +3934,7 @@ let accFreevarsInTyconCache = CheckCachability("accFreevarsInTycon", (fun opts let accFreeVarsInTy opts ty fvs = accFreeVarsInTy_cache.Apply(opts,ty,fvs) let accFreeVarsInTys opts tys fvs = - if isNil tys then fvs else accFreeVarsInTys_cache.Apply(opts,tys,fvs) + if List.isEmpty tys then fvs else accFreeVarsInTys_cache.Apply(opts,tys,fvs) let accFreevarsInTycon opts (tcr:TyconRef) acc = match tcr.IsLocalRef with | true -> accFreevarsInTyconCache.Apply(opts,tcr,acc) @@ -3943,7 +3943,7 @@ let accFreevarsInVal opts v fvs = accFreevarsInValCache.Apply(opts,v,fvs) #else let accFreeVarsInTy opts ty acc = accFreeTyvars opts accFreeInType ty acc -let accFreeVarsInTys opts tys acc = if isNil tys then acc else accFreeTyvars opts accFreeInTypes tys acc +let accFreeVarsInTys opts tys acc = if List.isEmpty tys then acc else accFreeTyvars opts accFreeInTypes tys acc let accFreevarsInTycon opts tcref acc = accFreeTyvars opts accFreeTycon tcref acc let accFreevarsInVal opts v acc = accFreeTyvars opts accFreeInVal v acc #endif @@ -4263,8 +4263,8 @@ let freeInModuleOrNamespace opts mdef = accFreeInModuleOrNamespace opts mdef emp let rec stripLambda (e,ty) = match e with | Expr.Lambda (_,ctorThisValOpt,baseValOpt,v,b,_,rty) -> - if isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", e.Range)); - if isSome baseValOpt then errorR(InternalError("skipping baseValOpt", e.Range)); + if Option.isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", e.Range)); + if Option.isSome baseValOpt then errorR(InternalError("skipping baseValOpt", e.Range)); let (vs',b',rty') = stripLambda (b,rty) (v :: vs', b', rty') | _ -> ([],e,ty) @@ -4273,8 +4273,8 @@ let rec stripLambdaN n e = assert (n >= 0) match e with | Expr.Lambda (_,ctorThisValOpt,baseValOpt,v,body,_,_) when n > 0 -> - if isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", e.Range)); - if isSome baseValOpt then errorR(InternalError("skipping baseValOpt", e.Range)); + if Option.isSome ctorThisValOpt then errorR(InternalError("skipping ctorThisValOpt", e.Range)); + if Option.isSome baseValOpt then errorR(InternalError("skipping baseValOpt", e.Range)); let (vs,body',remaining) = stripLambdaN (n-1) body (v :: vs, body', remaining) | _ -> ([],e,n) @@ -4815,7 +4815,7 @@ and remapTyconExnInfo g tmenv inp = and remapMemberInfo g m topValInfo ty ty' tmenv x = // The slotsig in the ImplementedSlotSigs is w.r.t. the type variables in the value's type. // REVIEW: this is a bit gross. It would be nice if the slotsig was standalone - assert (isSome topValInfo); + assert (Option.isSome topValInfo) let tpsOrig,_,_,_ = GetMemberTypeInFSharpForm g x.MemberFlags (Option.get topValInfo) ty m let tps,_,_,_ = GetMemberTypeInFSharpForm g x.MemberFlags (Option.get topValInfo) ty' m let renaming,_ = mkTyparToTyparRenaming tpsOrig tps @@ -5100,7 +5100,7 @@ let isExnFieldMutable ecref n = (recdFieldOfExnDefRefByIdx ecref n).IsMutable let useGenuineField (tycon:Tycon) (f:RecdField) = - isSome f.LiteralValue || tycon.IsEnumTycon || f.rfield_secret || (not f.IsStatic && f.rfield_mutable && not tycon.IsRecordTycon) + Option.isSome f.LiteralValue || tycon.IsEnumTycon || f.rfield_secret || (not f.IsStatic && f.rfield_mutable && not tycon.IsRecordTycon) let ComputeFieldName tycon f = if useGenuineField tycon f then f.rfield_id.idText @@ -5215,7 +5215,7 @@ let rec mkExprApplAux g f fty argsl m = match f with | Expr.App(f',fty',tyargs,pargs,m2) when - (isNil pargs || + (List.isEmpty pargs || (match stripExpr f' with | Expr.Val(v,_,_) -> match v.ValReprInfo with @@ -5298,7 +5298,7 @@ let rec decisionTreeHasNonTrivialBindings tree = edges |> List.exists (fun c -> decisionTreeHasNonTrivialBindings c.CaseTree) || dflt |> Option.exists decisionTreeHasNonTrivialBindings | TDSuccess _ -> false - | TDBind (_,t) -> isNone (targetOfSuccessDecisionTree t) + | TDBind (_,t) -> Option.isNone (targetOfSuccessDecisionTree t) // If a target has assignments and can only be reached through one // branch (i.e. is "linear"), then transfer the assignments to the r.h.s. to be a "let". @@ -5315,7 +5315,7 @@ let foldLinearBindingTargetsOfMatch tree (targets: _[]) = let rec accumulateTipsOfDecisionTree accBinds tree = match tree with | TDSwitch (_,edges,dflt,_) -> - assert (isNil accBinds) // No switches under bindings + assert (List.isEmpty accBinds) // No switches under bindings for edge in edges do accumulateTipsOfDecisionTree accBinds edge.CaseTree match dflt with | None -> () @@ -6173,7 +6173,7 @@ let mkThrow m ty e = mkAsmExpr ([ IL.I_throw ],[], [e],[ty],m) let destThrow = function | Expr.Op (TOp.ILAsm([IL.I_throw],[ty2]),[],[e],m) -> Some (m,ty2,e) | _ -> None -let isThrow x = isSome (destThrow x) +let isThrow x = Option.isSome (destThrow x) // rethrow - parsed as library call - internally represented as op form. let mkReraiseLibCall g ty m = let ve,vt = typedExprForIntrinsic g m g.reraise_info in Expr.App(ve,vt,[ty],[mkUnit g m],m) @@ -6691,7 +6691,7 @@ let AdjustPossibleSubsumptionExpr g (expr: Expr) (suppliedArgs: Expr list) : (Ex let exprForAllArgs = - if isNil argTysWithNiceNames then + if List.isEmpty argTysWithNiceNames then mkInvisibleLet appm cloVar exprWithActualTy exprForOtherArgs else let lambdaBuilders,binderBuilders,inpsAsArgs = @@ -6784,7 +6784,7 @@ let NormalizeAndAdjustPossibleSubsumptionExprs g inputExpr = // polymorphic things bound in complex matches at top level require eta expansion of the // type function to ensure the r.h.s. of the binding is indeed a type function let etaExpandTypeLambda g m tps (tm,ty) = - if isNil tps then tm else mkTypeLambda m tps (mkApps g ((tm,ty),[(List.map mkTyparTy tps)],[],m),ty) + if List.isEmpty tps then tm else mkTypeLambda m tps (mkApps g ((tm,ty),[(List.map mkTyparTy tps)],[],m),ty) let AdjustValToTopVal (tmp:Val) parent valData = tmp.SetValReprInfo (Some valData); @@ -6925,7 +6925,7 @@ and tyargsEnc g (gtpsType,gtpsMethod) args = | _ -> angleEnc (commaEncs (List.map (typeEnc g (gtpsType,gtpsMethod)) args)) let XmlDocArgsEnc g (gtpsType,gtpsMethod) argTs = - if isNil argTs then "" + if List.isEmpty argTs then "" else "(" + String.concat "," (List.map (typeEnc g (gtpsType,gtpsMethod)) argTs) + ")" let buildAccessPath (cp : CompilationPath option) = @@ -6967,7 +6967,7 @@ let XmlDocSigOfVal g path (v:Val) = let tps,argInfos,_,_ = GetTopValTypeInCompiledForm g w v.Type v.Range let name = v.CompiledName let prefix = - if w.NumCurriedArgs = 0 && isNil tps then "P:" + if w.NumCurriedArgs = 0 && List.isEmpty tps then "P:" else "M:" [],tps,argInfos,prefix,path,name let argTs = argInfos |> List.concat |> List.map fst @@ -7171,7 +7171,7 @@ let MemberIsCompiledAsInstance g parent isExtensionMember (membInfo:ValMemberInf if isExtensionMember then false // Anything implementing a dispatch slot is compiled as an instance member elif membInfo.MemberFlags.IsOverrideOrExplicitImpl then true - elif nonNil membInfo.ImplementedSlotSigs then true + elif not (List.isEmpty membInfo.ImplementedSlotSigs) then true else // Otherwise check attributes to see if there is an explicit instance or explicit static flag let explicitInstance,explicitStatic = diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index b6f149a8eb3..2243b552c9f 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -691,7 +691,7 @@ let mkTcGlobals (compilingFslib,sysCcu,ilg,fslibCcu,directoryToResolveRelativePa let makeIntrinsicValRef (enclosingEntity, logicalName, memberParentName, compiledNameOpt, typars, (argtys,rty)) = let ty = tryMkForallTy typars (mkIteratedFunTy (List.map mkSmallRefTupledTy argtys) rty) - let isMember = isSome memberParentName + let isMember = Option.isSome memberParentName let argCount = if isMember then List.sum (List.map List.length argtys) else 0 let linkageType = if isMember then Some ty else None let key = ValLinkageFullKey({ MemberParentMangledName=memberParentName; MemberIsOverride=false; LogicalName=logicalName; TotalArgCount= argCount },linkageType) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 5c0d9cb9e4c..45b9b098e92 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -646,7 +646,7 @@ let TryStripPrefixPath (g:TcGlobals) (enclosingNamespacePath: Ident list) = | _ -> None let ImplicitlyOpenOwnNamespace tcSink g amap scopem enclosingNamespacePath env = - if isNil enclosingNamespacePath then + if List.isEmpty enclosingNamespacePath then env else // For F# interactive, skip "FSI_0002" prefixes when determining the path to open implicitly @@ -939,10 +939,10 @@ let TranslateTopArgSynInfo isArg m tcAttributes (SynArgInfo(attrs,isOpt,nm)) = else [] - if isArg && nonNil attrs && isNone nm then + if isArg && not (List.isEmpty attrs) && Option.isNone nm then errorR(Error(FSComp.SR.tcParameterRequiresName(),m)) - if not isArg && isSome nm then + if not isArg && Option.isSome nm then errorR(Error(FSComp.SR.tcReturnValuesCannotHaveNames(),m)) // Call the attribute checking function @@ -998,7 +998,7 @@ let MakeMemberDataAndMangledNameForMemberVal(g,tcref,isExtrinsic,attrs,optImplSl // properly when we check the allImplemented implementation checks at the end of the inference scope. ImplementedSlotSigs=optImplSlotTys |> List.map (fun ity -> TSlotSig(logicalName,ity,[],[],[],None)) } let isInstance = MemberIsCompiledAsInstance g tcref isExtrinsic memberInfo attrs - if (memberFlags.IsDispatchSlot || nonNil optIntfSlotTys) then + if (memberFlags.IsDispatchSlot || not (List.isEmpty optIntfSlotTys)) then if not isInstance then errorR(VirtualAugmentationOnNullValuedType(id.idRange)) elif not memberFlags.IsOverrideOrExplicitImpl && memberFlags.IsInstance then @@ -1271,7 +1271,7 @@ let PublishValueDefnPrim cenv env (vspec:Val) = let PublishValueDefn cenv env declKind (vspec:Val) = if (declKind = ModuleOrMemberBinding) && ((GetCurrAccumulatedModuleOrNamespaceType env).ModuleOrNamespaceKind = Namespace) && - (isNone vspec.MemberInfo) then + (Option.isNone vspec.MemberInfo) then errorR(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(),vspec.Range)) if (declKind = ExtrinsicExtensionBinding) && @@ -1301,9 +1301,9 @@ let PublishValueDefn cenv env declKind (vspec:Val) = | _ -> () let CombineVisibilityAttribs vis1 vis2 m = - if isSome vis1 && isSome vis2 then + if Option.isSome vis1 && Option.isSome vis2 then errorR(Error(FSComp.SR.tcMultipleVisibilityAttributes(),m)) - if isSome vis1 then vis1 else vis2 + if Option.isSome vis1 then vis1 else vis2 let ComputeAccessAndCompPath env declKindOpt m vis actualParent = let accessPath = env.eAccessPath @@ -1312,7 +1312,7 @@ let ComputeAccessAndCompPath env declKindOpt m vis actualParent = | None -> true | Some declKind -> DeclKind.IsAccessModifierPermitted declKind - if isSome vis && not accessModPermitted then + if Option.isSome vis && not accessModPermitted then errorR(Error(FSComp.SR.tcMultipleVisibilityAttributesWithLet(),m)) let vis = match vis with @@ -1330,9 +1330,7 @@ let ComputeAccessAndCompPath env declKindOpt m vis actualParent = let cpath = (if accessModPermitted then Some cpath else None) vis,cpath -let CheckForAbnormalOperatorNames cenv (idRange:range) opName isMember = - - +let CheckForAbnormalOperatorNames cenv (idRange:range) opName isMember = if (idRange.EndColumn - idRange.StartColumn <= 5) && not cenv.g.compilingFslib then match opName, isMember with @@ -1392,12 +1390,12 @@ let MakeAndPublishVal cenv env (altActualParent,inSig,declKind,vrec,(ValScheme(i // CompiledName not allowed on virtual/abstract/override members let compiledNameAttrib = TryFindFSharpStringAttribute cenv.g cenv.g.attrib_CompiledNameAttribute attrs - if isSome compiledNameAttrib && ( ( match memberInfoOpt with - | Some (ValMemberInfoTransient(memberInfo,_,_)) -> - memberInfo.MemberFlags.IsDispatchSlot - || memberInfo.MemberFlags.IsOverrideOrExplicitImpl - | None -> false) - || (match altActualParent with ParentNone -> true | _ -> false)) then + if Option.isSome compiledNameAttrib && ( ( match memberInfoOpt with + | Some (ValMemberInfoTransient(memberInfo,_,_)) -> + memberInfo.MemberFlags.IsDispatchSlot + || memberInfo.MemberFlags.IsOverrideOrExplicitImpl + | None -> false) + || (match altActualParent with ParentNone -> true | _ -> false)) then errorR(Error(FSComp.SR.tcCompiledNameAttributeMisused(),m)) let compiledNameIsOnProp = @@ -1440,7 +1438,7 @@ let MakeAndPublishVal cenv env (altActualParent,inSig,declKind,vrec,(ValScheme(i (hasDeclaredTypars || inSig),isGeneratedEventVal,konst,actualParent) - CheckForAbnormalOperatorNames cenv id.idRange (DecompileOpName vspec.CoreDisplayName) (isSome memberInfoOpt) + CheckForAbnormalOperatorNames cenv id.idRange (DecompileOpName vspec.CoreDisplayName) (Option.isSome memberInfoOpt) PublishValueDefn cenv env declKind vspec @@ -1518,7 +1516,7 @@ let AdjustAndForgetUsesOfRecValue cenv (vrefTgt: ValRef) (valScheme : ValScheme) let (TypeScheme(generalizedTypars,_)) = valScheme.TypeScheme let fty = GeneralizedTypeForTypeScheme valScheme.TypeScheme let lvrefTgt = vrefTgt.Deref - if nonNil generalizedTypars then + if not (List.isEmpty generalizedTypars) then // Find all the uses of this recursive binding and use mutation to adjust the expressions // at those points in order to record the inferred type parameters. let recUses = cenv.recUses.Find lvrefTgt @@ -1636,7 +1634,7 @@ let GeneralizeVal cenv denv enclosingDeclaredTypars generalizedTyparsForThisBind List.forall2 typarEq generalizedTypars generalizedTyparsLookingThroughTypeAbbreviations) then warning(Error(FSComp.SR.tcTypeParametersInferredAreNotStable(),m)) - let hasDeclaredTypars = nonNil declaredTypars + let hasDeclaredTypars = not (List.isEmpty declaredTypars) // This is just about the only place we form a TypeScheme let tyScheme = TypeScheme(generalizedTypars, ty) PrelimValScheme2(id,tyScheme,partialValReprInfo,memberInfoOpt,isMutable,inlineFlag,baseOrThis,argAttribs,vis,compgen,hasDeclaredTypars) @@ -1832,7 +1830,7 @@ let FreshenTyconRef m rigid (tcref:TyconRef) declaredTyconTypars = let FreshenPossibleForallTy g m rigid ty = let tpsorig,tau = tryDestForallTy g ty - if isNil tpsorig then [],[],tau + if List.isEmpty tpsorig then [],[],tau else // tps may be have been equated to other tps in equi-recursive type inference and units-of-measure type inference. Normalize them here let tpsorig = NormalizeDeclaredTyparsForEquiRecursiveInference g tpsorig @@ -1856,8 +1854,8 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = match synTyparDecls with | SynValTyparDecls(synTypars,infer,_) -> - if nonNil synTypars && infer then errorR(Error(FSComp.SR.tcOverridingMethodRequiresAllOrNoTypeParameters(),m)) - isNil synTypars + if not (List.isEmpty synTypars) && infer then errorR(Error(FSComp.SR.tcOverridingMethodRequiresAllOrNoTypeParameters(),m)) + List.isEmpty synTypars let (CompiledSig (argtys,retTy,fmtps,_)) = CompiledSigOfMeth g amap m absMethInfo @@ -1880,7 +1878,7 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo = let BuildFieldMap cenv env isPartial ty flds m = let ad = env.eAccessRights - if isNil flds then invalidArg "flds" "BuildFieldMap" + if List.isEmpty flds then invalidArg "flds" "BuildFieldMap" let frefSets = let allFields = flds |> List.map (fun ((_,ident),_) -> ident) @@ -2058,7 +2056,7 @@ module GeneralizationHelpers = match ctorInfo with | RecdExpr -> not (isRecdOrUnionOrStructTyconRefAllocObservable g tcref) | RecdExprIsObjInit -> false - | TOp.Array -> isNil args + | TOp.Array -> List.isEmpty args | TOp.ExnConstr ec -> not (isExnAllocObservable ec) | TOp.ILAsm([],_) -> true @@ -2113,7 +2111,7 @@ module GeneralizationHelpers = genConstrainedTyparFlag = CanGeneralizeConstrainedTypars || tp.Constraints.IsEmpty) - if isNil ungeneralizableTypars1 && isNil ungeneralizableTypars2 && isNil ungeneralizableTypars3 then + if List.isEmpty ungeneralizableTypars1 && List.isEmpty ungeneralizableTypars2 && List.isEmpty ungeneralizableTypars3 then generalizedTypars, freeInEnv else let freeInEnv = @@ -2163,7 +2161,7 @@ module GeneralizationHelpers = // A condensation typar may not a user-generated type variable nor has it been unified with any user type variable (tp.DynamicReq = TyparDynamicReq.No) && // A condensation typar must have a single constraint "'a :> A" - (isSome (relevantUniqueSubtypeConstraint tp)) && + (Option.isSome (relevantUniqueSubtypeConstraint tp)) && // This is type variable is not used on the r.h.s. of the type not (ListSet.contains typarEq tp returnTypeFreeTypars) && // A condensation typar can't be used in the constraints of any candidate condensation typars @@ -2247,10 +2245,10 @@ module GeneralizationHelpers = match memberFlags.MemberKind with // can't infer extra polymorphism for properties | MemberKind.PropertyGet | MemberKind.PropertySet -> - if nonNil declaredTypars then + if not (List.isEmpty declaredTypars) then errorR(Error(FSComp.SR.tcPropertyRequiresExplicitTypeParameters(),m)) | MemberKind.Constructor -> - if nonNil declaredTypars then + if not (List.isEmpty declaredTypars) then errorR(Error(FSComp.SR.tcConstructorCannotHaveTypeParameters(),m)) | _ -> () @@ -2378,7 +2376,7 @@ module BindingNormalization = let private MakeNormalizedStaticOrValBinding cenv isObjExprBinding id vis typars args rhsExpr valSynData = let (SynValData(memberFlagsOpt,_,_)) = valSynData - NormalizedBindingPat(mkSynPatVar vis id, PushMultiplePatternsToRhs cenv ((isObjExprBinding = ObjExprBinding) || isSome memberFlagsOpt) args rhsExpr,valSynData,typars) + NormalizedBindingPat(mkSynPatVar vis id, PushMultiplePatternsToRhs cenv ((isObjExprBinding = ObjExprBinding) || Option.isSome memberFlagsOpt) args rhsExpr,valSynData,typars) let private MakeNormalizedInstanceMemberBinding cenv thisId memberId toolId vis m typars args rhsExpr valSynData = NormalizedBindingPat(SynPat.InstanceMember(thisId,memberId,toolId,vis,m), PushMultiplePatternsToRhs cenv true args rhsExpr,valSynData,typars) @@ -2612,7 +2610,7 @@ let FreshenObjectArgType cenv m rigid tcref isExtrinsic declaredTyconTypars = // scope of "A". let TcValEarlyGeneralizationConsistencyCheck cenv (env:TcEnv) (v:Val, vrec, tinst, vty, tau, m) = match vrec with - | ValInRecScope isComplete when isComplete && nonNil tinst -> + | ValInRecScope isComplete when isComplete && not (List.isEmpty tinst) -> //printfn "pushing post-inference check for '%s', vty = '%s'" v.DisplayName (DebugPrint.showType vty) cenv.postInferenceChecks.Add (fun () -> //printfn "running post-inference check for '%s'" v.DisplayName @@ -2620,7 +2618,7 @@ let TcValEarlyGeneralizationConsistencyCheck cenv (env:TcEnv) (v:Val, vrec, tins //printfn "vty = '%s'" (DebugPrint.showType vty) let tpsorig,tau2 = tryDestForallTy cenv.g vty //printfn "tau2 = '%s'" (DebugPrint.showType tau2) - if nonNil tpsorig then + if not (List.isEmpty tpsorig) then let tpsorig = NormalizeDeclaredTyparsForEquiRecursiveInference cenv.g tpsorig let tau3 = instType (mkTyparInst tpsorig tinst) tau2 //printfn "tau3 = '%s'" (DebugPrint.showType tau3) @@ -2784,7 +2782,7 @@ type ApplicableExpr = let combinedExpr = match fe with | Expr.App(e1,e1ty,tyargs1,args1,e1m) when - (not first || isNil args1) && + (not first || List.isEmpty args1) && (not (isForallTy cenv.g e1ty) || isFunTy cenv.g (applyTys cenv.g e1ty (tyargs1,args1))) -> Expr.App(e1,e1ty,tyargs1,args1@[e2],unionRanges e1m m) | _ -> @@ -3081,7 +3079,7 @@ let TryGetNamedArg e = | SimpleEqualsExpr(LongOrSingleIdent(isOpt,LongIdentWithDots([a],_),None,_),b) -> Some(isOpt,a,b) | _ -> None -let IsNamedArg e = isSome (TryGetNamedArg e) +let inline IsNamedArg e = Option.isSome (TryGetNamedArg e) /// Get the method arguments at a callsite, taking into account named and optional arguments let GetMethodArgs arg = @@ -4656,10 +4654,10 @@ and CrackStaticConstantArgs cenv env tpenv (staticParameters: Tainted List.map (function | SynType.StaticConstantNamed(SynType.LongIdent(LongIdentWithDots([id],_)),v,_) -> (Some id, v) | v -> (None, v)) - let unnamedArgs = args |> Seq.takeWhile (fst >> isNone) |> Seq.toArray |> Array.map snd - let otherArgs = args |> List.skipWhile (fst >> isNone) - let namedArgs = otherArgs |> List.takeWhile (fst >> isSome) |> List.map (map1Of2 Option.get) - let otherArgs = otherArgs |> List.skipWhile (fst >> isSome) + let unnamedArgs = args |> Seq.takeWhile (fst >> Option.isNone) |> Seq.toArray |> Array.map snd + let otherArgs = args |> List.skipWhile (fst >> Option.isNone) + let namedArgs = otherArgs |> List.takeWhile (fst >> Option.isSome) |> List.map (map1Of2 Option.get) + let otherArgs = otherArgs |> List.skipWhile (fst >> Option.isSome) if not otherArgs.IsEmpty then error (Error(FSComp.SR.etBadUnnamedStaticArgs(),m)) for (n,_) in namedArgs do @@ -4923,7 +4921,7 @@ and TcSimplePatsOfUnknownType cenv optArgsOK checkCxs env tpenv spats = TcSimplePats cenv optArgsOK checkCxs argty env (tpenv,NameMap.empty,Set.empty) spats and TcPatBindingName cenv env id ty isMemberThis vis1 topValData (inlineFlag,declaredTypars,argAttribs,isMutable,vis2,compgen) (names,takenNames:Set) = - let vis = if isSome vis1 then vis1 else vis2 + let vis = if Option.isSome vis1 then vis1 else vis2 if takenNames.Contains id.idText then errorR (VarBoundTwice id) let baseOrThis = if isMemberThis then MemberThisVal else NormalVal let names = Map.add id.idText (PrelimValScheme1(id,declaredTypars,ty,topValData,None,isMutable,inlineFlag,baseOrThis,argAttribs,vis,compgen)) names @@ -5037,7 +5035,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv,names,takenNames) ty pat (fun values -> TPat_conjs(List.map (fun f -> f values) pats',m)), acc | SynPat.LongIdent (LongIdentWithDots(longId,_),_,tyargs,args,vis,m) -> - if isSome tyargs then errorR(Error(FSComp.SR.tcInvalidTypeArgumentUsage(),m)) + if Option.isSome tyargs then errorR(Error(FSComp.SR.tcInvalidTypeArgumentUsage(),m)) let warnOnUpperForId = match args with | SynConstructorArgs.Pats [] -> warnOnUpper @@ -5058,7 +5056,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv,names,takenNames) ty pat | _ -> error (UndefinedName(0,FSComp.SR.undefinedNamePatternDiscriminator,id,NoPredictions)) | Item.ActivePatternCase(APElemRef(apinfo,vref,idx)) as item -> - let args = match args with SynConstructorArgs.Pats args -> args | _ -> failwith "impossible" + let args = match args with SynConstructorArgs.Pats args -> args | _ -> error(Error(FSComp.SR.tcNamedActivePattern(apinfo.ActiveTags.[idx]),m)) // TOTAL/PARTIAL ACTIVE PATTERNS let vexp, _, _, tinst, _ = TcVal true cenv env tpenv vref None m let vexp = MakeApplicableExprWithFlex cenv env vexp @@ -5077,7 +5075,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv,names,takenNames) ty pat else List.frontAndBack args - if nonNil activePatArgsAsSynPats && apinfo.ActiveTags.Length <> 1 then + if not (List.isEmpty activePatArgsAsSynPats) && apinfo.ActiveTags.Length <> 1 then error(Error(FSComp.SR.tcRequireActivePatternWithOneResult(),m)) // Parse the arguments to an active pattern @@ -5118,7 +5116,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv,names,takenNames) ty pat // The identity of an active pattern consists of its value and the types it is applied to. // If there are any expression args then we've lost identity. - let activePatIdentity = (if nonNil activePatArgsAsSynExprs then None else Some (vref, tinst)) + let activePatIdentity = if List.isEmpty activePatArgsAsSynExprs then Some (vref, tinst) else None (fun values -> // Report information about the 'active recognizer' occurence to IDE CallNameResolutionSink cenv.tcSink (rangeOfLid longId,env.NameEnv,item,item,ItemOccurence.Pattern,env.DisplayEnv,env.eAccessRights) @@ -5162,7 +5160,7 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv,names,takenNames) ty pat | _ -> error(Error(FSComp.SR.tcUnionCaseFieldCannotBeUsedMoreThanOnce(id.idText), id.idRange)) for i = 0 to nargtys - 1 do - if box result.[i] = null then + if isNull (box result.[i]) then result.[i] <- SynPat.Wild(m.MakeSynthetic()) let args = List.ofArray result @@ -5780,7 +5778,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = | SynExpr.IfThenElse (e1,e2,e3opt,spIfToThen,isRecovery,mIfToThen,m) -> let e1',tpenv = TcExprThatCantBeCtorBody cenv cenv.g.bool_ty env tpenv e1 let e2',tpenv = - if not isRecovery && isNone e3opt then + if not isRecovery && Option.isNone e3opt then let env = { env with eContextInfo = ContextInfo.OmittedElseBranch } UnifyTypes cenv env m cenv.g.unit_ty overallTy TcExprThatCanBeCtorBody cenv overallTy env tpenv e2 @@ -5848,7 +5846,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) = let returnTy = GetFSharpViewOfReturnType cenv.g returnTy let args,namedCallerArgs = GetMethodArgs arg - if nonNil namedCallerArgs then errorR(Error(FSComp.SR.tcNamedArgumentsCannotBeUsedInMemberTraits(),m)) + if not (List.isEmpty namedCallerArgs) then errorR(Error(FSComp.SR.tcNamedArgumentsCannotBeUsedInMemberTraits(),m)) // Subsumption at trait calls if arguments have nominal type prior to unification of any arguments or return type let flexes = argtys |> List.map (isTyparTy cenv.g >> not) let args',tpenv = TcExprs cenv env m tpenv flexes argtys args @@ -6023,8 +6021,7 @@ and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv wholeExpr e1 indexArg match attemptArrayString with | Some res -> res | None -> - if (isNominal || isSome propName) then - + if isNominal || Option.isSome propName then let nm = match propName with | None -> "Item" @@ -6173,7 +6170,7 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m = let ns1 = NameSet.ofList (List.map fst fldsList) let ns2 = NameSet.ofList (List.map (fun x -> x.rfield_id.idText) fspecs) - if isNone optOrigExpr && not (Zset.subset ns2 ns1) then + if Option.isNone optOrigExpr && not (Zset.subset ns2 ns1) then error (MissingFields(Zset.elements (Zset.diff ns2 ns1),m)) if not (Zset.subset ns1 ns2) then @@ -6450,10 +6447,10 @@ and TcObjectExpr cenv overallTy env tpenv (synObjTy,argopt,binds,extraImpls,mNew if // record construction ? (isRecdTy cenv.g objTy) || // object construction? - (isFSharpObjModelTy cenv.g objTy && not (isInterfaceTy cenv.g objTy) && isNone argopt) then + (isFSharpObjModelTy cenv.g objTy && not (isInterfaceTy cenv.g objTy) && Option.isNone argopt) then - if isSome argopt then error(Error(FSComp.SR.tcNoArgumentsForRecordValue(),mWholeExpr)) - if nonNil extraImpls then error(Error(FSComp.SR.tcNoInterfaceImplementationForConstructionExpression(),mNewExpr)) + if Option.isSome argopt then error(Error(FSComp.SR.tcNoArgumentsForRecordValue(),mWholeExpr)) + if not (List.isEmpty extraImpls) then error(Error(FSComp.SR.tcNoInterfaceImplementationForConstructionExpression(),mNewExpr)) if isFSharpObjModelTy cenv.g objTy && GetCtorShapeCounter env <> 1 then error(Error(FSComp.SR.tcObjectConstructionCanOnlyBeUsedInClassTypes(),mNewExpr)) let fldsList = @@ -6479,7 +6476,7 @@ and TcObjectExpr cenv overallTy env tpenv (synObjTy,argopt,binds,extraImpls,mNew errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(),m)) (m,intfTy,overrides),tpenv) - let realObjTy = (if isObjTy cenv.g objTy && nonNil extraImpls then (p23 (List.head extraImpls)) else objTy) + let realObjTy = if isObjTy cenv.g objTy && not (List.isEmpty extraImpls) then (p23 (List.head extraImpls)) else objTy UnifyTypes cenv env mWholeExpr overallTy realObjTy let ctorCall,baseIdOpt,tpenv = @@ -6629,7 +6626,7 @@ and TcConstExpr cenv overallTy env m tpenv c = with _ -> SynExpr.App(ExprAtomicFlag.Atomic, false, mkSynLidGet m [modName] "FromString",SynExpr.Const(SynConst.String (s,m),m),m) let ccu = ccuOfTyconRef mref - if isSome ccu && ccuEq ccu.Value cenv.g.fslibCcu && suffix = "I" then + if Option.isSome ccu && ccuEq ccu.Value cenv.g.fslibCcu && suffix = "I" then SynExpr.Typed(expr,SynType.LongIdent(LongIdentWithDots(pathToSynLid m ["System";"Numerics";"BigInteger"],[])),m) else expr @@ -6663,7 +6660,7 @@ and TcAssertExpr cenv overallTy env (m:range) tpenv x = and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr) = let requiresCtor = (GetCtorShapeCounter env = 1) // Get special expression forms for constructors - let haveCtor = (isSome inherits) + let haveCtor = Option.isSome inherits let optOrigExpr,tpenv = match optOrigExpr with @@ -6691,12 +6688,12 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr match flds with | [] -> [] | _ -> - let tcref,_,fldsList = BuildFieldMap cenv env (isSome optOrigExpr) overallTy flds mWholeExpr + let tcref,_,fldsList = BuildFieldMap cenv env (Option.isSome optOrigExpr) overallTy flds mWholeExpr let _,_,_,gtyp = infoOfTyconRef mWholeExpr tcref UnifyTypes cenv env mWholeExpr overallTy gtyp fldsList - if isSome optOrigExpr && not (isRecdTy cenv.g overallTy) then + if Option.isSome optOrigExpr && not (isRecdTy cenv.g overallTy) then errorR(Error(FSComp.SR.tcExpressionFormRequiresRecordTypes(),mWholeExpr)) if requiresCtor || haveCtor then @@ -6706,9 +6703,9 @@ and TcRecdExpr cenv overallTy env tpenv (inherits, optOrigExpr, flds, mWholeExpr if not requiresCtor then errorR(Error(FSComp.SR.tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes(),mWholeExpr)) else - if isNil flds then + if List.isEmpty flds then let errorInfo = - if isSome optOrigExpr then FSComp.SR.tcEmptyCopyAndUpdateRecordInvalid() + if Option.isSome optOrigExpr then FSComp.SR.tcEmptyCopyAndUpdateRecordInvalid() else FSComp.SR.tcEmptyRecordInvalid() error(Error(errorInfo,mWholeExpr)) @@ -6985,9 +6982,9 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv | _ -> None /// Decide if the identifier represents a use of a custom query operator - let hasCustomOperations () = not (isNil customOperationMethods) + let hasCustomOperations () = not (List.isEmpty customOperationMethods) - let isCustomOperation nm = tryGetDataForCustomOperation nm |> isSome + let isCustomOperation nm = tryGetDataForCustomOperation nm |> Option.isSome // Check for the MaintainsVariableSpace on custom operation let customOperationMaintainsVarSpace (nm:Ident) = @@ -7213,7 +7210,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv (let _firstSourceSimplePats,later1 = use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat - isNone later1) + Option.isNone later1) -> Some (isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore, innerComp) @@ -7371,8 +7368,8 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let firstSourceSimplePats,later1 = SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat let secondSourceSimplePats,later2 = SimplePatsOfPat cenv.synArgNameGenerator secondSourcePat - if isSome later1 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), firstSourcePat.Range)) - if isSome later2 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondSourcePat.Range)) + if Option.isSome later1 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), firstSourcePat.Range)) + if Option.isSome later2 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondSourcePat.Range)) // check 'join' or 'groupJoin' or 'zip' is permitted for this builder match tryGetDataForCustomOperation nm with @@ -7422,7 +7419,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv // groupJoin | Some secondResultPat, Some relExpr when customOperationIsLikeGroupJoin nm -> let secondResultSimplePats,later3 = SimplePatsOfPat cenv.synArgNameGenerator secondResultPat - if isSome later3 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondResultPat.Range)) + if Option.isSome later3 then errorR (Error (FSComp.SR.tcJoinMustUseSimplePattern(nm.idText), secondResultPat.Range)) match relExpr with | JoinRelation cenv env (keySelector1, keySelector2) -> mkJoinExpr keySelector1 keySelector2 secondResultSimplePats, varSpaceWithGroupJoinVars @@ -7488,7 +7485,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let mFor = match spForLoop with SequencePointAtForLoop(m) -> m | _ -> pat.Range let mPat = pat.Range let spBind = match spForLoop with SequencePointAtForLoop(m) -> SequencePointAtBinding(m) | NoSequencePointAtForLoop -> NoSequencePointAtStickyBinding - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mFor ad "For" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("For"),mFor)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mFor ad "For" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("For"),mFor)) // Add the variables to the query variable space, on demand let varSpace = @@ -7508,23 +7505,23 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let mGuard = guardExpr.Range let mWhile = match spWhile with SequencePointAtWhileLoop(m) -> m | _ -> mGuard if isQuery then error(Error(FSComp.SR.tcNoWhileInQuery(),mWhile)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mWhile ad "While" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("While"),mWhile)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mWhile ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),mWhile)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mWhile ad "While" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("While"),mWhile)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mWhile ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),mWhile)) Some(trans true q varSpace innerComp (fun holeFill -> translatedCtxt (mkSynCall "While" mWhile [mkSynDelay2 guardExpr; mkSynCall "Delay" mWhile [mkSynDelay innerComp.Range holeFill]])) ) | SynExpr.TryFinally (innerComp,unwindExpr,mTryToLast,spTry,_spFinally) -> let mTry = match spTry with SequencePointAtTry(m) -> m | _ -> mTryToLast if isQuery then error(Error(FSComp.SR.tcNoTryFinallyInQuery(),mTry)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "TryFinally" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("TryFinally"),mTry)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),mTry)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "TryFinally" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("TryFinally"),mTry)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),mTry)) Some (translatedCtxt (mkSynCall "TryFinally" mTry [mkSynCall "Delay" mTry [mkSynDelay innerComp.Range (transNoQueryOps innerComp)]; mkSynDelay2 unwindExpr])) | SynExpr.Paren (_,_,_,m) -> error(Error(FSComp.SR.tcConstructIsAmbiguousInComputationExpression(),m)) | SynExpr.ImplicitZero m -> - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"),m)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"),m)) Some (translatedCtxt (mkSynCall "Zero" m [])) | OptionalSequential (JoinOrGroupJoinOrZipClause (_, _, _, _, _, mClause), _) @@ -7681,8 +7678,8 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv | SynExpr.ForEach (SequencePointAtForLoop mBind,_,_,_,_,_,_) -> mBind | SynExpr.While (SequencePointAtWhileLoop mWhile,_,_,_) -> mWhile | _ -> innerComp1.Range - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Combine" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Combine"),m)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),m)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Combine" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Combine"),m)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),m)) Some (translatedCtxt (mkSynCall "Combine" m1 [c; mkSynCall "Delay" m1 [mkSynDelay innerComp2.Range (transNoQueryOps innerComp2)]])) | None -> // "do! expr; cexpr" is treated as { let! () = expr in cexpr } @@ -7705,7 +7702,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv Some (translatedCtxt (SynExpr.IfThenElse(guardExpr, transNoQueryOps thenComp, Some(transNoQueryOps elseComp), spIfToThen,isRecovery,mIfToThen,mIfToEndOfElseBranch))) | None -> let elseComp = - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mIfToThen ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"),mIfToThen)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mIfToThen ad "Zero" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Zero"),mIfToThen)) mkSynCall "Zero" mIfToThen [] Some (trans true q varSpace thenComp (fun holeFill -> translatedCtxt (SynExpr.IfThenElse(guardExpr, holeFill, Some elseComp, spIfToThen,isRecovery,mIfToThen,mIfToEndOfElseBranch)))) @@ -7746,7 +7743,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv if isQuery then error(Error(FSComp.SR.tcUseMayNotBeUsedInQueries(),bindRange)) let innerCompRange = innerComp.Range let consumeExpr = SynExpr.MatchLambda(false,innerCompRange,[Clause(pat,None, transNoQueryOps innerComp,innerCompRange,SequencePointAtTarget)],spBind,innerCompRange) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Using" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Using"),bindRange)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Using" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Using"),bindRange)) Some (translatedCtxt (mkSynCall "Using" bindRange [rhsExpr; consumeExpr ])) // 'let! pat = expr in expr' --> build.Bind(e1,(function _argN -> match _argN with pat -> expr)) @@ -7755,7 +7752,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let bindRange = match spBind with SequencePointAtBinding(m) -> m | _ -> rhsExpr.Range if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(),bindRange)) let innerRange = innerComp.Range - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"),bindRange)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"),bindRange)) // Add the variables to the query variable space, on demand let varSpace = @@ -7775,8 +7772,8 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let bindRange = match spBind with SequencePointAtBinding(m) -> m | _ -> rhsExpr.Range if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(),bindRange)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Using" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Using"),bindRange)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"),bindRange)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Using" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Using"),bindRange)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env bindRange ad "Bind" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Bind"),bindRange)) let consumeExpr = SynExpr.MatchLambda(false,bindRange,[Clause(pat,None, transNoQueryOps innerComp, innerComp.Range, SequencePointAtTarget)],spBind,bindRange) let consumeExpr = mkSynCall "Using" bindRange [SynExpr.Ident(id); consumeExpr ] let consumeExpr = SynExpr.MatchLambda(false,bindRange,[Clause(pat,None, consumeExpr,id.idRange,SequencePointAtTarget)],spBind,bindRange) @@ -7799,19 +7796,19 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv if isQuery then error(Error(FSComp.SR.tcTryWithMayNotBeUsedInQueries(),mTry)) let clauses = clauses |> List.map (fun (Clause(pat,cond,clauseComp,patm,sp)) -> Clause(pat,cond,transNoQueryOps clauseComp,patm,sp)) let consumeExpr = SynExpr.MatchLambda(true,mTryToLast,clauses,NoSequencePointAtStickyBinding,mTryToLast) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "TryWith" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("TryWith"),mTry)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),mTry)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "TryWith" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("TryWith"),mTry)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env mTry ad "Delay" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("Delay"),mTry)) Some(translatedCtxt (mkSynCall "TryWith" mTry [mkSynCall "Delay" mTry [mkSynDelay2 (transNoQueryOps innerComp)]; consumeExpr])) | SynExpr.YieldOrReturnFrom((isYield,_),yieldExpr,m) -> let yieldExpr = mkSourceExpr yieldExpr if isYield then - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "YieldFrom" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("YieldFrom"),m)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "YieldFrom" builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod("YieldFrom"),m)) Some (translatedCtxt (mkSynCall "YieldFrom" m [yieldExpr])) else if isQuery then error(Error(FSComp.SR.tcReturnMayNotBeUsedInQueries(),m)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "ReturnFrom" builderTy) then + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "ReturnFrom" builderTy) then errorR(Error(FSComp.SR.tcRequireBuilderMethod("ReturnFrom"),m)) Some (translatedCtxt yieldExpr) else @@ -7821,7 +7818,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv | SynExpr.YieldOrReturn((isYield,_),yieldExpr,m) -> let methName = (if isYield then "Yield" else "Return") if isQuery && not isYield then error(Error(FSComp.SR.tcReturnMayNotBeUsedInQueries(),m)) - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad methName builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod(methName),m)) + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad methName builderTy) then error(Error(FSComp.SR.tcRequireBuilderMethod(methName),m)) Some(translatedCtxt (mkSynCall methName m [yieldExpr])) | _ -> None @@ -7839,7 +7836,7 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let rhsExpr = mkSourceExpr rhsExpr if isQuery then error(Error(FSComp.SR.tcBindMayNotBeUsedInQueries(),m)) let bodyExpr = - if isNil (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Return" builderTy) then + if List.isEmpty (TryFindIntrinsicOrExtensionMethInfo cenv env m ad "Return" builderTy) then SynExpr.ImplicitZero m else SynExpr.YieldOrReturn((false,true), SynExpr.Const(SynConst.Unit, m), m) @@ -8091,7 +8088,7 @@ and PropagateThenTcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFla match delayedList with | [] -> // Avoid unifying twice: we're about to unify in TcDelayed - if nonNil delayed then + if not (List.isEmpty delayed) then UnifyTypes cenv env mExpr overallTy exprty | DelayedDot :: _ | DelayedSet _ :: _ @@ -8264,12 +8261,10 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution match delayed with // This is where the constructor is applied to an argument | ((DelayedApp (atomicFlag, (FittedArgs args as origArg), mExprAndArg))::otherDelayed) -> - // assert the overall result type if possible - if isNil otherDelayed then + if List.isEmpty otherDelayed then UnifyTypes cenv env mExprAndArg overallTy ucaseAppTy - let nargs = List.length args UnionCaseOrExnCheck env nargtys nargs mExprAndArg @@ -8299,7 +8294,7 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution for (_, id, arg) in namedCallerArgs do match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with | Some i -> - if box fittedArgs.[i] = null then + if isNull(box fittedArgs.[i]) then fittedArgs.[i] <- arg let argContainerOpt = match item with | Item.UnionCase(uci,_) -> Some(ArgumentContainer.UnionCase(uci)) @@ -8325,7 +8320,7 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution | _ -> false if isSpecialCaseForBackwardCompatibility then - assert (box fittedArgs.[currentIndex] = null) + assert (isNull(box fittedArgs.[currentIndex])) fittedArgs.[currentIndex] <- List.item currentIndex args // grab original argument, not item from the list of named parametere currentIndex <- currentIndex + 1 else @@ -8552,7 +8547,7 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution match delayed with // Mutable value set: 'v <- e' | DelayedSet(e2,mStmt) :: otherDelayed -> - if nonNil otherDelayed then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) + if not (List.isEmpty otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty vref.Deref.SetHasBeenReferenced() CheckValAccessible mItem env.eAccessRights vref @@ -8598,7 +8593,7 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution PropagateThenTcDelayed cenv overallTy env tpenv mItem vexp vexpty ExprAtomicFlag.Atomic delayed | Item.Property (nm,pinfos) -> - if isNil pinfos then error (InternalError ("Unexpected error: empty property list",mItem)) + if List.isEmpty pinfos then error (InternalError ("Unexpected error: empty property list",mItem)) // if there are both intrinsics and extensions in pinfos, intrinsics will be listed first. // by looking at List.Head we are letting the intrinsics determine indexed/non-indexed let pinfo = List.head pinfos @@ -8610,11 +8605,11 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution match delayed with | DelayedSet(e2,mStmt) :: otherDelayed -> let args = if pinfo.IsIndexer then args else [] - if nonNil otherDelayed then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) + if not (List.isEmpty otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) // Static Property Set (possibly indexer) UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty let meths = pinfos |> SettersOfPropInfos - if isNil meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm,mItem)) + if List.isEmpty meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm,mItem)) let afterTcOverloadResolution = afterOverloadResolution |> AfterTcOverloadResolution.ForProperties nm SettersOfPropInfos // Note: static calls never mutate a struct object argument TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mStmt mItem nm ad NeverMutates true meths afterTcOverloadResolution NormalValUse (args@[e2]) ExprAtomicFlag.NonAtomic otherDelayed @@ -8622,7 +8617,7 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution // Static Property Get (possibly indexer) let meths = pinfos |> GettersOfPropInfos let afterTcOverloadResolution = afterOverloadResolution |> AfterTcOverloadResolution.ForProperties nm GettersOfPropInfos - if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable(nm),mItem)) + if List.isEmpty meths then error (Error (FSComp.SR.tcPropertyIsNotReadable(nm),mItem)) // Note: static calls never mutate a struct object argument TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mItem mItem nm ad NeverMutates true meths afterTcOverloadResolution NormalValUse args ExprAtomicFlag.Atomic delayed @@ -8668,7 +8663,7 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution let fieldTy = rfinfo.FieldType match delayed with | DelayedSet(e2,mStmt) :: otherDelayed -> - if nonNil otherDelayed then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) + if not (List.isEmpty otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) // Set static F# field CheckRecdFieldMutation mItem env.DisplayEnv rfinfo @@ -8678,7 +8673,6 @@ and TcItemThen cenv overallTy env tpenv (item,mItem,rest,afterOverloadResolution let e2',tpenv = TcExprFlex cenv true fieldTy env tpenv e2 let expr = mkStaticRecdFieldSet (rfinfo.RecdFieldRef,rfinfo.TypeInst,e2',mStmt) expr,tpenv - | _ -> let exprty = fieldTy let expr = @@ -8776,7 +8770,7 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela | Item.Property (nm,pinfos) -> // Instance property - if isNil pinfos then error (InternalError ("Unexpected error: empty property list",mItem)) + if List.isEmpty pinfos then error (InternalError ("Unexpected error: empty property list",mItem)) // if there are both intrinsics and extensions in pinfos, intrinsics will be listed first. // by looking at List.Head we are letting the intrinsics determine indexed/non-indexed let pinfo = List.head pinfos @@ -8790,18 +8784,18 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela match delayed with | DelayedSet(e2,mStmt) :: otherDelayed -> let args = if pinfo.IsIndexer then args else [] - if nonNil otherDelayed then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) + if not (List.isEmpty otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(),mStmt)) // Instance property setter UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty let meths = SettersOfPropInfos pinfos - if isNil meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm,mItem)) + if List.isEmpty meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm,mItem)) let afterTcOverloadResolution = afterOverloadResolution |> AfterTcOverloadResolution.ForProperties nm SettersOfPropInfos let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mStmt mItem nm ad mut true meths afterTcOverloadResolution NormalValUse (args @ [e2]) atomicFlag [] | _ -> // Instance property getter let meths = GettersOfPropInfos pinfos - if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable(nm),mItem)) + if List.isEmpty meths then error (Error (FSComp.SR.tcPropertyIsNotReadable(nm),mItem)) let afterTcOverloadResolution = afterOverloadResolution |> AfterTcOverloadResolution.ForProperties nm GettersOfPropInfos TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterTcOverloadResolution NormalValUse args atomicFlag delayed @@ -8816,7 +8810,7 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela match delayed with | DelayedSet(e2,mStmt) :: otherDelayed -> // Mutable value set: 'v <- e' - if nonNil otherDelayed then error(Error(FSComp.SR.tcInvalidAssignment(),mItem)) + if not (List.isEmpty otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(),mItem)) CheckRecdFieldMutation mItem env.DisplayEnv rfinfo UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty // Always allow subsumption on assignment to fields @@ -8931,14 +8925,14 @@ and TcMethodApplicationThen // Work out if we know anything about the return type of the overall expression. If there are any delayed // lookups then we don't know anything. - let exprTy = if isNil delayed then overallTy else NewInferenceType () + let exprTy = if List.isEmpty delayed then overallTy else NewInferenceType () // Call the helper below to do the real checking let (expr,attributeAssignedNamedItems,delayed),tpenv = TcMethodApplication false cenv env tpenv callerTyArgs objArgs mWholeExpr mItem methodName objTyOpt ad mut isProp meths afterTcOverloadResolution isSuperInit args exprTy delayed // Give errors if some things couldn't be assigned - if nonNil attributeAssignedNamedItems then + if not (List.isEmpty attributeAssignedNamedItems) then let (CallerNamedArg(id,_)) = List.head attributeAssignedNamedItems errorR(Error(FSComp.SR.tcNamedArgumentDidNotMatch(id.idText),id.idRange)) @@ -9044,7 +9038,7 @@ and TcMethodApplication // x.M ((x,y)) match candidates with | [calledMeth] - when (namedCurriedCallerArgs |> List.forall isNil && + when (namedCurriedCallerArgs |> List.forall List.isEmpty && let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) curriedCalledArgs.Length = 1 && curriedCalledArgs.Head.Length = 1 && @@ -9061,7 +9055,7 @@ and TcMethodApplication // Without this rule this requires // x.M (fst p,snd p) | [calledMeth] - when (namedCurriedCallerArgs |> List.forall isNil && + when (namedCurriedCallerArgs |> List.forall List.isEmpty && unnamedCurriedCallerArgs.Length = 1 && unnamedCurriedCallerArgs.Head.Length = 1 && let curriedCalledArgs = calledMeth.GetParamAttribs(cenv.amap, mItem) @@ -9106,7 +9100,7 @@ and TcMethodApplication resultTy) curriedArgTys,returnTy - if isProp && isNone curriedCallerArgsOpt then + if isProp && Option.isNone curriedCallerArgsOpt then error(Error(FSComp.SR.parsIndexerPropertyRequiresAtLeastOneArgument(),mItem)) // STEP 1. UnifyUniqueOverloading. This happens BEFORE we type check the arguments. @@ -9323,7 +9317,7 @@ and TcMethodApplication finalCalledPropInfoOpt |> Option.iter (fun pinfo -> CheckPropInfoAttributes pinfo mItem |> CommitOperationResult) - let isInstance = nonNil objArgs + let isInstance = not (List.isEmpty objArgs) MethInfoChecks cenv.g cenv.amap isInstance tyargsOpt objArgs ad mItem finalCalledMethInfo // Adhoc constraints on use of .NET methods @@ -9612,7 +9606,7 @@ and TcMethodApplication // Bind "out" parameters as part of the result tuple let expr,exprty = - if isNil outArgTmpBinds then expr,exprty + if List.isEmpty outArgTmpBinds then expr,exprty else let outArgTys = outArgExprs |> List.map (tyOfExpr cenv.g) let expr = if isUnitTy cenv.g exprty then mkCompGenSequential mMethExpr expr (mkRefTupled cenv.g mMethExpr outArgExprs outArgTys) @@ -9622,7 +9616,7 @@ and TcMethodApplication // Handle post-hoc property assignments let expr = - if isNil finalAssignedItemSetters then expr else + if List.isEmpty finalAssignedItemSetters then expr else // This holds the result of the call let objv,objExpr = mkMutableCompGenLocal mMethExpr "returnVal" exprty // mutable in case it's a struct // This expression mutates the properties on the result of the call @@ -9992,7 +9986,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt // Check the attributes of the binding, parameters or return value let TcAttrs tgt attrs = let attrs = TcAttributes cenv envinner tgt attrs - if attrTgt = enum 0 && nonNil attrs then + if attrTgt = enum 0 && not (List.isEmpty attrs) then errorR(Error(FSComp.SR.tcAttributesAreNotPermittedOnLetBindings(),mBinding)) attrs @@ -10032,25 +10026,25 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt if not declKind.CanBeDllImport || (match memberFlagsOpt with Some memberFlags -> memberFlags.IsInstance | _ -> false) then errorR(Error(FSComp.SR.tcDllImportNotAllowed(),mBinding)) - if HasFSharpAttribute cenv.g cenv.g.attrib_ConditionalAttribute valAttribs && isNone(memberFlagsOpt) then + if HasFSharpAttribute cenv.g cenv.g.attrib_ConditionalAttribute valAttribs && Option.isNone memberFlagsOpt then errorR(Error(FSComp.SR.tcConditionalAttributeRequiresMembers(),mBinding)) if HasFSharpAttribute cenv.g cenv.g.attrib_EntryPointAttribute valAttribs then - if isSome(memberFlagsOpt) then + if Option.isSome memberFlagsOpt then errorR(Error(FSComp.SR.tcEntryPointAttributeRequiresFunctionInModule(),mBinding)) else UnifyTypes cenv env mBinding overallPatTy (mkArrayType cenv.g cenv.g.string_ty --> cenv.g.int_ty) if isMutable && isInline then errorR(Error(FSComp.SR.tcMutableValuesCannotBeInline(),mBinding)) - if isMutable && nonNil declaredTypars then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(),mBinding)) + if isMutable && not (List.isEmpty declaredTypars) then errorR(Error(FSComp.SR.tcMutableValuesMayNotHaveGenericParameters(),mBinding)) let flex = if isMutable then dontInferTypars else flex - if isMutable && nonNil spatsL then errorR(Error(FSComp.SR.tcMutableValuesSyntax(),mBinding)) + if isMutable && not (List.isEmpty spatsL) then errorR(Error(FSComp.SR.tcMutableValuesSyntax(),mBinding)) let isInline = - if isInline && isNil spatsL && isNil declaredTypars then + if isInline && List.isEmpty spatsL && List.isEmpty declaredTypars then errorR(Error(FSComp.SR.tcOnlyFunctionsCanBeInline(),mBinding)) false else @@ -10079,7 +10073,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt let envinner = match apinfoOpt with | Some (apinfo,ty,m) -> - if isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then + if Option.isSome memberFlagsOpt || (not apinfo.IsTotal && apinfo.ActiveTags.Length > 1) then error(Error(FSComp.SR.tcInvalidActivePatternName(),mBinding)) apinfo.ActiveTagsWithRanges |> List.iteri (fun i (_tag,tagRange) -> @@ -10132,7 +10126,7 @@ and TcNormalizedBinding declKind (cenv:cenv) env tpenv overallTy safeThisValOpt errorR(Error(FSComp.SR.tcLiteralCannotBeMutable(),mBinding)) if hasLiteralAttr && isInline then errorR(Error(FSComp.SR.tcLiteralCannotBeInline(),mBinding)) - if hasLiteralAttr && nonNil declaredTypars then + if hasLiteralAttr && not (List.isEmpty declaredTypars) then errorR(Error(FSComp.SR.tcLiteralCannotHaveGenericParameters(),mBinding)) CheckedBindingInfo(inlineFlag,valAttribs,doc,tcPatPhase2,flex,nameToPrelimValSchemeMap,rhsExprChecked,argAndRetAttribs,overallPatTy,mBinding,spBind,compgen,konst,isFixed),tpenv @@ -10408,7 +10402,7 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope let maxInferredTypars = freeInTypeLeftToRight cenv.g false tauTy let generalizedTypars = - if isNil maxInferredTypars && isNil allDeclaredTypars then + if List.isEmpty maxInferredTypars && List.isEmpty allDeclaredTypars then [] else let freeInEnv = lazyFreeInEnv.Force() @@ -10432,10 +10426,9 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (binds,bindsm,scope match pat' with // Don't introduce temporary or 'let' for 'match against wild' or 'match against unit' - | (TPat_wild _ | TPat_const (Const.Unit,_)) when not isUse && not isFixed && isNil generalizedTypars -> + | (TPat_wild _ | TPat_const (Const.Unit,_)) when not isUse && not isFixed && List.isEmpty generalizedTypars -> let mk_seq_bind (tm,tmty) = (mkSequential SequencePointsAtSeq m rhsExpr tm, tmty) (mk_seq_bind << mkf_sofar,env,tpenv) - | _ -> // nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to @@ -10511,7 +10504,7 @@ and CheckMemberFlags _g optIntfSlotTy newslotsOK overridesOK memberFlags m = errorR(Error(FSComp.SR.tcAbstractMembersIllegalInAugmentation(),m)) if overridesOK = ErrorOnOverrides && memberFlags.MemberKind = MemberKind.Constructor then errorR(Error(FSComp.SR.tcConstructorsIllegalInAugmentation(),m)) - if overridesOK = WarnOnOverrides && memberFlags.IsOverrideOrExplicitImpl && isNone optIntfSlotTy then + if overridesOK = WarnOnOverrides && memberFlags.IsOverrideOrExplicitImpl && Option.isNone optIntfSlotTy then warning(OverrideInIntrinsicAugmentation(m)) if overridesOK = ErrorOnOverrides && memberFlags.IsOverrideOrExplicitImpl then error(Error(FSComp.SR.tcMethodOverridesIllegalHere(),m)) @@ -10660,7 +10653,7 @@ and ApplyAbstractSlotInference cenv (envinner:TcEnv) (bindingTy,m,synTyparDecls, let _,typarsFromAbsSlot,argTysFromAbsSlot, retTyFromAbsSlot = FreshenAbstractSlot cenv.g cenv.amap m synTyparDecls uniqueAbstractMeth - if nonNil typarsFromAbsSlot then + if not (List.isEmpty typarsFromAbsSlot) then errorR(InternalError("Unexpected generic property",memberId.idRange)) let absSlotTy = @@ -10717,7 +10710,7 @@ and AnalyzeRecursiveStaticMemberOrValDecl (cenv, envinner: TcEnv, tpenv, declKin match tcrefContainerInfo, memberFlagsOpt with | (Some(MemberOrValContainerInfo(tcref, optIntfSlotTy, baseValOpt, _safeInitInfo, declaredTyconTypars)),Some memberFlags) -> - assert (isNone(optIntfSlotTy)) + assert (Option.isNone optIntfSlotTy) CheckMemberFlags cenv.g None newslotsOK overridesOK memberFlags id.idRange CheckForNonAbstractInterface declKind tcref memberFlags id.idRange @@ -10784,10 +10777,9 @@ and AnalyzeRecursiveInstanceMemberDecl (cenv,envinner: TcEnv, tpenv, declKind, s CheckMemberFlags cenv.g optIntfSlotTy newslotsOK overridesOK memberFlags mBinding - if isSome vis && memberFlags.IsOverrideOrExplicitImpl then + if Option.isSome vis && memberFlags.IsOverrideOrExplicitImpl then errorR(Error(FSComp.SR.tcOverridesCannotHaveVisibilityDeclarations(),memberId.idRange)) - - + // Syntactically push the "this" variable across to be a lambda on the right let bindingRhs = PushOnePatternToRhs cenv true (mkSynThisPatVar thisId) bindingRhs @@ -10910,8 +10902,7 @@ and AnalyzeAndMakeAndPublishRecursiveValue overridesOK isGeneratedEventVal cenv newslotsOK, overridesOK, vis1, declPattern, bindingAttribs, tcrefContainerInfo, memberFlagsOpt, ty, bindingRhs, mBinding) - - let optArgsOK = isSome(memberFlagsOpt) + let optArgsOK = Option.isSome memberFlagsOpt // Assert the types given in the argument patterns ApplyTypesFromArgumentPatterns(cenv,envinner,optArgsOK,ty,mBinding,tpenv,bindingRhs,memberFlagsOpt) @@ -11866,7 +11857,7 @@ module IncrClassChecking = // Create the values with the given names let _,vspecs = MakeSimpleVals cenv env names - if tcref.IsStructOrEnumTycon && isNil spats then + if tcref.IsStructOrEnumTycon && List.isEmpty spats then errorR (ParameterlessStructCtor(tcref.Range)) // Put them in order @@ -12499,8 +12490,8 @@ module IncrClassChecking = TransTrueDec true reps (IncrClassBindingGroup(binds,false,false)) // We expect that only ctorInitActions1 will be non-empty here, and even then only if some elements are stored in the field - assert (isNil cctorInitActions1) - assert (isNil methodBinds1) + assert (List.isEmpty cctorInitActions1) + assert (List.isEmpty methodBinds1) // Now deal with all the 'let' and 'member' declarations let initActions,reps = List.mapFold TransDec reps decs @@ -12754,7 +12745,7 @@ module MutRecBindingChecking = // Code for potential future design change to allow functions-compiled-as-members in structs errorR(Error(FSComp.SR.tcStructsMayNotContainLetBindings(),(trimRangeToLine m))) - if isStatic && isNone incrClassCtorLhsOpt then + if isStatic && Option.isNone incrClassCtorLhsOpt then errorR(Error(FSComp.SR.tcStaticLetBindingsRequireClassesWithImplicitConstructors(),m)) // Phase2A: let-bindings - pass through @@ -13372,7 +13363,7 @@ module MutRecBindingChecking = | _ -> () ]) // Now check they don't escape the overall scope of the recursive set of types - if nonNil allExtraGeneralizableTypars then + if not (List.isEmpty allExtraGeneralizableTypars) then let freeInInitialEnv = GeneralizationHelpers.ComputeUngeneralizableTypars envInitial for extraTypar in allExtraGeneralizableTypars do if Zset.memberOf freeInInitialEnv extraTypar then @@ -13458,11 +13449,11 @@ let TcMutRecDefns_Phase2 cenv envInitial bindsm scopem mutRecNSInfo (envMutRec: if not (tcref.HasInterface cenv.g ity') then error(Error(FSComp.SR.tcAllImplementedInterfacesShouldBeDeclared(),ity.Range)) - if (typeEquiv cenv.g ity' cenv.g.mk_IComparable_ty && isSome tcref.GeneratedCompareToValues) || - (typeEquiv cenv.g ity' cenv.g.mk_IStructuralComparable_ty && isSome tcref.GeneratedCompareToWithComparerValues) || - (typeEquiv cenv.g ity' ((mkAppTy cenv.g.system_GenericIComparable_tcref [typ])) && isSome tcref.GeneratedCompareToValues) || - (typeEquiv cenv.g ity' ((mkAppTy cenv.g.system_GenericIEquatable_tcref [typ])) && isSome tcref.GeneratedHashAndEqualsWithComparerValues) || - (typeEquiv cenv.g ity' cenv.g.mk_IStructuralEquatable_ty && isSome tcref.GeneratedHashAndEqualsWithComparerValues) then + if (typeEquiv cenv.g ity' cenv.g.mk_IComparable_ty && Option.isSome tcref.GeneratedCompareToValues) || + (typeEquiv cenv.g ity' cenv.g.mk_IStructuralComparable_ty && Option.isSome tcref.GeneratedCompareToWithComparerValues) || + (typeEquiv cenv.g ity' ((mkAppTy cenv.g.system_GenericIComparable_tcref [typ])) && Option.isSome tcref.GeneratedCompareToValues) || + (typeEquiv cenv.g ity' ((mkAppTy cenv.g.system_GenericIEquatable_tcref [typ])) && Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues) || + (typeEquiv cenv.g ity' cenv.g.mk_IStructuralEquatable_ty && Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues) then errorR(Error(FSComp.SR.tcDefaultImplementationForInterfaceHasAlreadyBeenAdded(),ity.Range)) if overridesOK = WarnOnOverrides then warning(IntfImplInIntrinsicAugmentation(ity.Range)) @@ -13608,19 +13599,19 @@ module AddAugmentationDeclarations = let AddGenericCompareBindings cenv (tycon:Tycon) = - if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) isSome tycon.GeneratedCompareToValues then + if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) Option.isSome tycon.GeneratedCompareToValues then AugmentWithHashCompare.MakeBindingsForCompareAugmentation cenv.g tycon else [] let AddGenericCompareWithComparerBindings cenv (tycon:Tycon) = - if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) isSome tycon.GeneratedCompareToWithComparerValues then + if (* AugmentWithHashCompare.TyconIsCandidateForAugmentationWithCompare cenv.g tycon && *) Option.isSome tycon.GeneratedCompareToWithComparerValues then (AugmentWithHashCompare.MakeBindingsForCompareWithComparerAugmentation cenv.g tycon) else [] let AddGenericEqualityWithComparerBindings cenv (tycon:Tycon) = - if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon && isSome tycon.GeneratedHashAndEqualsWithComparerValues then + if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon && Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues then (AugmentWithHashCompare.MakeBindingsForEqualityWithComparerAugmentation cenv.g tycon) else [] @@ -13653,7 +13644,7 @@ module AddAugmentationDeclarations = // Note: only provide the equals method if Equals is not implemented explicitly, and // we're actually generating Hash/Equals for this type if not hasExplicitObjectEqualsOverride && - isSome tycon.GeneratedHashAndEqualsWithComparerValues then + Option.isSome tycon.GeneratedHashAndEqualsWithComparerValues then let vspec1,vspec2 = AugmentWithHashCompare.MakeValsForEqualsAugmentation cenv.g tcref tcaug.SetEquals (mkLocalValRef vspec1, mkLocalValRef vspec2) @@ -13850,7 +13841,7 @@ module TyconConstraintInference = (if initialAssumedTycons.Contains tcref.Stamp then assumedTycons.Contains tcref.Stamp elif AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals g tcref.Deref then - isSome tcref.GeneratedHashAndEqualsWithComparerValues + Option.isSome tcref.GeneratedHashAndEqualsWithComparerValues else true) && @@ -14099,8 +14090,8 @@ module EstablishTypeDefinitionCores = if hasClassAttr || hasAbstractClassAttr || hasMeasureAttr then TyconClass elif hasInterfaceAttr then TyconInterface elif hasStructAttr then TyconStruct - elif isConcrete || nonNil fields then TyconClass - elif isNil slotsigs && inSig then TyconHiddenRepr + elif isConcrete || not (List.isEmpty fields) then TyconClass + elif List.isEmpty slotsigs && inSig then TyconHiddenRepr else TyconInterface | k -> if hasClassAttr && not (match k with TyconClass -> true | _ -> false) || @@ -14116,7 +14107,7 @@ module EstablishTypeDefinitionCores = | SynTypeDefnSimpleRepr.TypeAbbrev(_, SynType.LongIdent(LongIdentWithDots([unionCaseName],_)),m) when (not hasMeasureAttr && - (isNil (LookupTypeNameInEnvNoArity OpenQualified unionCaseName.idText envinner.eNameResEnv) || + (List.isEmpty (LookupTypeNameInEnvNoArity OpenQualified unionCaseName.idText envinner.eNameResEnv) || id.idText = unionCaseName.idText)) -> Some(unionCaseName,m) | _ -> @@ -14162,7 +14153,7 @@ module EstablishTypeDefinitionCores = for arg in ctorArgNames do let ty = names.[arg].Type let m = names.[arg].Ident.idRange - if nonNil (ListSet.subtract typarEq (freeInTypeLeftToRight cenv.g false ty) tycon.TyparsNoRange) then + if not (List.isEmpty (ListSet.subtract typarEq (freeInTypeLeftToRight cenv.g false ty) tycon.TyparsNoRange)) then errorR(Error(FSComp.SR.tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly(),m)) yield (ty, m) @@ -14287,7 +14278,7 @@ module EstablishTypeDefinitionCores = if hasMeasureAttr then tycon.Data.entity_kind <- TyparKind.Measure - if nonNil typars then error(Error(FSComp.SR.tcMeasureDefinitionsCannotHaveTypeParameters(),m)) + if not (List.isEmpty typars) then error(Error(FSComp.SR.tcMeasureDefinitionsCannotHaveTypeParameters(),m)) let repr = match synTyconRepr with @@ -14404,9 +14395,8 @@ module EstablishTypeDefinitionCores = let tcref = mkLocalTyconRef tycon try - let resolutionEnvironment = - - if nonNil args then + let resolutionEnvironment = + if not (List.isEmpty args) then checkTypeName() let resolutionEnvironment = match tcrefForContainer.TypeReprInfo with @@ -14950,7 +14940,7 @@ module EstablishTypeDefinitionCores = noSealedAttributeCheck FSComp.SR.tcTypesAreAlwaysSealedStruct noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() - if nonNil slotsigs then + if not (List.isEmpty slotsigs) then errorR (Error(FSComp.SR.tcStructTypesCannotContainAbstractMembers(),m)) structLayoutAttributeCheck(true) @@ -15683,7 +15673,7 @@ module TcDeclarations = let isConcrete = members |> List.exists (function | SynMemberDefn.Member(Binding(_,_,_,_,_,_,SynValData(Some memberFlags,_,_),_,_,_,_,_),_) -> not memberFlags.IsDispatchSlot - | SynMemberDefn.Interface (_,defOpt,_) -> isSome defOpt + | SynMemberDefn.Interface (_,defOpt,_) -> Option.isSome defOpt | SynMemberDefn.LetBindings _ -> true | SynMemberDefn.ImplicitCtor _ -> true | SynMemberDefn.ImplicitInherit _ -> true @@ -15711,7 +15701,7 @@ module TcDeclarations = members |> List.exists (function | SynMemberDefn.Member(Binding(_,_,_,_,_,_,SynValData(Some memberFlags,_,_),SynPatForConstructorDecl(SynPatForNullaryArgs),_,_,_,_),_) -> memberFlags.MemberKind=MemberKind.Constructor - | SynMemberDefn.ImplicitCtor (_,_,spats,_, _) -> isNil spats + | SynMemberDefn.ImplicitCtor (_,_,spats,_, _) -> List.isEmpty spats | _ -> false) let repr = SynTypeDefnSimpleRepr.General(kind,inherits,slotsigs,fields,isConcrete,isIncrClass,implicitCtorSynPats,m) let isAtOriginalTyconDefn = not (isAugmentationTyconDefnRepr repr) @@ -15754,7 +15744,7 @@ module TcDeclarations = let (ComponentInfo(_,typars, cs,longPath, _, _, _,_)) = synTyconInfo let declKind, tcref, declaredTyconTypars = ComputeTyconDeclKind tyconOpt isAtOriginalTyconDefn cenv envForDecls false tyDeclRange typars cs longPath let newslotsOK = (if isAtOriginalTyconDefn && tcref.IsFSharpObjectModelTycon then NewSlotsOK else NoNewSlots) - if nonNil members && tcref.IsTypeAbbrev then + if not (List.isEmpty members) && tcref.IsTypeAbbrev then errorR(Error(FSComp.SR.tcTypeAbbreviationsCannotHaveAugmentations(), tyDeclRange)) MutRecDefnsPhase2DataForTycon(tyconOpt, innerParent, declKind, tcref, baseValOpt, safeInitInfo, declaredTyconTypars, members, tyDeclRange, newslotsOK, fixupFinalAttrs)) @@ -15845,7 +15835,7 @@ module TcDeclarations = // 'type X with ...' in a signature is always interpreted as an extrinsic extension. // Representation-hidden types with members and interfaces are written 'type X = ...' - | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _ as r),_) when nonNil extraMembers -> + | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _ as r),_) when not (List.isEmpty extraMembers) -> let isAtOriginalTyconDefn = false let tyconCore = MutRecDefnsPhase1DataForTycon (synTyconInfo, r, implements1, false, false, isAtOriginalTyconDefn) tyconCore, (synTyconInfo,extraMembers) @@ -16026,7 +16016,7 @@ let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synS MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo let env = - if isNil enclosingNamespacePath then + if List.isEmpty enclosingNamespacePath then envAtEnd else let env = AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m env mtypRoot @@ -16071,7 +16061,7 @@ and TcSignatureElementsNonMutRec cenv parent endm env defs = | SynModuleSigDecl.Types (typeSpecs,_) -> for (TypeDefnSig(ComponentInfo(_,_,_,ids,_,_,_,_),trepr,extraMembers,_)) in typeSpecs do match trepr with - | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _),_) when nonNil extraMembers -> () + | SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _),_) when not (List.isEmpty extraMembers) -> () | _ -> yield (List.last ids).idText | _ -> () ] |> set @@ -16343,10 +16333,9 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem MutRecBindingChecking.TcMutRecDefns_UpdateNSContents nsInfo let env = - if isNil enclosingNamespacePath then + if List.isEmpty enclosingNamespacePath then envAtEnd else - let env = AddLocalRootModuleOrNamespace cenv.tcSink cenv.g cenv.amap m env mtypRoot // If the namespace is an interactive fragment e.g. FSI_0002, then open FSI_0002 in the subsequent environment @@ -16375,7 +16364,7 @@ and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, | (firstDef :: otherDefs) -> // Lookahead one to find out the scope of the next declaration. let scopem = - if isNil otherDefs then unionRanges firstDef.Range endm + if List.isEmpty otherDefs then unionRanges firstDef.Range endm else unionRanges (List.head otherDefs).Range endm // Possibly better: @@ -16526,7 +16515,7 @@ let ApplyAssemblyLevelAutoOpenAttributeToTcEnv g amap (ccu: CcuThunk) scopem env warning(Error(FSComp.SR.tcAttributeAutoOpenWasIgnored(p, ccu.AssemblyName),scopem)) env let p = splitNamespace p - if isNil p then warn() else + if List.isEmpty p then warn() else let h,t = List.frontAndBack p let modref = mkNonLocalTyconRef (mkNonLocalEntityRef ccu (Array.ofList h)) t match modref.TryDeref with @@ -16621,10 +16610,8 @@ let ApplyDefaults cenv g denvAtEnd m mexpr extraAttribs = ConstraintSolver.ChooseTyparSolutionAndSolve cenv.css denvAtEnd tp) with e -> errorRecovery e m - let CheckValueRestriction denvAtEnd rootSigOpt implFileTypePriorToSig m = - if isNone rootSigOpt then - + if Option.isNone rootSigOpt then let rec check (mty:ModuleOrNamespaceType) = for v in mty.AllValsAndMembers do let ftyvs = (freeInVal CollectTyparsNoCaching v).FreeTypars |> Zset.elements @@ -16696,7 +16683,7 @@ let TypeCheckOneImplFile (ParsedImplFileInput(_,isScript,qualNameOfFile,scopedPragmas,_,implFileFrags,isLastCompiland)) = eventually { - let cenv = cenv.Create (g, isScript, niceNameGen, amap, topCcu, false, isSome rootSigOpt, conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g)) + let cenv = cenv.Create (g, isScript, niceNameGen, amap, topCcu, false, Option.isSome rootSigOpt, conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g)) let envinner, mtypeAcc = MakeInitialEnv env diff --git a/src/fsharp/TypeRelations.fs b/src/fsharp/TypeRelations.fs index 201f8d790a6..c3cdc8d3382 100644 --- a/src/fsharp/TypeRelations.fs +++ b/src/fsharp/TypeRelations.fs @@ -259,7 +259,7 @@ let tryDestTopLambda g amap (ValReprInfo (tpNames,_,_) as tvd) (e,ty) = let n = tvd.NumCurriedArgs let tps,taue,tauty = match e with - | Expr.TyLambda (_,tps,b,_,retTy) when nonNil tpNames -> tps,b,retTy + | Expr.TyLambda (_,tps,b,_,retTy) when not (List.isEmpty tpNames) -> tps,b,retTy | _ -> [],e,ty let ctorThisValOpt,baseValOpt,vsl,body,retTy = startStripLambdaUpto n (taue,tauty) if vsl.Length <> n then diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs index 3a17d24684c..d1447739531 100644 --- a/src/fsharp/ast.fs +++ b/src/fsharp/ast.fs @@ -1675,7 +1675,7 @@ let PushPatternToExpr synArgNameGenerator isMember pat (rhs: SynExpr) = let private isSimplePattern pat = let _nowpats,laterf = SimplePatsOfPat (SynArgNameGenerator()) pat - isNone laterf + Option.isNone laterf /// "fun (UnionCase x) (UnionCase y) -> body" /// ==> @@ -1879,7 +1879,7 @@ module SynInfo = let selfMetadata = unnamedTopArg /// Determine if a syntactic information represents a member without arguments (which is implicitly a property getter) - let HasNoArgs (SynValInfo(args,_)) = isNil args + let HasNoArgs (SynValInfo(args,_)) = List.isEmpty args /// Check if one particular argument is an optional argument. Used when adjusting the /// types of optional arguments for function and member signatures. diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 583d1a3d29d..43b1659e453 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -199,7 +199,7 @@ type DisposablesTracker() = /// Type checking a set of inputs let TypeCheck (tcConfig, tcImports, tcGlobals, errorLogger:ErrorLogger, assemblyName, niceNameGen, tcEnv0, inputs, exiter: Exiter) = try - if isNil inputs then error(Error(FSComp.SR.fscNoImplementationFiles(),Range.rangeStartup)) + if List.isEmpty inputs then error(Error(FSComp.SR.fscNoImplementationFiles(),Range.rangeStartup)) let ccuName = assemblyName let tcInitialState = GetInitialTcState (rangeStartup,ccuName,tcConfig,tcGlobals,tcImports,niceNameGen,tcEnv0) TypeCheckClosedInputSet ((fun () -> errorLogger.ErrorCount > 0),tcConfig,tcImports,tcGlobals,None,tcInitialState,inputs) @@ -1260,7 +1260,7 @@ module StaticLinker = let debugStaticLinking = condition "FSHARP_DEBUG_STATIC_LINKING" let StaticLinkILModules (tcConfig, ilGlobals, ilxMainModule, dependentILModules: (CcuThunk option * ILModuleDef) list) = - if isNil dependentILModules then + if List.isEmpty dependentILModules then ilxMainModule,(fun x -> x) else @@ -1441,7 +1441,7 @@ module StaticLinker = begin let remaining = ref (computeILRefs ilxMainModule).AssemblyReferences - while nonNil !remaining do + while not (List.isEmpty !remaining) do let ilAssemRef = List.head !remaining remaining := List.tail !remaining if assumedIndependentSet.Contains ilAssemRef.Name || (ilAssemRef.PublicKey = Some ecmaPublicKey) then @@ -1503,7 +1503,7 @@ module StaticLinker = ] let remaining = ref roots - [ while nonNil !remaining do + [ while not (List.isEmpty !remaining) do let n = List.head !remaining remaining := List.tail !remaining if not n.visited then @@ -1614,7 +1614,7 @@ module StaticLinker = // Build the ILTypeDefs for generated types, starting with the roots let generatedILTypeDefs = let rec buildRelocatedGeneratedType (ProviderGeneratedType(ilOrigTyRef, ilTgtTyRef, ch)) = - let isNested = ilTgtTyRef.Enclosing |> nonNil + let isNested = not (List.isEmpty ilTgtTyRef.Enclosing) if allTypeDefsInProviderGeneratedAssemblies.ContainsKey ilOrigTyRef then let ilOrigTypeDef = allTypeDefsInProviderGeneratedAssemblies.[ilOrigTyRef] if debugStaticLinking then printfn "Relocating %s to %s " ilOrigTyRef.QualifiedName ilTgtTyRef.QualifiedName @@ -1714,7 +1714,7 @@ type SigningInfo = SigningInfo of (* delaysign:*) bool * (* publicsign:*) bool * let GetSigner signingInfo = let (SigningInfo(delaysign,publicsign,signer,container)) = signingInfo // REVIEW: favor the container over the key file - C# appears to do this - if isSome container then + if Option.isSome container then Some(ILBinaryWriter.ILStrongNameSigner.OpenKeyContainer container.Value) else match signer with @@ -1810,23 +1810,25 @@ let copyFSharpCore(outFile: string, referencedDlls: AssemblyReference list) = let outDir = Path.GetDirectoryName(outFile) let fsharpCoreAssemblyName = GetFSharpCoreLibraryName() + ".dll" let fsharpCoreDestinationPath = Path.Combine(outDir, fsharpCoreAssemblyName) - - if not (File.Exists(fsharpCoreDestinationPath)) then - match referencedDlls |> Seq.tryFind (fun dll -> String.Equals(Path.GetFileName(dll.Text), fsharpCoreAssemblyName, StringComparison.CurrentCultureIgnoreCase)) with - | Some referencedFsharpCoreDll -> File.Copy(referencedFsharpCoreDll.Text, fsharpCoreDestinationPath) - | None -> - let executionLocation = + let copyFileIfDifferent src dest = + if not (File.Exists(dest)) || (File.GetCreationTimeUtc(src) <> File.GetCreationTimeUtc(dest)) then + File.Copy(src, dest, true) + + match referencedDlls |> Seq.tryFind (fun dll -> String.Equals(Path.GetFileName(dll.Text), fsharpCoreAssemblyName, StringComparison.CurrentCultureIgnoreCase)) with + | Some referencedFsharpCoreDll -> copyFileIfDifferent referencedFsharpCoreDll.Text fsharpCoreDestinationPath + | None -> + let executionLocation = #if FX_RESHAPED_REFLECTION - TypeInThisAssembly(null).GetType().GetTypeInfo().Assembly.Location + TypeInThisAssembly(null).GetType().GetTypeInfo().Assembly.Location #else - Assembly.GetExecutingAssembly().Location + Assembly.GetExecutingAssembly().Location #endif - let compilerLocation = Path.GetDirectoryName(executionLocation) - let compilerFsharpCoreDllPath = Path.Combine(compilerLocation, fsharpCoreAssemblyName) - if File.Exists(compilerFsharpCoreDllPath) then - File.Copy(compilerFsharpCoreDllPath, fsharpCoreDestinationPath) - else - errorR(Error(FSComp.SR.fsharpCoreNotFoundToBeCopied(), rangeCmdArgs)) + let compilerLocation = Path.GetDirectoryName(executionLocation) + let compilerFsharpCoreDllPath = Path.Combine(compilerLocation, fsharpCoreAssemblyName) + if File.Exists(compilerFsharpCoreDllPath) then + copyFileIfDifferent compilerFsharpCoreDllPath fsharpCoreDestinationPath + else + errorR(Error(FSComp.SR.fsharpCoreNotFoundToBeCopied(), rangeCmdArgs)) //---------------------------------------------------------------------------- // main - split up to make sure that we can GC the @@ -2040,7 +2042,8 @@ let main4 (Args (tcConfig, errorLogger: ErrorLogger, ilGlobals, ilxMainModule, o AbortOnError(errorLogger, tcConfig, exiter) - if tcConfig.copyFSharpCore then + // Don't copy referenced fharp.core.dll if we are building fsharp.core.dll + if tcConfig.copyFSharpCore && not tcConfig.compilingFslib then copyFSharpCore(outfile, tcConfig.referencedDLLs) SqmLoggerWithConfig tcConfig errorLogger.ErrorNumbers errorLogger.WarningNumbers diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index c4b2759f917..9af45e894ae 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -714,7 +714,7 @@ type internal FsiConsoleInput(fsiOptions: FsiCommandLineOptions, inReader: TextR (new Thread(fun () -> match consoleOpt with | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.IsInteractiveServer -> - if isNil fsiOptions.SourceFiles then + if List.isEmpty fsiOptions.SourceFiles then if !progress then fprintfn outWriter "first-line-reader-thread reading first line..."; firstLine <- Some(console.ReadLine()); if !progress then fprintfn outWriter "first-line-reader-thread got first line = %A..." firstLine; @@ -1077,7 +1077,7 @@ type internal FsiDynamicCompiler |> List.unzip errorLogger.AbortOnError(); - if inputs |> List.exists isNone then failwith "parse error"; + if inputs |> List.exists Option.isNone then failwith "parse error" let inputs = List.map Option.get inputs let istate = List.fold2 fsiDynamicCompiler.ProcessMetaCommandsFromInputAsInteractiveCommands istate sourceFiles inputs fsiDynamicCompiler.EvalParsedSourceFiles (istate, inputs) @@ -1900,7 +1900,7 @@ type internal FsiInteractionProcessor let istate = consume istate fsiOptions.SourceFiles - if nonNil fsiOptions.SourceFiles then + if not (List.isEmpty fsiOptions.SourceFiles) then fsiConsolePrompt.PrintAhead(); // Seems required. I expected this could be deleted. Why not? istate @@ -2282,7 +2282,7 @@ type internal FsiEvaluationSession (argv:string[], inReader:TextReader, outWrite do fsiConsoleOutput.uprintfn "" // When no source files to load, print ahead prompt here - do if isNil fsiOptions.SourceFiles then + do if List.isEmpty fsiOptions.SourceFiles then fsiConsolePrompt.PrintAhead() diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 5a171a6b023..21832594706 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -369,7 +369,7 @@ type ValRef with member vref.IsDefiniteFSharpOverrideMember = let membInfo = vref.MemberInfo.Value let flags = membInfo.MemberFlags - not flags.IsDispatchSlot && (flags.IsOverrideOrExplicitImpl || nonNil membInfo.ImplementedSlotSigs) + not flags.IsDispatchSlot && (flags.IsOverrideOrExplicitImpl || not (List.isEmpty membInfo.ImplementedSlotSigs)) /// Check if an F#-declared member value is an explicit interface member implementation member vref.IsFSharpExplicitInterfaceImplementation g = @@ -561,24 +561,26 @@ type ParamData = type ILFieldInit with /// Compute the ILFieldInit for the given provided constant value for a provided enum type. static member FromProvidedObj m (v:obj) = - if v = null then ILFieldInit.Null else - let objTy = v.GetType() - let v = if objTy.IsEnum then objTy.GetField("value__").GetValue(v) else v - match v with - | :? single as i -> ILFieldInit.Single i - | :? double as i -> ILFieldInit.Double i - | :? bool as i -> ILFieldInit.Bool i - | :? char as i -> ILFieldInit.Char (uint16 i) - | :? string as i -> ILFieldInit.String i - | :? sbyte as i -> ILFieldInit.Int8 i - | :? byte as i -> ILFieldInit.UInt8 i - | :? int16 as i -> ILFieldInit.Int16 i - | :? uint16 as i -> ILFieldInit.UInt16 i - | :? int as i -> ILFieldInit.Int32 i - | :? uint32 as i -> ILFieldInit.UInt32 i - | :? int64 as i -> ILFieldInit.Int64 i - | :? uint64 as i -> ILFieldInit.UInt64 i - | _ -> error(Error(FSComp.SR.infosInvalidProvidedLiteralValue(try v.ToString() with _ -> "?"),m)) + match v with + | null -> ILFieldInit.Null + | _ -> + let objTy = v.GetType() + let v = if objTy.IsEnum then objTy.GetField("value__").GetValue(v) else v + match v with + | :? single as i -> ILFieldInit.Single i + | :? double as i -> ILFieldInit.Double i + | :? bool as i -> ILFieldInit.Bool i + | :? char as i -> ILFieldInit.Char (uint16 i) + | :? string as i -> ILFieldInit.String i + | :? sbyte as i -> ILFieldInit.Int8 i + | :? byte as i -> ILFieldInit.UInt8 i + | :? int16 as i -> ILFieldInit.Int16 i + | :? uint16 as i -> ILFieldInit.UInt16 i + | :? int as i -> ILFieldInit.Int32 i + | :? uint32 as i -> ILFieldInit.UInt32 i + | :? int64 as i -> ILFieldInit.Int64 i + | :? uint64 as i -> ILFieldInit.UInt64 i + | _ -> error(Error(FSComp.SR.infosInvalidProvidedLiteralValue(try v.ToString() with _ -> "?"),m)) /// Compute the OptionalArgInfo for a provided parameter. @@ -785,7 +787,7 @@ type ILMethInfo = member x.IsDllImport g = match g.attrib_DllImportAttribute with | None -> false - | Some (AttribInfo(tref,_)) ->x.RawMetadata.CustomAttrs |> TryDecodeILAttribute g tref |> isSome + | Some (AttribInfo(tref,_)) ->x.RawMetadata.CustomAttrs |> TryDecodeILAttribute g tref |> Option.isSome /// Get the (zero or one) 'self'/'this'/'object' arguments associated with an IL method. /// An instance extension method returns one object argument. @@ -1689,10 +1691,10 @@ type ILPropInfo = ILMethInfo(g,x.ILTypeInfo.ToType,None,mdef,[]) /// Indicates if the IL property has a 'get' method - member x.HasGetter = isSome x.RawMetadata.GetMethod + member x.HasGetter = Option.isSome x.RawMetadata.GetMethod /// Indicates if the IL property has a 'set' method - member x.HasSetter = isSome x.RawMetadata.SetMethod + member x.HasSetter = Option.isSome x.RawMetadata.SetMethod /// Indicates if the IL property is static member x.IsStatic = (x.RawMetadata.CallingConv = ILThisConvention.Static) @@ -1771,7 +1773,7 @@ type PropInfo = member x.HasGetter = match x with | ILProp(_,x) -> x.HasGetter - | FSProp(_,_,x,_) -> isSome x + | FSProp(_,_,x,_) -> Option.isSome x #if EXTENSIONTYPING | ProvidedProp(_,pi,m) -> pi.PUntaint((fun pi -> pi.CanRead),m) #endif @@ -1780,7 +1782,7 @@ type PropInfo = member x.HasSetter = match x with | ILProp(_,x) -> x.HasSetter - | FSProp(_,_,_,x) -> isSome x + | FSProp(_,_,_,x) -> Option.isSome x #if EXTENSIONTYPING | ProvidedProp(_,pi,m) -> pi.PUntaint((fun pi -> pi.CanWrite),m) #endif @@ -2218,7 +2220,7 @@ type EventInfo = | ILEvent(_,ILEventInfo(tinfo,edef)) -> // Get the delegate type associated with an IL event, taking into account the instantiation of the // declaring type. - if isNone edef.Type then error (nonStandardEventError x.EventName m) + if Option.isNone edef.Type then error (nonStandardEventError x.EventName m) ImportILTypeFromMetadata amap m tinfo.ILScopeRef tinfo.TypeInst [] edef.Type.Value | FSEvent(g,p,_,_) -> diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index c055a6e6614..53d5ec743a5 100755 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -53,7 +53,7 @@ let mkUnderscoreRecdField m = LongIdentWithDots([ident("_", m)], []), false let mkRecdField lidwd = lidwd, true let mkSynDoBinding (vis,strict,expr,m) = - if isSome vis then errorR(Error(FSComp.SR.parsDoCannotHaveVisibilityDeclarations(),m)); + if Option.isSome vis then errorR(Error(FSComp.SR.parsDoCannotHaveVisibilityDeclarations(),m)); Binding (None, (if strict then DoBinding else StandaloneExpression), false,false,[],PreXmlDoc.Empty,SynInfo.emptySynValData, @@ -111,20 +111,20 @@ let mkClassMemberLocalBindings(isStatic,initialRangeOpt,attrs,vis,BindingSetPreA match initialRangeOpt with | None -> bindingSetRange | Some m -> unionRanges m bindingSetRange - if nonNil ignoredFreeAttrs then warning(Error(FSComp.SR.parsAttributesIgnored(),wholeRange)); + if not (List.isEmpty ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(),wholeRange)); if isUse then errorR(Error(FSComp.SR.parsUseBindingsIllegalInImplicitClassConstructors(),wholeRange)) SynMemberDefn.LetBindings (decls,isStatic,isRec,wholeRange) let mkLocalBindings (mWhole,BindingSetPreAttrs(_,isRec,isUse,declsPreAttrs,_),body) = let ignoredFreeAttrs,decls = declsPreAttrs [] None - if nonNil ignoredFreeAttrs then warning(Error(FSComp.SR.parsAttributesIgnored(),mWhole)) + if not (List.isEmpty ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(),mWhole)) SynExpr.LetOrUse (isRec,isUse,decls,body,mWhole) let mkDefnBindings (mWhole,BindingSetPreAttrs(_,isRec,isUse,declsPreAttrs,_bindingSetRange),attrs,vis,attrsm) = if isUse then warning(Error(FSComp.SR.parsUseBindingsIllegalInModules(),mWhole)) let freeAttrs,decls = declsPreAttrs attrs vis let letDecls = [ SynModuleDecl.Let (isRec,decls,mWhole) ] - let attrDecls = if nonNil freeAttrs then [ SynModuleDecl.Attributes (freeAttrs,attrsm) ] else [] + let attrDecls = if not (List.isEmpty freeAttrs) then [ SynModuleDecl.Attributes (freeAttrs,attrsm) ] else [] attrDecls @ letDecls let idOfPat m p = @@ -134,7 +134,7 @@ let idOfPat m p = | _ -> raiseParseErrorAt m (FSComp.SR.parsIntegerForLoopRequiresSimpleIdentifier()) let checkForMultipleAugmentations m a1 a2 = - if nonNil a1 && nonNil a2 then raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed()) + if not (List.isEmpty a1) && not (List.isEmpty a2) then raiseParseErrorAt m (FSComp.SR.parsOnlyOneWithAugmentationAllowed()) a1 @ a2 let grabXmlDoc(parseState:IParseState,elemIdx) = @@ -547,8 +547,8 @@ interactiveDefns: /* An expression as part of one interaction in F# Interactive */ interactiveExpr: | opt_attributes opt_declVisibility declExpr - { if isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) - let attrDecls = if nonNil $1 then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] in + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) + let attrDecls = if not (List.isEmpty $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] in attrDecls @ [ mkSynDoDecl($3)] } @@ -664,12 +664,12 @@ fileNamespaceSpec: /* The single module declaration that can make up a signature file */ fileModuleSpec: | opt_attributes opt_declVisibility moduleIntro moduleSpfnsPossiblyEmptyBlock - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let m2 = rhs parseState 3 let m = (rhs2 parseState 3 4) let isRec,path2,xml,vis = $3 (fun (isRec2,path,_) -> - if nonNil path then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) + if not (List.isEmpty path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) let lid = path@path2 ParsedSigFileFragment.NamedModule(SynModuleOrNamespaceSig(lid, (isRec || isRec2), true, $4, xml,$1,vis,m))) } @@ -728,12 +728,12 @@ moduleSpfn: { $1 } | opt_attributes opt_declVisibility moduleIntro colonOrEquals namedModuleAbbrevBlock - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let isRec, path, xml, vis = $3 if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) if List.length path <> 1 then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) if List.length $1 <> 0 then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) - if isSome(vis) then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate()) + if Option.isSome vis then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate()) SynModuleSigDecl.ModuleAbbrev(List.head path,$5,rhs2 parseState 3 5) } | opt_attributes opt_declVisibility moduleIntro colonOrEquals moduleSpecBlock @@ -741,11 +741,11 @@ moduleSpfn: if List.length path <> 1 then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleDefnMustBeSimpleName()) if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) let info = ComponentInfo($1,[],[],path,xml,false,vis,rhs parseState 3) - if isSome($2) then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) SynModuleSigDecl.NestedModule(info, isRec, $5, rhs2 parseState 3 5) } | opt_attributes opt_declVisibility tyconSpfns - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let (TypeDefnSig(ComponentInfo(cas,a,cs,b,c,d,d2,d3),e,f,g)),rest = match $3 with | [] -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedEmptyModuleDefn()) @@ -754,7 +754,7 @@ moduleSpfn: SynModuleSigDecl.Types (tc::rest,rhs parseState 3) } | opt_attributes opt_declVisibility exconSpfn - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let (SynExceptionSig(SynExceptionDefnRepr(cas,a,b,c,d,d2),e,f)) = $3 let ec = (SynExceptionSig(SynExceptionDefnRepr($1@cas,a,b,c,d,d2),e,f)) SynModuleSigDecl.Exception(ec, rhs parseState 3) } @@ -764,9 +764,9 @@ moduleSpfn: valSpfn: | opt_attributes opt_declVisibility VAL opt_attributes opt_inline opt_mutable opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints optLiteralValueSpfn - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let attr1,attr2,isInline,isMutable,vis2,id,doc,explicitValTyparDecls,(ty,arity),konst = ($1),($4),($5),($6),($7),($8),grabXmlDoc(parseState,3),($9),($11),($12) - if nonNil attr2 then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(),rhs parseState 4)) + if not (List.isEmpty attr2) then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(),rhs parseState 4)) let m = rhs2 parseState 3 11 let valSpfn = ValSpfn((attr1@attr2),id,explicitValTyparDecls,ty,arity,isInline,isMutable,doc, vis2,konst,m) SynModuleSigDecl.Val(valSpfn,m) @@ -855,7 +855,7 @@ tyconSpfnRhs: { let m = lhs parseState let needsCheck,(kind,decls) = $1 (fun nameRange nameInfo augmentation -> - if needsCheck && isNil decls then + if needsCheck && List.isEmpty decls then reportParseErrorAt nameRange (FSComp.SR.parsEmptyTypeDefinition()) TypeDefnSig(nameInfo,SynTypeDefnSigRepr.ObjectModel (kind,decls,m),augmentation,m)) } @@ -864,7 +864,7 @@ tyconSpfnRhs: let ty,arity = $3 let invoke = SynMemberSig.Member(ValSpfn([],mkSynId m "Invoke",inferredTyparDecls,ty,arity,false,false,PreXmlDoc.Empty,None,None,m),AbstractMemberFlags MemberKind.Member,m) (fun nameRange nameInfo augmentation -> - if nonNil augmentation then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType()) + if not (List.isEmpty augmentation) then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType()) TypeDefnSig(nameInfo,SynTypeDefnSigRepr.ObjectModel (TyconDelegate (ty,arity),[invoke],m),[],m)) } @@ -932,7 +932,7 @@ classSpfnMembersAtLeastOne: /* A object member in a signature */ classMemberSpfn: | opt_attributes opt_declVisibility memberSpecFlags opt_inline opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet optLiteralValueSpfn - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let isInline,doc,vis2,id,explicitValTyparDecls,(ty,arity),optLiteralValue = $4,grabXmlDoc(parseState,3),$5,$6,$7,$9,$11 let getSetRangeOpt, getSet = $10 let getSetAdjuster arity = match arity,getSet with SynValInfo([],_),MemberKind.Member -> MemberKind.PropertyGet | _ -> getSet @@ -946,24 +946,24 @@ classMemberSpfn: SynMemberSig.Member(valSpfn, flags (getSetAdjuster arity),wholeRange) } | opt_attributes opt_declVisibility interfaceMember appType - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) SynMemberSig.Interface ($4,unionRanges (rhs parseState 3) ($4).Range) } | opt_attributes opt_declVisibility INHERIT appType - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) SynMemberSig.Inherit ($4,unionRanges (rhs parseState 3) ($4).Range) } | opt_attributes opt_declVisibility VAL fieldDecl - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let fld = $4 $1 false SynMemberSig.ValField(fld,rhs2 parseState 3 4) } | opt_attributes opt_declVisibility STATIC VAL fieldDecl - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) SynMemberSig.ValField($5 $1 true,rhs2 parseState 3 5) } | opt_attributes opt_declVisibility STATIC typeKeyword tyconSpfn - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) SynMemberSig.NestedType($5,rhs2 parseState 3 5) } | opt_attributes opt_declVisibility NEW COLON topTypeWithTypeConstraints @@ -1085,12 +1085,12 @@ fileNamespaceImpl: /* A single module definition in an implementation file */ fileModuleImpl: | opt_attributes opt_declVisibility moduleIntro moduleDefnsOrExprPossiblyEmptyOrBlock - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let m2 = rhs parseState 3 let m = (m2, $4) ||> unionRangeWithListBy (fun modu -> modu.Range) let isRec2,path2,xml,vis = $3 (fun (isRec, path, _) -> - if nonNil path then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) + if not (List.isEmpty path) then errorR(Error(FSComp.SR.parsNamespaceOrModuleNotBoth(),m2)) let lid = path@path2 ParsedImplFileFragment.NamedModule(SynModuleOrNamespace(lid, (isRec || isRec2), true, $4, xml,$1,vis,m))) } @@ -1132,25 +1132,25 @@ moduleDefnsOrExprPossiblyEmpty: /* A naked expression is only allowed at the start of a module/file, or straight after a topSeparators */ moduleDefnsOrExpr: | opt_attributes opt_declVisibility declExpr topSeparators moduleDefnsOrExpr - { if isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) - let attrDecls = if nonNil $1 then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) + let attrDecls = if not (List.isEmpty $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] attrDecls @ mkSynDoDecl ($3) :: $5 } | opt_attributes opt_declVisibility declExpr topSeparators - { if isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) - let attrDecls = if nonNil $1 then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) + let attrDecls = if not (List.isEmpty $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] attrDecls @ [ mkSynDoDecl($3) ] } | opt_attributes opt_declVisibility declExpr - { if isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) - let attrDecls = if nonNil $1 then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnexpectedVisibilityDeclaration(),rhs parseState 3)) + let attrDecls = if not (List.isEmpty $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] attrDecls @ [ mkSynDoDecl($3) ] } | moduleDefns { $1 } | opt_attributes error - { if nonNil $1 then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] } + { if not (List.isEmpty $1) then [ SynModuleDecl.Attributes ($1, rangeOfNonNilAttrs $1) ] else [] } /* A sequence of definitions in a namespace or module */ @@ -1186,7 +1186,7 @@ moduleDefn: /* 'let' definitions in non-#light*/ | opt_attributes opt_declVisibility defnBindings %prec decl_let - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) parseState.ResetSynArgNameGenerator() let (BindingSetPreAttrs(_,_,_,_,mWhole)) = $3 mkDefnBindings (mWhole,$3,$1,$2,mWhole) } @@ -1194,19 +1194,19 @@ moduleDefn: /* 'let' or 'do' definitions in #light */ | opt_attributes opt_declVisibility hardwhiteLetBindings %prec decl_let { let hwlb,m = $3 - if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) parseState.ResetSynArgNameGenerator() mkDefnBindings (m,hwlb,$1,$2,m) } /* 'do' definitions in non-#light*/ | opt_attributes opt_declVisibility doBinding %prec decl_let - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let mWhole = rhs parseState 3 mkDefnBindings (mWhole,$3,$1,$2,mWhole) } /* 'type' definitions */ | opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let (TypeDefn(ComponentInfo(cas ,a,cs,b,c,d,d2,d3),e,f,g)) = $4 let tc = (TypeDefn(ComponentInfo($1@cas,a,cs,b,c,d,d2,d3),e,f,g)) let types = tc :: $5 @@ -1214,7 +1214,7 @@ moduleDefn: /* 'exception' definitions */ | opt_attributes opt_declVisibility exconDefn - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let (SynExceptionDefn(SynExceptionDefnRepr(cas,a,b,c,d,d2),e,f)) = $3 let f = (f, $1) ||> unionRangeWithListBy (fun a -> a.Range) let ec = (SynExceptionDefn(SynExceptionDefnRepr($1@cas,a,b,c,d,d2),e,f)) @@ -1222,15 +1222,15 @@ moduleDefn: /* 'module' definitions */ | opt_attributes opt_declVisibility moduleIntro EQUALS namedModuleDefnBlock - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let attribs, (isRec, path, xml, vis) = $1,$3 match $5 with | Choice1Of2 eqn -> - if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) if List.length path <> 1 then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) if List.length $1 <> 0 then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviation()) - if isSome vis then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate()) + if Option.isSome vis then raiseParseErrorAt (rhs parseState 1) (FSComp.SR.parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate()) [ SynModuleDecl.ModuleAbbrev(List.head path,eqn,(rhs parseState 3, eqn) ||> unionRangeWithListBy (fun id -> id.idRange) ) ] | Choice2Of2 def -> if List.length path <> 1 then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleAbbreviationMustBeSimpleName()) @@ -1494,7 +1494,7 @@ tyconDefnRhs: | None -> (lhs parseState).StartRange // create a zero-width range | Some m -> m (fun nameRange augmentation -> - if needsCheck && isNil decls then + if needsCheck && List.isEmpty decls then reportParseErrorAt nameRange (FSComp.SR.parsEmptyTypeDefinition()) SynTypeDefnRepr.ObjectModel (kind,decls,m),augmentation) } @@ -1505,7 +1505,7 @@ tyconDefnRhs: (fun nameRange augmentation -> let valSpfn = ValSpfn([],mkSynId m "Invoke",inferredTyparDecls,ty,arity,false,false,PreXmlDoc.Empty,None,None,m) let invoke = SynMemberDefn.AbstractSlot(valSpfn,AbstractMemberFlags MemberKind.Member,m) - if nonNil augmentation then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType()) + if not (List.isEmpty augmentation) then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType()) SynTypeDefnRepr.ObjectModel (TyconDelegate (ty,arity),[invoke],m),[]) } @@ -1798,21 +1798,21 @@ abstractMemberFlags: /* A member definition */ classDefnMember: | opt_attributes opt_declVisibility classDefnBindings - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) [mkClassMemberLocalBindings(false,None,$1,$2,$3)] } | opt_attributes opt_declVisibility STATIC classDefnBindings - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) [mkClassMemberLocalBindings(true,Some (rhs parseState 3),$1,$2,$4)] } | opt_attributes opt_declVisibility memberFlags memberCore opt_ODECLEND - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let _,flags = $3 $4 $2 flags $1 } | opt_attributes opt_declVisibility interfaceMember appType opt_interfaceImplDefn - { if nonNil $1 then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(),rhs parseState 1)) - if isSome $2 then errorR(Error(FSComp.SR.parsInterfacesHaveSameVisibilityAsEnclosingType(),rhs parseState 3)) + { if not (List.isEmpty $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(),rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsInterfacesHaveSameVisibilityAsEnclosingType(),rhs parseState 3)) let mWhole = match $5 with | None -> rhs2 parseState 3 4 @@ -1829,25 +1829,25 @@ classDefnMember: match getSetRangeOpt with | None -> unionRanges m ty.Range | Some m2 -> unionRanges m m2 - if isSome $2 then errorR(Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract(),wholeRange)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract(),wholeRange)) let valSpfn = ValSpfn($1,id,explicitValTyparDecls,ty,arity, isInline,false,doc, None,None,wholeRange) [ SynMemberDefn.AbstractSlot(valSpfn,AbstractMemberFlags (getSetAdjuster arity), wholeRange) ] } | opt_attributes opt_declVisibility inheritsDefn - { if nonNil $1 then errorR(Error(FSComp.SR.parsAttributesIllegalOnInherit(),rhs parseState 1)) - if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityIllegalOnInherit(),rhs parseState 1)) + { if not (List.isEmpty $1) then errorR(Error(FSComp.SR.parsAttributesIllegalOnInherit(),rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityIllegalOnInherit(),rhs parseState 1)) [ $3 ] } | opt_attributes opt_declVisibility valDefnDecl opt_ODECLEND - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) $3 None $1 false } | opt_attributes opt_declVisibility STATIC valDefnDecl opt_ODECLEND - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) $4 (Some (rhs parseState 3)) $1 true } | opt_attributes opt_declVisibility memberFlags autoPropsDefnDecl opt_ODECLEND - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) let isStatic, flags = $3 $4 $1 isStatic flags } @@ -1862,7 +1862,7 @@ classDefnMember: [ SynMemberDefn.Member(Binding (None,NormalBinding,false,false,$1,grabXmlDoc(parseState,3),valSynData, declPat,None,expr,m,NoSequencePointAtInvisibleBinding),m) ] } | opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn - { if isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(),rhs parseState 2)) [ SynMemberDefn.NestedType($5,None,rhs2 parseState 3 5) ] } @@ -2018,17 +2018,17 @@ tyconDefnOrSpfnSimpleRepr: /* A type abbreviation */ | opt_attributes opt_declVisibility typ - { if nonNil $1 then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) - if isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(),rhs parseState 2)) + { if not (List.isEmpty $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(),rhs parseState 2)) SynTypeDefnSimpleRepr.TypeAbbrev (ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A union type definition */ | opt_attributes opt_declVisibility unionTypeRepr - { if nonNil $1 then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) + { if not (List.isEmpty $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) let rangesOf3 = $3 |> List.map (function |Choice1Of2(ec)->ec.Range | Choice2Of2(uc)->uc.Range) let mWhole = (rhs2 parseState 1 2, rangesOf3) ||> List.fold unionRanges if $3 |> List.exists (function Choice1Of2 _ -> true | _ -> false) then ( - if isSome $2 then errorR(Error(FSComp.SR.parsEnumTypesCannotHaveVisibilityDeclarations(),rhs parseState 2)); + if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumTypesCannotHaveVisibilityDeclarations(),rhs parseState 2)); SynTypeDefnSimpleRepr.Enum ($3 |> List.choose (function | Choice1Of2 data -> Some(data) @@ -2042,14 +2042,14 @@ tyconDefnOrSpfnSimpleRepr: /* A record type definition */ | opt_attributes opt_declVisibility braceFieldDeclList - { if nonNil $1 then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) + { if not (List.isEmpty $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) SynTypeDefnSimpleRepr.Record ($2,$3,lhs parseState) } /* An inline-assembly type definition, for FSharp.Core library only */ | opt_attributes opt_declVisibility LPAREN inlineAssemblyTyconRepr rparen - { if nonNil $1 then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) + { if not (List.isEmpty $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(),rhs parseState 1)) libraryOnlyError (lhs parseState) - if isSome $2 then errorR(Error(FSComp.SR.parsInlineAssemblyCannotHaveVisibilityDeclarations(),rhs parseState 2)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsInlineAssemblyCannotHaveVisibilityDeclarations(),rhs parseState 2)) $4 } @@ -2220,26 +2220,26 @@ attrUnionCaseDecls: /* The core of a union case definition */ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName opt_OBLOCKSEP - { if isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) let mDecl = rhs parseState 3 (fun xmlDoc -> Choice2Of2 (UnionCase ( $1, $3,UnionCaseFields [],xmlDoc,None,mDecl))) } | opt_attributes opt_access unionCaseName OF unionCaseRepr opt_OBLOCKSEP - { if isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) let mDecl = rhs2 parseState 3 5 (fun xmlDoc -> Choice2Of2 (UnionCase ( $1, $3,UnionCaseFields $5,xmlDoc,None,mDecl))) } | opt_attributes opt_access unionCaseName COLON topType opt_OBLOCKSEP - { if isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(),rhs parseState 2)) libraryOnlyWarning(lhs parseState) let mDecl = rhs2 parseState 3 5 (fun xmlDoc -> Choice2Of2 (UnionCase ( $1, $3,UnionCaseFullType $5,xmlDoc,None,mDecl))) } | opt_attributes opt_access unionCaseName EQUALS constant opt_OBLOCKSEP - { if isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(),rhs parseState 2)) + { if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(),rhs parseState 2)) let mDecl = rhs2 parseState 3 5 (fun xmlDoc -> Choice1Of2 (EnumCase ( $1, $3,$5,xmlDoc,mDecl))) } @@ -2301,7 +2301,7 @@ recdFieldDecl: | opt_attributes fieldDecl { let fld = $2 $1 false let (Field(a,b,c,d,e,f,vis,g)) = fld - if isSome vis then errorR(Error(FSComp.SR.parsRecordFieldsCannotHaveVisibilityDeclarations(),rhs parseState 2)) + if Option.isSome vis then errorR(Error(FSComp.SR.parsRecordFieldsCannotHaveVisibilityDeclarations(),rhs parseState 2)) Field(a,b,c,d,e,f,None,g) } /* Part of a field or val declaration in a record type or object type */ diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 27cecaa4e43..799ea4af9ed 100755 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -3430,11 +3430,11 @@ and CcuThunk = name: CcuReference } member ccu.Deref = - if isNull ccu.target || ccu.orphanfixup then + if isNull (ccu.target :> obj) || ccu.orphanfixup then raise(UnresolvedReferenceNoRange ccu.name) ccu.target - member ccu.IsUnresolvedReference = (isNull ccu.target || ccu.orphanfixup) + member ccu.IsUnresolvedReference = isNull (ccu.target :> obj) || ccu.orphanfixup /// Ensure the ccu is derefable in advance. Supply a path to attach to any resulting error message. member ccu.EnsureDerefable(requiringPath:string[]) = diff --git a/src/fsharp/vs/ServiceDeclarations.fs b/src/fsharp/vs/ServiceDeclarations.fs index a6482c6d31c..f8a0d9c5139 100644 --- a/src/fsharp/vs/ServiceDeclarations.fs +++ b/src/fsharp/vs/ServiceDeclarations.fs @@ -663,7 +663,7 @@ module internal ItemDescriptionsImpl = NicePrint.outputTyconRef denv os ucinfo.TyconRef bprintf os ".%s: " (DecompileOpName uc.Id.idText) - if not (isNil recd) then + if not (List.isEmpty recd) then NicePrint.outputUnionCases denv os recd os.Append (" -> ") |> ignore NicePrint.outputTy denv os rty ) @@ -864,7 +864,7 @@ module internal ItemDescriptionsImpl = | _ -> st) |> Seq.mapi (fun i x -> i,x) |> Seq.toList - if nonNil namesToAdd then + if not (List.isEmpty namesToAdd) then bprintf os "\n" for i, txt in namesToAdd do bprintf os "\n%s" ((if i = 0 then FSComp.SR.typeInfoFromFirst else FSComp.SR.typeInfoFromNext) txt) @@ -1243,7 +1243,7 @@ type FSharpDeclarationListItem(name, glyph:int, info) = // The dataTipSpinWaitTime limits how long we block the UI thread while a tooltip pops up next to a selected item in an IntelliSense completion list. // This time appears to be somewhat amortized by the time it takes the VS completion UI to actually bring up the tooltip after selecting an item in the first place. - if task = null then + if isNull task then // kick off the actual (non-cooperative) work task <- System.Threading.Tasks.Task.Factory.StartNew(fun() -> let text = decl.DescriptionTextAsync |> Async.RunSynchronously diff --git a/src/fsharp/vs/ServiceUntypedParse.fs b/src/fsharp/vs/ServiceUntypedParse.fs index 52f280ab9c2..3797daef7b0 100755 --- a/src/fsharp/vs/ServiceUntypedParse.fs +++ b/src/fsharp/vs/ServiceUntypedParse.fs @@ -122,9 +122,9 @@ type FSharpParseFileResults(errors : FSharpErrorInfo[], input : Ast.ParsedInput let rec walkBind (Binding(_, _, _, _, _, _, SynValData(memFlagsOpt,_,_), synPat, _, synExpr, _, spInfo)) = [ // Don't yield the binding sequence point if there are any arguments, i.e. we're defining a function or a method let isFunction = - isSome memFlagsOpt || + Option.isSome memFlagsOpt || match synPat with - | SynPat.LongIdent (_,_,_, SynConstructorArgs.Pats args,_,_) when nonNil args -> true + | SynPat.LongIdent (_,_,_, SynConstructorArgs.Pats args,_,_) when not (List.isEmpty args) -> true | _ -> false if not isFunction then yield! walkBindSeqPt spInfo diff --git a/src/fsharp/vs/Symbols.fs b/src/fsharp/vs/Symbols.fs index 2c911afaf8e..531f120797b 100644 --- a/src/fsharp/vs/Symbols.fs +++ b/src/fsharp/vs/Symbols.fs @@ -1231,7 +1231,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = match d with | E e -> let dty = e.GetDelegateType(cenv.amap,range0) - TryDestStandardDelegateTyp cenv.infoReader range0 AccessibleFromSomewhere dty |> isSome + TryDestStandardDelegateTyp cenv.infoReader range0 AccessibleFromSomewhere dty |> Option.isSome | P _ | M _ | V _ -> invalidOp "the value or member is not an event" member __.HasSetterMethod = @@ -1333,7 +1333,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | M m when m.LogicalName.StartsWith("add_") -> let eventName = m.LogicalName.[4..] let entityTy = generalizedTyconRef m.DeclaringEntityRef - nonNil (cenv.infoReader.GetImmediateIntrinsicEventsOfType (Some eventName, AccessibleFromSomeFSharpCode, range0, entityTy)) || + not (List.isEmpty (cenv.infoReader.GetImmediateIntrinsicEventsOfType (Some eventName, AccessibleFromSomeFSharpCode, range0, entityTy))) || match GetImmediateIntrinsicPropInfosOfType(Some eventName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 (generalizedTyconRef m.DeclaringEntityRef) with | pinfo :: _ -> pinfo.IsFSharpEventProperty | _ -> false @@ -1346,7 +1346,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | M m when m.LogicalName.StartsWith("remove_") -> let eventName = m.LogicalName.[7..] let entityTy = generalizedTyconRef m.DeclaringEntityRef - nonNil (cenv.infoReader.GetImmediateIntrinsicEventsOfType (Some eventName, AccessibleFromSomeFSharpCode, range0, entityTy)) || + not (List.isEmpty (cenv.infoReader.GetImmediateIntrinsicEventsOfType (Some eventName, AccessibleFromSomeFSharpCode, range0, entityTy))) || match GetImmediateIntrinsicPropInfosOfType(Some eventName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 (generalizedTyconRef m.DeclaringEntityRef) with | pinfo :: _ -> pinfo.IsFSharpEventProperty | _ -> false @@ -1377,7 +1377,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = match d with | M m when m.LogicalName.StartsWith("get_") -> let propName = PrettyNaming.ChopPropertyName(m.LogicalName) - nonNil (GetImmediateIntrinsicPropInfosOfType(Some propName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 (generalizedTyconRef m.DeclaringEntityRef)) + not (List.isEmpty (GetImmediateIntrinsicPropInfosOfType(Some propName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 (generalizedTyconRef m.DeclaringEntityRef))) | V v -> match v.MemberInfo with | None -> false @@ -1390,7 +1390,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = // Look for a matching property with the right name. | M m when m.LogicalName.StartsWith("set_") -> let propName = PrettyNaming.ChopPropertyName(m.LogicalName) - nonNil (GetImmediateIntrinsicPropInfosOfType(Some propName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 (generalizedTyconRef m.DeclaringEntityRef)) + not (List.isEmpty (GetImmediateIntrinsicPropInfosOfType(Some propName, AccessibleFromSomeFSharpCode) cenv.g cenv.amap range0 (generalizedTyconRef m.DeclaringEntityRef))) | V v -> match v.MemberInfo with | None -> false @@ -1466,7 +1466,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = member __.IsActivePattern = if isUnresolved() then false else match fsharpInfo() with - | Some v -> PrettyNaming.ActivePatternInfoOfValName v.CoreDisplayName v.Range |> isSome + | Some v -> PrettyNaming.ActivePatternInfoOfValName v.CoreDisplayName v.Range |> Option.isSome | None -> false member x.CompiledName = diff --git a/src/fsharp/vs/service.fs b/src/fsharp/vs/service.fs index d9d6df9d45c..fdaecbb202a 100755 --- a/src/fsharp/vs/service.fs +++ b/src/fsharp/vs/service.fs @@ -334,7 +334,7 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) static member Create(infoReader:InfoReader,m,denv,items:Item list) = let g = infoReader.g - if isNil items then new FSharpMethodGroup("", [| |]) else + if List.isEmpty items then new FSharpMethodGroup("", [| |]) else let name = items.Head.DisplayName let getOverloadsForItem item = #if FX_ATLEAST_40 @@ -357,7 +357,7 @@ type FSharpMethodGroup( name: string, unsortedMethods: FSharpMethodGroupItem[] ) | Item.UnionCase(ucr,_) -> if not ucr.UnionCase.IsNullary then [item] else [] | Item.ExnCase(ecr) -> - if recdFieldsOfExnDefRef ecr |> nonNil then [item] else [] + if List.isEmpty (recdFieldsOfExnDefRef ecr) then [] else [item] | Item.Property(_,pinfos) -> let pinfo = List.head pinfos if pinfo.IsIndexer then [item] else [] @@ -568,7 +568,7 @@ type TypeCheckInfo |> RemoveExplicitlySuppressed g |> FilterItemsForCtors filterCtors - if nonNil items then + if not (List.isEmpty items) then if hasTextChangedSinceLastTypecheck(textSnapshotInfo, m) then NameResResult.TypecheckStaleAndTextChanged // typecheck is stale, wait for second-chance IntelliSense to bring up right result else @@ -821,9 +821,9 @@ type TypeCheckInfo let safeCheck item = try check item with _ -> false // Are we looking for items with precisely the given name? - if nonNil items && exactMatchResidueOpt.IsSome then + if not (List.isEmpty items) && exactMatchResidueOpt.IsSome then let items = items |> FilterDeclItemsByResidue exactMatchResidueOpt.Value |> List.filter safeCheck - if nonNil items then Some(items, denv, m) else None + if not (List.isEmpty items) then Some(items, denv, m) else None else // When (items = []) we must returns Some([],..) and not None // because this value is used if we want to stop further processing (e.g. let x.$ = ...) @@ -888,7 +888,7 @@ type TypeCheckInfo | None, _ -> [], None | Some(origLongIdent), Some _ -> origLongIdent, None | Some(origLongIdent), None -> - assert (nonNil origLongIdent) + assert (not (List.isEmpty origLongIdent)) // note: as above, this happens when we are called for "precise" resolution - (F1 keyword, data tip etc..) let plid, residue = List.frontAndBack origLongIdent plid, Some residue @@ -954,13 +954,13 @@ type TypeCheckInfo match nameResItems, envItems, qualItems with // First, use unfiltered name resolution items, if they're not empty - | NameResResult.Members(items, denv, m), _, _ when nonNil items -> + | NameResResult.Members(items, denv, m), _, _ when not (List.isEmpty items) -> // lookup based on name resolution results successful Some(items, denv, m) // If we have nonempty items from environment that were resolved from a type, then use them... // (that's better than the next case - here we'd return 'int' as a type) - | _, FilterRelevantItems exactMatchResidueOpt (items, denv, m), _ when nonNil items -> + | _, FilterRelevantItems exactMatchResidueOpt (items, denv, m), _ when not (List.isEmpty items) -> // lookup based on name and environment successful Some(items, denv, m) @@ -1315,7 +1315,7 @@ type TypeCheckInfo | Item.RecdField(rfinfo) -> if isFunction g rfinfo.FieldType then [item] else [] | Item.Value v -> if isFunction g v.Type then [item] else [] | Item.UnionCase(ucr,_) -> if not ucr.UnionCase.IsNullary then [item] else [] - | Item.ExnCase(ecr) -> if recdFieldsOfExnDefRef ecr |> nonNil then [item] else [] + | Item.ExnCase(ecr) -> if List.isEmpty (recdFieldsOfExnDefRef ecr) then [] else [item] | Item.Property(_,pinfos) -> let pinfo = List.head pinfos if pinfo.IsIndexer then [item] else [] diff --git a/src/ilx/EraseClosures.fs b/src/ilx/EraseClosures.fs index eee997a8a00..3c39ac0d8f8 100644 --- a/src/ilx/EraseClosures.fs +++ b/src/ilx/EraseClosures.fs @@ -179,7 +179,7 @@ let mkCallBlockForMultiValueApp cenv doTailCall (args',rty') = let mkMethSpecForClosureCall cenv (clospec: IlxClosureSpec) = let tyargsl,argtys,rstruct = stripSupportedAbstraction clospec.FormalLambdas - if nonNil tyargsl then failwith "mkMethSpecForClosureCall: internal error"; + if not (List.isEmpty tyargsl) then failwith "mkMethSpecForClosureCall: internal error"; let rty' = mkTyOfLambdas cenv rstruct let argtys' = typesOfILParamsList argtys let minst' = clospec.GenericArgs @@ -237,7 +237,7 @@ let mkCallFunc cenv allocLocal numThisGenParams tl apps = // direct calls. match stripSupportedIndirectCall apps with // Type applications: REVIEW: get rid of curried tyapps - just tuple them - | tyargs,[],_ when nonNil tyargs -> + | tyargs,[],_ when not (List.isEmpty tyargs) -> // strip again, instantiating as we go. we could do this while we count. let (revInstTyArgs, rest') = (([],apps), tyargs) ||> List.fold (fun (revArgsSoFar,cs) _ -> @@ -260,7 +260,7 @@ let mkCallFunc cenv allocLocal numThisGenParams tl apps = else instrs1 @ buildApp false loaders' rest' // Term applications - | [],args,rest when nonNil args -> + | [],args,rest when not (List.isEmpty args) -> let precall,loaders' = computePreCall fst args.Length rest loaders let isLast = (match rest with Apps_done _ -> true | _ -> false) let rty = mkTyOfApps cenv rest diff --git a/src/ilx/EraseUnions.fs b/src/ilx/EraseUnions.fs index 47bc8183206..4cae9873d59 100644 --- a/src/ilx/EraseUnions.fs +++ b/src/ilx/EraseUnions.fs @@ -941,7 +941,7 @@ let mkClassUnionDef ilg tref td cud = yield { fdef with IsInitOnly= (not isStruct && isTotallyImmutable) } ] let ctorMeths = - if (isNil selfFields && isNil tagFieldsInObject && nonNil selfMeths) + if (List.isEmpty selfFields && List.isEmpty tagFieldsInObject && not (List.isEmpty selfMeths)) || cud.cudAlternatives |> Array.forall (fun alt -> repr.RepresentAlternativeAsFreshInstancesOfRootClass (info,alt)) then [] (* no need for a second ctor in these cases *) @@ -957,7 +957,7 @@ let mkClassUnionDef ilg tref td cud = // Now initialize the constant fields wherever they are stored... let addConstFieldInit cd = - if isNil altNullaryFields then + if List.isEmpty altNullaryFields then cd else prependInstrsToClassCtor diff --git a/src/update.cmd b/src/update.cmd index f489fd5ca61..67a4b8f792b 100644 --- a/src/update.cmd +++ b/src/update.cmd @@ -26,7 +26,9 @@ if not "%WindowsSDK_ExecutablePath_x86%" == "" goto :havesdk set REGEXE32BIT=reg.exe if not "%OSARCH%"=="x86" set REGEXE32BIT=%WINDIR%\syswow64\reg.exe - FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B + FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6.2\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B +if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B +if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B diff --git a/src/update.fs b/src/update.fs index 05bddd9692e..d79793ada79 100644 --- a/src/update.fs +++ b/src/update.fs @@ -59,36 +59,53 @@ let updateCmd envVars args = attempt { let processorArchitecture = WindowsPlatform.processorArchitecture envVars let x86_ProgramFiles = WindowsPlatform.x86ProgramFilesDirectory envVars processorArchitecture - let! windir = env "windir" - - let REGEXE32BIT path value = - let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32) - match hklm32 |> regQuery path value with - | Some (:? string as d) -> Some d - | Some _ | None -> None - - let allWINSDKNETFXTOOLS = seq { - // FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B - yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" "InstallationFolder" - // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B - yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" "InstallationFolder" - // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B - yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" "InstallationFolder" - // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B - yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" "InstallationFolder" - // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B - yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" "InstallationFolder" - } + // if exist "%WindowsSDK_ExecutablePath_x64%" set WINSDKNETFXTOOLS_X64=%WindowsSDK_ExecutablePath_x64% + // if exist "%WindowsSDK_ExecutablePath_x86%" set WINSDKNETFXTOOLS_X86=%WindowsSDK_ExecutablePath_x86% + + let WINSDKNETFXTOOLS_X86, WINSDKNETFXTOOLS_X64 = + let EnvironmentPath var = + match env var () with + | Success x -> if Directory.Exists(x) then x else "" + | _ -> "" + let WindowsSDK_ExecutablePath_x64 = EnvironmentPath "WindowsSDK_ExecutablePath_x64" + let WindowsSDK_ExecutablePath_x86 = EnvironmentPath "WindowsSDK_ExecutablePath_x86" + if WindowsSDK_ExecutablePath_x86 <> "" || WindowsSDK_ExecutablePath_x64 <> "" then + WindowsSDK_ExecutablePath_x86,WindowsSDK_ExecutablePath_x64 + else + let allWINSDKNETFXTOOLS = + let REGEXE32BIT path value = + let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32) + match hklm32 |> regQuery path value with + | Some (:? string as d) -> Some d + | Some _ | None -> None + seq { + // FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6.2\WinSDK-NetFx40Tools" "InstallationFolder" + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6.1\WinSDK-NetFx40Tools" "InstallationFolder" + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" "InstallationFolder" + + // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" "InstallationFolder" + // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" "InstallationFolder" + // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" "InstallationFolder" + // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B + yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" "InstallationFolder" + } + + match allWINSDKNETFXTOOLS |> Seq.tryPick id with + | Some sdk -> sdk, sdk + @"x64\" + | None -> "", "" + + let SN32 = WINSDKNETFXTOOLS_X86+"sn.exe" + let SN64 = WINSDKNETFXTOOLS_X64+"sn.exe" - let WINSDKNETFXTOOLS = match allWINSDKNETFXTOOLS |> Seq.tryPick id with Some sdk -> sdk | None -> "" - // set SN32="%WINSDKNETFXTOOLS%sn.exe" - let SN32 = WINSDKNETFXTOOLS/"sn.exe" - // set SN64="%WINSDKNETFXTOOLS%x64\sn.exe" - let SN64 = WINSDKNETFXTOOLS/"x64"/"sn.exe" // set NGEN32=%windir%\Microsoft.NET\Framework\v4.0.30319\ngen.exe - let NGEN32 = windir/"Microsoft.NET"/"Framework"/"v4.0.30319"/"ngen.exe" // set NGEN64=%windir%\Microsoft.NET\Framework64\v4.0.30319\ngen.exe + let! windir = env "windir" + let NGEN32 = windir/"Microsoft.NET"/"Framework"/"v4.0.30319"/"ngen.exe" let NGEN64 = windir/"Microsoft.NET"/"Framework64"/"v4.0.30319"/"ngen.exe" let checkResult = function CmdResult.ErrorLevel (msg, err) -> Failure (sprintf "%s. ERRORLEVEL %d" msg err) | CmdResult.Success -> Success () @@ -119,22 +136,28 @@ let updateCmd envVars args = attempt { let strongName (snExe: string -> Result<_,_>) = attempt { let all = [ "FSharp.Core"; - "FSharp.Build"; - "FSharp.Compiler.Interactive.Settings";"FSharp.Compiler.Hosted"; - "FSharp.Compiler";"FSharp.Compiler.Server.Shared"; - "FSharp.Editor"; - "FSharp.LanguageService";"FSharp.LanguageService.Base";"FSharp.LanguageService.Compiler"; - "FSharp.ProjectSystem.Base";"FSharp.ProjectSystem.FSharp";"FSharp.ProjectSystem.PropertyPages"; - "FSharp.VS.FSI"; - "VisualFSharp.Unittests"; - "VisualFSharp.Salsa" ] + "FSharp.Build"; + "FSharp.Compiler.Interactive.Settings"; + "FSharp.Compiler.Hosted"; + "FSharp.Compiler"; + "FSharp.Compiler.Server.Shared"; + "FSharp.Editor"; + "FSharp.LanguageService"; + "FSharp.LanguageService.Base"; + "FSharp.LanguageService.Compiler"; + "FSharp.ProjectSystem.Base"; + "FSharp.ProjectSystem.FSharp"; + "FSharp.ProjectSystem.PropertyPages"; + "FSharp.VS.FSI"; + "VisualFSharp.Unittests"; + "VisualFSharp.Salsa" ] for a in all do snExe (sprintf " -Vr %s,b03f5f7f11d50a3a" a) |> ignore // ignore result - SN is not needed for tests to pass, and this fails without admin rights } do! strongName sn32 - + //if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" ( do! if processorArchitecture = AMD64 then // %SN64% -Vr FSharp.Core,b03f5f7f11d50a3a diff --git a/src/utils/CompilerLocationUtils.fs b/src/utils/CompilerLocationUtils.fs index 85efb2e5735..32e28fca14e 100644 --- a/src/utils/CompilerLocationUtils.fs +++ b/src/utils/CompilerLocationUtils.fs @@ -99,12 +99,13 @@ module internal FSharpEnvironment = Option.ofString (try let key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32) - if key = null then null - else + match key with + | null -> null + | _ -> let sub = key.OpenSubKey(subKey) - if sub = null then null - else - downcast (sub.GetValue(null, null)) + match sub with + | null -> null + | _ -> downcast (sub.GetValue(null, null)) with e-> System.Diagnostics.Debug.Assert(false, sprintf "Failed in Get32BitRegistryStringValueViaDotNet: %s" (e.ToString())) null) diff --git a/src/utils/reshapedmsbuild.fs b/src/utils/reshapedmsbuild.fs index ae8c8c86846..51bf7bd7717 100644 --- a/src/utils/reshapedmsbuild.fs +++ b/src/utils/reshapedmsbuild.fs @@ -743,7 +743,6 @@ module internal ToolLocationHelper = CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion451 visualStudioVersion120 // v4.5.1 CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion452 visualStudioVersion150 // v4.5.2 CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion46 visualStudioVersion140 // v4.6 - CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion46 visualStudioVersion150 // v4.6 CreateDotNetFrameworkSpecForV4 dotNetFrameworkVersion461 visualStudioVersion150 // v4.6.1 |] array.ToDictionary(fun spec -> spec.Version) diff --git a/src/utils/reshapedreflection.fs b/src/utils/reshapedreflection.fs index fe32990c35e..600bf46da51 100644 --- a/src/utils/reshapedreflection.fs +++ b/src/utils/reshapedreflection.fs @@ -83,7 +83,7 @@ module internal ReflectionAdapters = | _ -> raise (AmbiguousMatchException()) let canUseAccessor (accessor : MethodInfo) nonPublic = - box accessor <> null && (accessor.IsPublic || nonPublic) + isNotNull(box accessor) && (accessor.IsPublic || nonPublic) type System.Type with member this.GetTypeInfo() = IntrospectionExtensions.GetTypeInfo(this) @@ -124,7 +124,7 @@ module internal ReflectionAdapters = let bindingFlags = defaultArg bindingFlags publicFlags (if isDeclaredFlag bindingFlags then this.GetTypeInfo().DeclaredProperties else this.GetRuntimeProperties()) |> Seq.filter (fun pi-> - let mi = if pi.GetMethod <> null then pi.GetMethod else pi.SetMethod + let mi = match pi.GetMethod with | null -> pi.SetMethod | _ -> pi.GetMethod if mi = null then false else isAcceptable bindingFlags mi.IsStatic mi.IsPublic ) @@ -179,8 +179,9 @@ module internal ReflectionAdapters = #if FX_RESHAPED_REFLECTION_CORECLR member this.InvokeMember(memberName, bindingFlags, _binder, target:obj, arguments:obj[], _cultureInfo) = let m = this.GetMethod(memberName, (arguments |> Seq.map(fun x -> x.GetType()) |> Seq.toArray), bindingFlags) - if m <> null then m.Invoke(target, arguments) - else raise <| System.MissingMethodException(String.Format("Method '{0}.{1}' not found.", this.FullName, memberName)) + match m with + | null -> raise <| System.MissingMethodException(String.Format("Method '{0}.{1}' not found.", this.FullName, memberName)) + | _ -> m.Invoke(target, arguments) #endif member this.IsGenericType = this.GetTypeInfo().IsGenericType member this.IsGenericTypeDefinition = this.GetTypeInfo().IsGenericTypeDefinition diff --git a/src/utils/sformat.fs b/src/utils/sformat.fs index ee87a337fec..e106245e185 100644 --- a/src/utils/sformat.fs +++ b/src/utils/sformat.fs @@ -709,11 +709,10 @@ namespace Microsoft.FSharp.Text.StructuredFormat // pprinter: anyL - support functions // -------------------------------------------------------------------- - let getProperty (obj: obj) name = - let ty = obj.GetType() + let getProperty (ty: Type) (obj: obj) name = #if FX_ATLEAST_PORTABLE let prop = ty.GetProperty(name, (BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic)) - if prop <> null then prop.GetValue(obj,[||]) + if isNotNull prop then prop.GetValue(obj,[||]) #if FX_NO_MISSINGMETHODEXCEPTION // Profile 7, 47, 78 and 259 raise MissingMemberException else @@ -732,6 +731,9 @@ namespace Microsoft.FSharp.Text.StructuredFormat ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture) #endif #endif + let getField obj (fieldInfo: FieldInfo) = + fieldInfo.GetValue(obj) + let formatChar isChar c = match c with | '\'' when isChar -> "\\\'" @@ -827,12 +829,12 @@ namespace Microsoft.FSharp.Text.StructuredFormat Some (wordL (x.ToString())) else // Try the StructuredFormatDisplayAttribute extensibility attribute - match x.GetType().GetCustomAttributes (typeof, true) with + match ty.GetCustomAttributes (typeof, true) with | null | [| |] -> None | res -> let attr = (res.[0] :?> StructuredFormatDisplayAttribute) let txt = attr.Value - if txt = null || txt.Length <= 1 then + if isNull txt || txt.Length <= 1 then None else let messageRegexPattern = @"^(?
.*?)(?.*?)(?.*)$"
@@ -862,7 +864,7 @@ namespace Microsoft.FSharp.Text.StructuredFormat
                                         let postText = m.Groups.["post"].Value // Everything after the closing bracket
                                         let prop = replaceEscapedBrackets(m.Groups.["prop"].Value) // Unescape everything between the opening and closing brackets
 
-                                        match catchExn (fun () -> getProperty x prop) with
+                                        match catchExn (fun () -> getProperty ty x prop) with
                                           | Choice2Of2 e -> Some (wordL (""))
                                           | Choice1Of2 alternativeObj ->
                                               try 
@@ -1019,7 +1021,7 @@ namespace Microsoft.FSharp.Text.StructuredFormat
 #else
                         wordL (formatString s)  
 #endif                        
-                    | :? System.Array as arr -> 
+                    | :? Array as arr -> 
                         match arr.Rank with
                         | 1 -> 
                              let n = arr.Length
@@ -1044,18 +1046,17 @@ namespace Microsoft.FSharp.Text.StructuredFormat
                         
                     // Format 'set' and 'map' nicely
                     | _ when  
-                          (let ty = obj.GetType()
-                           ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof> 
+                          (ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof> 
                                                 || ty.GetGenericTypeDefinition() = typedefof>) ) ->
-                         let ty = obj.GetType()
                          let word = if ty.GetGenericTypeDefinition() = typedefof> then "map" else "set"
                          let possibleKeyValueL v = 
+                             let tyv = v.GetType()
                              if word = "map" &&
                                 (match v with null -> false | _ -> true) && 
-                                v.GetType().IsGenericType && 
-                                v.GetType().GetGenericTypeDefinition() = typedefof> then
-                                  objL depthLim Precedence.BracketIfTuple (v.GetType().GetProperty("Key").GetValue(v, [| |]), 
-                                                                           v.GetType().GetProperty("Value").GetValue(v, [| |]))
+                                tyv.IsGenericType && 
+                                tyv.GetGenericTypeDefinition() = typedefof> then
+                                  objL depthLim Precedence.BracketIfTuple (tyv.GetProperty("Key").GetValue(v, [| |]), 
+                                                                           tyv.GetProperty("Value").GetValue(v, [| |]))
                              else
                                   objL depthLim Precedence.BracketIfTuple v
                          let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
@@ -1089,7 +1090,7 @@ namespace Microsoft.FSharp.Text.StructuredFormat
                            // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
                            wordL "" |> showModeFilter
                     | _ ->
-                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString (obj.GetType()) then
+                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString ty then
                            emptyL
                          else
                            countNodes 1
@@ -1102,8 +1103,11 @@ namespace Microsoft.FSharp.Text.StructuredFormat
 #else                           
                               let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
 #endif                              
-                              let props = 
-                                props |> Array.filter (fun pi ->
+                              let fields = ty.GetFields(BindingFlags.Instance ||| BindingFlags.Public) |> Array.map (fun i -> i :> MemberInfo)
+                              let propsAndFields = 
+                                props |> Array.map (fun i -> i :> MemberInfo)
+                                      |> Array.append fields
+                                      |> Array.filter (fun pi ->
                                     // check if property is annotated with System.Diagnostics.DebuggerBrowsable(Never). 
                                     // Its evaluation may have unexpected side effects and\or block printing.
                                     match Seq.toArray (pi.GetCustomAttributes(typeof, false)) with
@@ -1114,17 +1118,21 @@ namespace Microsoft.FSharp.Text.StructuredFormat
                               // massively reign in deep printing of properties 
                               let nDepth = depthLim/10
 #if FX_ATLEAST_PORTABLE
-                              System.Array.Sort((props),{ new System.Collections.Generic.IComparer with member this.Compare(p1,p2) = compare (p1.Name) (p2.Name) } );
+                              Array.Sort((propsAndFields),{ new IComparer with member this.Compare(p1,p2) = compare (p1.Name) (p2.Name) } );
 #else                              
-                              System.Array.Sort((props:>System.Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> PropertyInfo).Name) ((p2 :?> PropertyInfo).Name) } );
+                              Array.Sort((propsAndFields :> Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> MemberInfo).Name) ((p2 :?> MemberInfo).Name) } );
 #endif                        
 
-                              if props.Length = 0 || (nDepth <= 0) then basicL 
+                              if propsAndFields.Length = 0 || (nDepth <= 0) then basicL 
                               else basicL --- 
-                                     (props 
+                                     (propsAndFields 
+                                      |> Array.map 
+                                        (fun m -> 
+                                            (m.Name,
+                                                (try Some (objL nDepth Precedence.BracketIfTuple (getProperty ty obj m.Name)) 
+                                                 with _ -> try Some (objL nDepth Precedence.BracketIfTuple (getField obj (m :?> FieldInfo))) 
+                                                           with _ -> None)))
                                       |> Array.toList 
-                                      |> List.map (fun p -> (p.Name,(try Some (objL nDepth Precedence.BracketIfTuple (getProperty obj p.Name)) 
-                                                                     with _ -> None)))
                                       |> makePropertiesL)
                            | _ -> basicL 
                 | UnitValue -> countNodes 1; measureL
@@ -1169,8 +1177,11 @@ namespace Microsoft.FSharp.Text.StructuredFormat
             | :? unativeint  as d -> d.ToString() + "un"
             | :? bool   as b -> (if b then "true" else "false")
             | :? char   as c -> "\'" + formatChar true c + "\'"
-            | _ -> try  let text = obj.ToString()
-                        if text = null then "" else text
+            | _ -> try 
+                        let text = obj.ToString()
+                        match text with
+                        | null -> ""
+                        | _ -> text
                    with e ->
                      // If a .ToString() call throws an exception, catch it and use the message as the result.
                      // This may be informative, e.g. division by zero etc...
diff --git a/tests/.gitignore b/tests/.gitignore
index fed220c1c2c..cb70a1d0dd9 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -2,4 +2,5 @@ FSharp_*
 FSharpQA_*
 CoreUnit_*
 TestResults
-*.il
\ No newline at end of file
+*.il
+dont.run.peverify
\ No newline at end of file
diff --git a/tests/config.bat b/tests/config.bat
index 0ac4e3c8da6..e563ecbbc3f 100644
--- a/tests/config.bat
+++ b/tests/config.bat
@@ -96,7 +96,20 @@ REM == Use the same runtime as our architecture
 REM == ASSUMPTION: This could be a good or bad thing.
 IF /I NOT "%PROCESSOR_ARCHITECTURE%"=="x86" set CORDIR=%CORDIR:Framework=Framework64%
 
-FOR /F "tokens=2* delims=	 " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
+set BINDIR=%~dp0..\%1\net40\bin
+if exist "%WindowsSDK_ExecutablePath_x86%" set WINSDKNETFXTOOLS_X86=%WindowsSDK_ExecutablePath_x86%
+if not "%WindowsSDK_ExecutablePath_x86%" == "" goto :havesdk
+set REGEXE32BIT=reg.exe
+if not "%OSARCH%"=="x86" set REGEXE32BIT=%WINDIR%\syswow64\reg.exe
+                                FOR /F "tokens=2* delims=	 " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder')  DO SET WINSDKNETFXTOOLS_x86=%%B
+if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B
+if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B
+if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder')  DO SET WINSDKNETFXTOOLS_x86=%%B
+if "%WINSDKNETFXTOOLS_x86%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS_x86=%%B
+
+:havesdk
+set SN="%WINSDKNETFXTOOLS_x86%sn.exe"
+
 if "%CORSDK%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
 if "%CORSDK%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
 if "%CORSDK%"=="" FOR /F "tokens=2* delims=	 " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
diff --git a/tests/config.fs b/tests/config.fs
index 25eac1ae36c..843f7277e47 100644
--- a/tests/config.fs
+++ b/tests/config.fs
@@ -135,8 +135,11 @@ let private attendedLog envVars x86_ProgramFiles corDir corDir40 =
     let getMsbuildPath =
         // rem first see if we have got msbuild installed
         let mutable MSBuildToolsPath = envVars |> Map.tryFind "MSBuildToolsPath"
+        let VS150COMNTOOLS = match envVars |> Map.tryFind "VS150COMNTOOLS" with | Some x -> x | None -> ""
 
         // if exist "%X86_PROGRAMFILES%\MSBuild\15.0\Bin\MSBuild.exe" SET MSBuildToolsPath=%X86_PROGRAMFILES%\MSBuild\15.0\Bin\
+        if VS150COMNTOOLS/".."/".."/"MSBuild"/"15.0"/"Bin"/"MSBuild.exe" |> fileExists then
+            MSBuildToolsPath <- Some (VS150COMNTOOLS/".."/".."/"MSBuild"/"15.0"/"Bin" |> Commands.pathAddBackslash)
         if x86_ProgramFiles/"MSBuild"/"15.0"/"Bin"/"MSBuild.exe" |> fileExists then
             MSBuildToolsPath <- Some (x86_ProgramFiles/"MSBuild"/"15.0"/"Bin" |> Commands.pathAddBackslash)
         if x86_ProgramFiles/"MSBuild"/"14.0"/"Bin"/"MSBuild.exe" |> fileExists then
@@ -330,8 +333,6 @@ let config envVars =
     | X86 -> () 
     | _ -> CORDIR <- CORDIR.Replace("Framework", "Framework64")
 
-
-
     let regQueryREG_SOFTWARE path value =
         let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
         match hklm32 |> regQuery path value with
diff --git a/tests/fsharp/core/fsfromfsviacs/lib.fs b/tests/fsharp/core/fsfromfsviacs/lib.fs
index aee878399a0..164c8bd90ef 100644
--- a/tests/fsharp/core/fsfromfsviacs/lib.fs
+++ b/tests/fsharp/core/fsfromfsviacs/lib.fs
@@ -43,6 +43,7 @@ let tup4 = (2,3,4,5)
 
 
 type OptionalParameterTests =
+    static member MethodWithOptionalParam<'T>(?value : 'T) = value
     static member MethodWithOptionalParams<'T>(?value1 : 'T, ?value2 : int) = (value1, value2)
 
     static member FSharpMethodThatConsumesOptionalParams() = 
diff --git a/tests/fsharp/core/fsfromfsviacs/lib2.cs b/tests/fsharp/core/fsfromfsviacs/lib2.cs
index f46cbac1581..1556406ea90 100644
--- a/tests/fsharp/core/fsfromfsviacs/lib2.cs
+++ b/tests/fsharp/core/fsfromfsviacs/lib2.cs
@@ -68,7 +68,15 @@ public class ApiWrapper
     {
         public static Tuple, FSharpOption> MethodWithOptionalParams(T value1, int value2)
         {
-            return Lib.OptionalParameterTests.MethodWithOptionalParams(value1 = value1, value2 = value2);
+            return Lib.OptionalParameterTests.MethodWithOptionalParams(value1: value1, value2: value2);
+        }
+
+        public static FSharpOption ConsumeOptionalParam(FSharpOption param)
+        {
+            if (param == null)
+                return Lib.OptionalParameterTests.MethodWithOptionalParam(value: null);
+            else
+                return Lib.OptionalParameterTests.MethodWithOptionalParam(value: param.Value);
         }
 
         public static int MethodThatImplicitlyConvertsFSharpOption(int x)
diff --git a/tests/fsharp/core/fsfromfsviacs/test.fsx b/tests/fsharp/core/fsfromfsviacs/test.fsx
index 1d84e3d689b..f650dbdd464 100644
--- a/tests/fsharp/core/fsfromfsviacs/test.fsx
+++ b/tests/fsharp/core/fsfromfsviacs/test.fsx
@@ -1,5 +1,6 @@
 // #Conformance #Interop #Unions 
 open Lib
+open FSharpOptionalTests
 
 let mutable failures = false
 let report_failure () = 
@@ -48,6 +49,25 @@ let _ = test "structunion394b25" (Lib.NestedStructUnionsTests.testPattern2mut(u2
 let _ = test "structunion394b36" (Lib.NestedStructUnionsTests.testPattern3mut(u2))
 
 
+// F# option implicit converter tests
+
+let testFsOpt() =
+    let testOpt (t : 'T option) =
+        test (sprintf "fsimplicitconv (%A)" t) (ApiWrapper.ConsumeOptionalParam<'T>(t) = t)
+
+    testOpt(Option.None)
+    testOpt(Some 42)
+
+    // check that implicit conversion of optionals does 
+    // differentiate between 'null' and 'Some null'
+    testOpt(Option.None)
+    testOpt(Option.Some null)
+    testOpt(Some "")
+    testOpt(Some "test")
+
+testFsOpt()
+
+
 module NestedStructPatternMatchingAcrossAssemblyBoundaries = 
     open Lib.NestedStructUnionsTests
 
diff --git a/tests/fsharp/typeProviders/negTests/neg2.bsl b/tests/fsharp/typeProviders/negTests/neg2.bsl
index b1bd82c195b..a5d71afcbf7 100644
--- a/tests/fsharp/typeProviders/negTests/neg2.bsl
+++ b/tests/fsharp/typeProviders/negTests/neg2.bsl
@@ -4,3 +4,7 @@ neg2.fsx(3,59,3,66): typecheck error FS3033: The type provider 'Provider.GoodPro
 neg2.fsx(3,59,3,66): typecheck error FS3033: The type provider 'Provider.GoodProviderForNegativeTypeTests1' reported an error: Kaboom
 
 neg2.fsx(3,59,3,66): typecheck error FS0039: The value, constructor, namespace or type 'TheHype' is not defined
+
+Maybe you want one of the following:
+
+   TheType
\ No newline at end of file
diff --git a/tests/fsharp/typecheck/sigs/neg01.bsl b/tests/fsharp/typecheck/sigs/neg01.bsl
index 9f25b3af21a..236872237c7 100644
--- a/tests/fsharp/typecheck/sigs/neg01.bsl
+++ b/tests/fsharp/typecheck/sigs/neg01.bsl
@@ -4,3 +4,15 @@ neg01a.fsi(24,8,25,7): typecheck error FS0913: Types cannot contain nested type
 neg01a.fs(22,8,23,7): typecheck error FS0913: Types cannot contain nested type definitions
 
 neg01b.fs(2,13,2,14): typecheck error FS0039: The value, constructor, namespace or type 'X' is not defined
+
+Maybe you want one of the following:
+
+   z
+
+   okType
+
+   fieldsInWrongOrder
+
+   missingFieldInSignature
+
+   missingInterfaceInSignature
diff --git a/tests/fsharp/typecheck/sigs/neg14.bsl b/tests/fsharp/typecheck/sigs/neg14.bsl
index bc17ed5b514..9f9cae40f67 100644
--- a/tests/fsharp/typecheck/sigs/neg14.bsl
+++ b/tests/fsharp/typecheck/sigs/neg14.bsl
@@ -2,3 +2,15 @@
 neg14a.fs(9,6,9,33): typecheck error FS0343: The type 'missingInterfaceInSignature' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'. An implementation of 'Object.Equals' has been automatically provided, implemented via 'System.IComparable'. Consider implementing the override 'Object.Equals' explicitly
 
 neg14b.fs(2,13,2,14): typecheck error FS0039: The value, constructor, namespace or type 'X' is not defined
+
+Maybe you want one of the following:
+
+   z
+
+   okType
+
+   fieldsInWrongOrder
+
+   missingFieldInSignature
+
+   missingInterfaceInSignature
diff --git a/tests/fsharp/typecheck/sigs/neg15.bsl b/tests/fsharp/typecheck/sigs/neg15.bsl
index 5e577283df9..06ca079c08d 100644
--- a/tests/fsharp/typecheck/sigs/neg15.bsl
+++ b/tests/fsharp/typecheck/sigs/neg15.bsl
@@ -31,10 +31,34 @@ neg15.fs(116,20,116,73): typecheck error FS0072: Lookup on object of indetermina
 
 neg15.fs(122,32,122,57): typecheck error FS0039: The value, constructor, namespace or type 'InternalTagOfInternalType' is not defined
 
+Maybe you want one of the following:
+
+   InternalUnionType
+
+   InternalRecordType
+
+   PrivateUnionType
+
+   PrivateRecordType
+
+   PublicRecordType
+
 neg15.fs(128,31,128,61): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
 
 neg15.fs(135,31,135,56): typecheck error FS0039: The value, constructor, namespace or type 'InternalTagOfInternalType' is not defined
 
+Maybe you want one of the following:
+
+   InternalUnionType
+
+   InternalRecordType
+
+   PrivateUnionType
+
+   PrivateRecordType
+
+   PublicRecordType
+
 neg15.fs(141,30,141,60): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
 
 neg15.fs(152,20,152,50): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
diff --git a/tests/fsharp/typecheck/sigs/neg17.bsl b/tests/fsharp/typecheck/sigs/neg17.bsl
index a74ee616628..a37d7abf981 100644
--- a/tests/fsharp/typecheck/sigs/neg17.bsl
+++ b/tests/fsharp/typecheck/sigs/neg17.bsl
@@ -23,6 +23,18 @@ neg17b.fs(17,19,17,47): typecheck error FS0072: Lookup on object of indeterminat
 
 neg17b.fs(21,31,21,77): typecheck error FS0039: The value, constructor, namespace or type 'DefaultTagOfUnionTypeWithPrivateRepresentation' is not defined
 
+Maybe you want one of the following:
+
+   UnionTypeWithPrivateRepresentation
+
+   RecordTypeWithPrivateRepresentation
+
+   InternalUnionType
+
+   PrivateUnionType
+
+   PrivateRecordType
+
 neg17b.fs(29,31,29,61): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
 
 neg17b.fs(30,31,30,84): typecheck error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5.fs
index 144c009368c..cfbb9722f2d 100644
--- a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5.fs
+++ b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5.fs
@@ -1,7 +1,7 @@
 // #Regression #NoMT #CompilerOptions 
 // See DevDiv:364238
-//The value has been copied to ensure the original is not mutated by this operation$
-//The value has been copied to ensure the original is not mutated by this operation$
+//The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$
+//The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$
 open System.Collections.Generic
 
 let x : IEnumerator> = failwith ""
diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5w.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5w.fs
index bec9eb74931..59e60b022da 100644
--- a/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5w.fs
+++ b/tests/fsharpqa/Source/CompilerOptions/fsc/warn/warn5_level5w.fs
@@ -1,7 +1,7 @@
 // #Regression #NoMT #CompilerOptions 
 // See DevDiv:364238
-//The value has been copied to ensure the original is not mutated by this operation$
-//The value has been copied to ensure the original is not mutated by this operation$
+//The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$
+//The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed$
 open System.Collections.Generic
 
 let x : IEnumerator> = failwith ""
diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns02.fs b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns02.fs
new file mode 100644
index 00000000000..50273c1058f
--- /dev/null
+++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/E_ActivePatterns02.fs
@@ -0,0 +1,8 @@
+// #Regression #Conformance #PatternMatching #ActivePatterns 
+// Verify error if Active Patterns used with named parameters
+//A is an active pattern and cannot be treated as a discriminated union case with named fields.
+
+let (|A|B|) n = if n%2 = 0 then A n else B n
+match 10 with A(hoho=n) -> n | _ -> 0
+
+exit 1
diff --git a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst
index 4a4f68c72f3..f71447b925f 100644
--- a/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst
+++ b/tests/fsharpqa/Source/Conformance/PatternMatching/Named/env.lst
@@ -25,6 +25,7 @@
 	SOURCE=RecursiveActivePats.fs		# RecursiveActivePats.fs	
 
 	SOURCE=E_ActivePatterns01.fs		# E_ActivePatterns01.fs
+	SOURCE=E_ActivePatterns02.fs		# E_ActivePatterns02.fs
 	SOURCE=E_ParameterRestrictions01.fs	# E_ParameterRestrictions01.fs	
 
  	SOURCE=MultiActivePatterns01.fs		# MultiActivePatterns01.fs
diff --git a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi
index 04d1d693c47..76a9a314b53 100644
--- a/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi
+++ b/tests/fsharpqa/Source/Conformance/Signatures/SignatureConformance/E_StructWithNameConflict02.fsi
@@ -1,6 +1,6 @@
 // #Conformance #Signatures #Structs #Regression
 // Regression for Dev11:137942, structs used to not give errors on when member names conflicted with interface members
-//The field, constructor or member 'GetEnumerator' is not defined$
+//The field, constructor or member 'GetEnumerator' is not defined
 //Module 'M' contains     override Foo\.GetEnumerator : unit -> IEnumerator<'T>     but its signature specifies     member Foo\.GetEnumerator : unit -> IEnumerator<'T>     The compiled names differ
 module M
 
diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/UnitSpecialization.fs b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/UnitSpecialization.fs
new file mode 100644
index 00000000000..f56675b651d
--- /dev/null
+++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/UnitSpecialization.fs
@@ -0,0 +1,9 @@
+// #UnitGenericAbstractType 
+//
+
+type Foo<'t> =
+  abstract member Bar : 't -> int
+
+type Bar() =
+  interface Foo with
+    member x.Bar _ = 1
\ No newline at end of file
diff --git a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/env.lst b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/env.lst
index d33bde606e7..63e29215be3 100644
--- a/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/env.lst
+++ b/tests/fsharpqa/Source/Conformance/TypesAndTypeConstraints/TypeParameterDefinitions/env.lst
@@ -6,3 +6,4 @@
 	SOURCE=E_LazyInType02.fs SCFLAGS="--test:ErrorRanges"		# E_LazyInType02.fs
 	SOURCE=MultipleConstraints01.fs							# MultipleConstraints01.fs
 	SOURCE=ValueTypesWithConstraints01.fs						# ValueTypesWithConstraints01.fs
+	SOURCE=UnitSpecialization.fs						# UnitSpecialization.fs
diff --git a/tests/fsharpqa/Source/ErrorMessages/UnitGenericAbstractType/E_UnitGenericAbstractType1.fs b/tests/fsharpqa/Source/ErrorMessages/UnitGenericAbstractType/E_UnitGenericAbstractType1.fs
new file mode 100644
index 00000000000..0b7f1d98a6d
--- /dev/null
+++ b/tests/fsharpqa/Source/ErrorMessages/UnitGenericAbstractType/E_UnitGenericAbstractType1.fs
@@ -0,0 +1,9 @@
+// #ErrorMessages #UnitGenericAbstractType 
+//The member 'Apply : int -> unit' is specialized with 'unit' but 'unit' can't be used as return type of an abstract method parameterized on return type\.
+type EDF<'S> =
+    abstract member Apply : int -> 'S
+type SomeEDF () =
+    interface EDF with
+        member this.Apply d = 
+            // [ERROR] The member 'Apply' does not have the correct type to override the corresponding abstract method.
+            ()
\ No newline at end of file
diff --git a/tests/fsharpqa/Source/ErrorMessages/UnitGenericAbstractType/env.lst b/tests/fsharpqa/Source/ErrorMessages/UnitGenericAbstractType/env.lst
new file mode 100644
index 00000000000..26ae602bd6a
--- /dev/null
+++ b/tests/fsharpqa/Source/ErrorMessages/UnitGenericAbstractType/env.lst
@@ -0,0 +1 @@
+	SOURCE=E_UnitGenericAbstractType1.fs		# E_UnitGenericAbstractType1
\ No newline at end of file
diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx b/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx
new file mode 100644
index 00000000000..d3ac670bff1
--- /dev/null
+++ b/tests/fsharpqa/Source/InteractiveSession/Misc/PublicField.fsx
@@ -0,0 +1,13 @@
+// #Regression #NoMT #FSI 
+// Public fields did not print.
+//val it : PublicField = FSI_0002+PublicField \{X = 2;
+//                                             Y = 1;\}
+[]
+type PublicField = 
+    val X : int
+    val mutable Y : int
+    new (x) = { X = x ; Y = 1 }
+
+let t2 = PublicField(2);;
+t2;;
+#q;;
diff --git a/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst b/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst
index 03dcd5eb60c..13803307162 100644
--- a/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst
+++ b/tests/fsharpqa/Source/InteractiveSession/Misc/env.lst
@@ -29,8 +29,10 @@ ReqENU	SOURCE=E_InterfaceCrossConstrained02.fsx   COMPILE_ONLY=1 FSIMODE=PIPE SC
 
 	SOURCE=ToStringNull.fsx COMPILE_ONLY=1 FSIMODE=PIPE SCFLAGS="--nologo"	# ToStringNull.fsx
 
-        SOURCE=EnumerateSets.fsx COMPILE_ONLY=1 FSIMODE=PIPE SCFLAGS="--nologo"	# EnumerateSets.fsx  
+    SOURCE=EnumerateSets.fsx COMPILE_ONLY=1 FSIMODE=PIPE SCFLAGS="--nologo"	# EnumerateSets.fsx  
 
+    SOURCE=PublicField.fsx COMPILE_ONLY=1 FSIMODE=PIPE SCFLAGS="--nologo"	# PublicField.fsx  
+    
 # These are the regression tests for FSHARP1.0:5427
 # The scenario is a bit convoluted because of the way we end up doing the verification
 # In the last 2 cases, the verification is achieved by dumping the output of FSI to a file
diff --git a/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fs b/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fs
index f9bc3fe2231..a11a5cea146 100644
--- a/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fs
+++ b/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fs
@@ -1,6 +1,6 @@
 // #Regression #Multitargeting #NoMono #NETFX40Only 
 // Regression test for FSHARP1.0:6026
 // Just a dummy file...
-//Unable to read assembly '.+I_DO_NOT_EXIST\\FSharp\.Core\.dll'$
+//Error opening binary file '.+I_DO_NOT_EXIST\\FSharp\.Core\.dll'
 
 exit 0
diff --git a/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fsx b/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fsx
index f9bc3fe2231..a11a5cea146 100644
--- a/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fsx
+++ b/tests/fsharpqa/Source/MultiTargeting/E_BadPathToFSharpCore.fsx
@@ -1,6 +1,6 @@
 // #Regression #Multitargeting #NoMono #NETFX40Only 
 // Regression test for FSHARP1.0:6026
 // Just a dummy file...
-//Unable to read assembly '.+I_DO_NOT_EXIST\\FSharp\.Core\.dll'$
+//Error opening binary file '.+I_DO_NOT_EXIST\\FSharp\.Core\.dll'
 
 exit 0
diff --git a/tests/fsharpqa/Source/Warnings/FieldSuggestion.fs b/tests/fsharpqa/Source/Warnings/FieldSuggestion.fs
new file mode 100644
index 00000000000..6931f36f98b
--- /dev/null
+++ b/tests/fsharpqa/Source/Warnings/FieldSuggestion.fs
@@ -0,0 +1,10 @@
+// #Warnings
+//
+//Maybe you want one of the following:
+//Name
+
+type Person = { Name : string; }
+
+let x = { Person.Names = "Isaac" }
+    
+exit 0
\ No newline at end of file
diff --git a/tests/fsharpqa/Source/Warnings/SuggestTypesInModule.fs b/tests/fsharpqa/Source/Warnings/SuggestTypesInModule.fs
new file mode 100644
index 00000000000..1c5f50ebd66
--- /dev/null
+++ b/tests/fsharpqa/Source/Warnings/SuggestTypesInModule.fs
@@ -0,0 +1,8 @@
+// #Warnings
+//The type 'Lst' is not defined in 'System.Collections.Generic'
+//Maybe you want one of the following:
+//List
+
+let x : System.Collections.Generic.Lst = ResizeArray()
+    
+exit 0
\ No newline at end of file
diff --git a/tests/fsharpqa/Source/Warnings/env.lst b/tests/fsharpqa/Source/Warnings/env.lst
index be9cc19b848..322ed3d77ea 100644
--- a/tests/fsharpqa/Source/Warnings/env.lst
+++ b/tests/fsharpqa/Source/Warnings/env.lst
@@ -13,12 +13,14 @@
 	SOURCE=AccessOfTypeAbbreviation4.fs # AccessOfTypeAbbreviation4.fs
 	SOURCE=AccessOfTypeAbbreviation5.fs # AccessOfTypeAbbreviation5.fs
 	SOURCE=AccessOfTypeAbbreviation6.fs # AccessOfTypeAbbreviation6.fs
+	SOURCE=SuggestTypesInModule.fs # SuggestTypesInModule.fs
 	SOURCE=ElseBranchHasWrongType.fs # ElseBranchHasWrongType.fs
 	SOURCE=MatchingMethodWithSameNameIsNotAbstract.fs # MatchingMethodWithSameNameIsNotAbstract.fs
 	SOURCE=NoMatchingAbstractMethodWithSameName.fs # NoMatchingAbstractMethodWithSameName.fs
 	SOURCE=MissingExpressionAfterLet.fs # MissingExpressionAfterLet.fs
 	SOURCE=AssignmentOnImmutable.fs # AssignmentOnImmutable.fs
 	SOURCE=SuggestFieldsInCtor.fs # SuggestFieldsInCtor.fs
+	SOURCE=FieldSuggestion.fs # FieldSuggestion.fs
 	SOURCE=RefCellInsteadOfNot.fs # RefCellInsteadOfNot.fs
 	SOURCE=RefCellInsteadOfNot2.fs # RefCellInsteadOfNot2.fs
 	SOURCE=UpcastInsteadOfDowncast.fs # UpcastInsteadOfDowncast.fs
diff --git a/tests/fsharpqa/Source/test.lst b/tests/fsharpqa/Source/test.lst
index 8b87fc8a031..1eb2476c1a7 100644
--- a/tests/fsharpqa/Source/test.lst
+++ b/tests/fsharpqa/Source/test.lst
@@ -260,6 +260,7 @@ Misc01			Libraries\Core\Reflection
 Misc01			Libraries\Core\Unchecked
 Misc01			Warnings
 Misc01			ErrorMessages\NameResolution
+Misc01			ErrorMessages\UnitGenericAbstractType
 
 Misc02			Libraries\Portable
 Misc02			Misc
diff --git a/tests/scripts/array-perf/array-perf.fs b/tests/scripts/array-perf/array-perf.fs
new file mode 100644
index 00000000000..0f93f5dcefe
--- /dev/null
+++ b/tests/scripts/array-perf/array-perf.fs
@@ -0,0 +1,191 @@
+/// BenchmarkDotNet Notes:
+/// Docs/Github: https://github.com/PerfDotNet/BenchmarkDotNet#getting-started
+///
+/// This benchmarking suite will perform JIT warmups, collect system environment data
+/// run multiple trials, and produce convenient reports.  
+/// You will find csv, markdown, and and html versions of the reports in .\BenchmarkDotNet.Artifacts\results
+/// after running the tests.
+///
+/// Be sure to run tests in Release mode, optimizations on, etc.
+
+
+module Program
+
+open System
+open System.Threading.Tasks
+
+/// BenchmarkDotNet on Nuget at:
+/// https://www.nuget.org/packages/BenchmarkDotNet/
+/// https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/
+open BenchmarkDotNet.Attributes
+open BenchmarkDotNet.Running
+open BenchmarkDotNet.Configs
+open BenchmarkDotNet.Jobs
+
+#if MONO
+#else
+open BenchmarkDotNet.Diagnostics.Windows
+#endif
+                
+/// When pulling functions out of the complete fsharp solution to test
+/// Some things are not easily available, such as Array.zeroCreateUnchecked
+/// We mock these here using their checked variations
+module Array =
+    let inline zeroCreateUnchecked (count:int) = 
+        Array.zeroCreate count
+
+    let inline subUnchecked startIndex count (array : 'T[]) =
+        Array.sub array startIndex count
+
+// Almost every array function calls this, so mock it with 
+// the exact same code
+let inline checkNonNull argName arg = 
+            match box arg with 
+            | null -> nullArg argName 
+            | _ -> ()
+
+
+/// Here you can add the functions you want to test against.
+/// Below I use Parrallel.Partition as an example
+
+
+// Original partition
+let partition predicate (array : 'T[]) =
+                checkNonNull "array" array
+                let inputLength = array.Length
+                let lastInputIndex = inputLength - 1
+
+                let isTrue = Array.zeroCreateUnchecked inputLength
+                Parallel.For(0, inputLength, 
+                    fun i -> isTrue.[i] <- predicate array.[i]
+                    ) |> ignore
+                
+                let mutable trueLength = 0
+                for i in 0 .. lastInputIndex do
+                    if isTrue.[i] then trueLength <- trueLength + 1
+                
+                let trueResult = Array.zeroCreateUnchecked trueLength
+                let falseResult = Array.zeroCreateUnchecked (inputLength - trueLength)
+                let mutable iTrue = 0
+                let mutable iFalse = 0
+                for i = 0 to lastInputIndex do
+                    if isTrue.[i] then
+                        trueResult.[iTrue] <- array.[i]
+                        iTrue <- iTrue + 1
+                    else
+                        falseResult.[iFalse] <- array.[i]
+                        iFalse <- iFalse + 1
+
+                (trueResult, falseResult)
+
+// New variation
+let partitionNew predicate (array : 'T[]) =
+                
+                checkNonNull "array" array
+                let inputLength = array.Length                
+                let isTrue = Array.zeroCreateUnchecked inputLength                
+                let mutable trueLength = 0
+                                                
+                Parallel.For(0, 
+                             inputLength, 
+                             (fun () -> 0),
+                             (fun i _ trueCount -> 
+                                if predicate array.[i] then
+                                    isTrue.[i] <- true
+                                    trueCount + 1
+                                else
+                                    trueCount),                        
+                             Action (fun x -> System.Threading.Interlocked.Add(&trueLength,x) |> ignore) ) |> ignore
+                                
+                let res1 = Array.zeroCreateUnchecked trueLength
+                let res2 = Array.zeroCreateUnchecked (inputLength - trueLength)
+                let mutable iTrue = 0
+                let mutable iFalse = 0
+                for i = 0 to isTrue.Length-1 do
+                    if isTrue.[i] then
+                        res1.[iTrue] <- array.[i]
+                        iTrue <- iTrue + 1
+                    else
+                        res2.[iFalse] <- array.[i]
+                        iFalse <- iFalse + 1
+
+                res1, res2
+
+
+
+
+/// Configuration for a given benchmark
+type ArrayPerfConfig () =
+    inherit ManualConfig()
+    do 
+        base.Add Job.RyuJitX64
+        //base.Add Job.LegacyJitX86 // If you want to also test 32bit. It will run tests on both if both of these are here.
+        #if MONO
+        #else
+        base.Add(new MemoryDiagnoser())  // To get GC and allocation data
+        #endif
+
+[)>]
+type ArrayBenchmark () =    
+    let r = Random()
+
+    let mutable array = [||]
+    let mutable array2 = [||]
+    let mutable array3 = [||]
+    
+
+
+    //When the test runs, it will run once per each each param.
+    //This is used to run the test on arrays of size 10, 100, etc
+    //You can create a 2nd Params section and the test will run over all permutations
+    [] 
+    member val public Length = 0 with get, set
+
+    //This is run before each iteration of a test
+    []
+    member self.SetupData () =       
+             
+        // Initialize whatever arrays or other data you want to test on here.
+        // Random is often handy but some algorithms you may want to test on 
+        // Sorted or other structured data. Ints/doubles/objects etc
+        // Create however many you need.  Setup time is not included in 
+        // runtime statistics, however allocations may be, due to a bug 
+        // as of this comment.
+
+        array <- Array.init self.Length (fun i -> int(r.NextDouble()*1000.0))
+        //array2 <- Array.create self.Length 5
+        
+    
+    
+    
+    // If you set a benchmark as baseline, the results output will add a 
+    // column showing runtime of all other benchmarks as a percentage of the baseline
+    // care must be taken here to be sure your benchmark is not JITTed into nothingness
+    // because it is identified as dead code.      
+    []
+    member self.Original () =
+        array |> partition (fun x -> x % 2 = 0) 
+
+    []
+    member self.New () =
+        array |> partitionNew (fun x -> x % 2 = 0)
+        
+    //Create any number of benchmarks                           
+                                       
+   
+
+    
+
+[]
+let main argv =              
+  
+    // Run the executable with the argument "ArrayPerfBenchmark" 
+    
+    let switch = 
+        BenchmarkSwitcher [|
+            typeof
+        |]
+
+    switch.Run argv |> ignore
+    0
+
diff --git a/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj b/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj
index 8d11aabaea9..599064f2d15 100644
--- a/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj
+++ b/vsintegration/ProjectTemplates/ConsoleProject/ConsoleProject.csproj
@@ -51,6 +51,7 @@
     
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj
index aa0d47b6523..2200bd4f253 100644
--- a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj
+++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.fsproj
@@ -45,6 +45,10 @@
     
       True
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
     
     $if$ ($targetframeworkversion$ >= 3.5)
     
@@ -56,6 +60,7 @@
   
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate
index 55b9389d8cb..3c023acf6a0 100644
--- a/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate
+++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/ConsoleApplication.vstemplate
@@ -17,6 +17,7 @@
     
       AssemblyInfo.fs
       Program.fs
+      packages.config
       App.config
     
   
diff --git a/vsintegration/ProjectTemplates/ConsoleProject/Template/packages.config b/vsintegration/ProjectTemplates/ConsoleProject/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/ConsoleProject/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj b/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj
index 7d7dc3fb15a..c71088687a8 100644
--- a/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj
+++ b/vsintegration/ProjectTemplates/LibraryProject/LibraryProject.csproj
@@ -41,19 +41,20 @@
       false
     
   
-  
+
   
     
   
-  
+
   
     
     
     
     
+    
     
   
-  
+
   
   
   
diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj
index fd5f2081854..6bcaa3bec86 100644
--- a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj
+++ b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.fsproj
@@ -41,6 +41,10 @@
     
       True
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
     
     $if$ ($targetframeworkversion$ >= 3.5)
     
@@ -52,6 +56,7 @@
   
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate
index 0dc7bb10a0e..d351e7034b4 100644
--- a/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate
+++ b/vsintegration/ProjectTemplates/LibraryProject/Template/Library.vstemplate
@@ -17,6 +17,7 @@
     
       AssemblyInfo.fs
       Library1.fs
+      packages.config
       Script.fsx
     
   
diff --git a/vsintegration/ProjectTemplates/LibraryProject/Template/packages.config b/vsintegration/ProjectTemplates/LibraryProject/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/LibraryProject/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/NetCore259Project/NetCore259Project.csproj b/vsintegration/ProjectTemplates/NetCore259Project/NetCore259Project.csproj
index 2b961b74159..28ef29bb455 100644
--- a/vsintegration/ProjectTemplates/NetCore259Project/NetCore259Project.csproj
+++ b/vsintegration/ProjectTemplates/NetCore259Project/NetCore259Project.csproj
@@ -51,6 +51,7 @@
     
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/NetCore259Project/Template/NETCore259PortableLibrary.vstemplate b/vsintegration/ProjectTemplates/NetCore259Project/Template/NETCore259PortableLibrary.vstemplate
index 104191439cd..787127b74fa 100644
--- a/vsintegration/ProjectTemplates/NetCore259Project/Template/NETCore259PortableLibrary.vstemplate
+++ b/vsintegration/ProjectTemplates/NetCore259Project/Template/NETCore259PortableLibrary.vstemplate
@@ -17,6 +17,7 @@
     
       AssemblyInfo.fs
       PortableLibrary1.fs
+      packages.config
       Script.fsx
     
   
diff --git a/vsintegration/ProjectTemplates/NetCore259Project/Template/PortableLibrary.fsproj b/vsintegration/ProjectTemplates/NetCore259Project/Template/PortableLibrary.fsproj
index 6add767452e..84f5a353b2d 100644
--- a/vsintegration/ProjectTemplates/NetCore259Project/Template/PortableLibrary.fsproj
+++ b/vsintegration/ProjectTemplates/NetCore259Project/Template/PortableLibrary.fsproj
@@ -40,10 +40,15 @@
       FSharp.Core.dll
       $(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore\$(TargetFSharpCoreVersion)\FSharp.Core.dll
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
   
   
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/NetCore259Project/Template/packages.config b/vsintegration/ProjectTemplates/NetCore259Project/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/NetCore259Project/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/NetCore78Project/NetCore78Project.csproj b/vsintegration/ProjectTemplates/NetCore78Project/NetCore78Project.csproj
index c809eda8d74..0bacc77498a 100644
--- a/vsintegration/ProjectTemplates/NetCore78Project/NetCore78Project.csproj
+++ b/vsintegration/ProjectTemplates/NetCore78Project/NetCore78Project.csproj
@@ -32,28 +32,29 @@
       $(FSharpSourcesRoot)\..\loc\lcl\{Lang}\$(TemplateCategory)\$(AssemblyName)\AssemblyInfo.fs.lcl
       $(FSharpSourcesRoot)\..\loc\lci\$(TemplateCategory)\$(AssemblyName)\AssemblyInfo.fs.lci
       false
-	  false
+      false
     
     
       $(FSharpSourcesRoot)\..\loc\lcl\{Lang}\$(TemplateCategory)\$(AssemblyName)\Script.fsx.lcl
       $(FSharpSourcesRoot)\..\loc\lci\$(TemplateCategory)\$(AssemblyName)\Script.fsx.lci
       false
-	  false
+      false
     
   
-  
+
   
     
   
-  
+
   
     
     
     
     
+    
     
   
-  
+
   
   
   
diff --git a/vsintegration/ProjectTemplates/NetCore78Project/Template/NETCore78PortableLibrary.vstemplate b/vsintegration/ProjectTemplates/NetCore78Project/Template/NETCore78PortableLibrary.vstemplate
index c03031a59fd..db0143565ca 100644
--- a/vsintegration/ProjectTemplates/NetCore78Project/Template/NETCore78PortableLibrary.vstemplate
+++ b/vsintegration/ProjectTemplates/NetCore78Project/Template/NETCore78PortableLibrary.vstemplate
@@ -17,6 +17,7 @@
     
       AssemblyInfo.fs
       PortableLibrary1.fs
+      packages.config
       Script.fsx
     
   
diff --git a/vsintegration/ProjectTemplates/NetCore78Project/Template/PortableLibrary.fsproj b/vsintegration/ProjectTemplates/NetCore78Project/Template/PortableLibrary.fsproj
index db9090f86b5..372c6b5a616 100644
--- a/vsintegration/ProjectTemplates/NetCore78Project/Template/PortableLibrary.fsproj
+++ b/vsintegration/ProjectTemplates/NetCore78Project/Template/PortableLibrary.fsproj
@@ -40,10 +40,15 @@
       FSharp.Core.dll
       $(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore\$(TargetFSharpCoreVersion)\FSharp.Core.dll
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
   
   
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/NetCore78Project/Template/packages.config b/vsintegration/ProjectTemplates/NetCore78Project/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/NetCore78Project/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/NetCoreProject/NetCoreProject.csproj b/vsintegration/ProjectTemplates/NetCoreProject/NetCoreProject.csproj
index 2aa6eec186b..6bcefea0501 100644
--- a/vsintegration/ProjectTemplates/NetCoreProject/NetCoreProject.csproj
+++ b/vsintegration/ProjectTemplates/NetCoreProject/NetCoreProject.csproj
@@ -24,9 +24,9 @@
     net40
     $(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\$(TemplateCategory)\$(AssemblyName)
   
-  
+
   
-  
+
   
     
       $(FSharpSourcesRoot)\..\loc\lcl\{Lang}\$(TemplateCategory)\$(AssemblyName)\AssemblyInfo.fs.lcl
@@ -52,6 +52,7 @@
     
     
     
+    
   
   
   
diff --git a/vsintegration/ProjectTemplates/NetCoreProject/Template/NETCore7PortableLibrary.vstemplate b/vsintegration/ProjectTemplates/NetCoreProject/Template/NETCore7PortableLibrary.vstemplate
index 86a55d608ca..b228ccb0c16 100644
--- a/vsintegration/ProjectTemplates/NetCoreProject/Template/NETCore7PortableLibrary.vstemplate
+++ b/vsintegration/ProjectTemplates/NetCoreProject/Template/NETCore7PortableLibrary.vstemplate
@@ -18,6 +18,7 @@
       AssemblyInfo.fs
       PortableLibrary1.fs
       Script.fsx
+      packages.config
     
   
 
diff --git a/vsintegration/ProjectTemplates/NetCoreProject/Template/PortableLibrary.fsproj b/vsintegration/ProjectTemplates/NetCoreProject/Template/PortableLibrary.fsproj
index bd081578eb2..ecf71f26e49 100644
--- a/vsintegration/ProjectTemplates/NetCoreProject/Template/PortableLibrary.fsproj
+++ b/vsintegration/ProjectTemplates/NetCoreProject/Template/PortableLibrary.fsproj
@@ -40,10 +40,15 @@
       FSharp.Core.dll
       $(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore\$(TargetFSharpCoreVersion)\FSharp.Core.dll
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
   
   
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/NetCoreProject/Template/packages.config b/vsintegration/ProjectTemplates/NetCoreProject/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/NetCoreProject/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/PortableLibraryProject/PortableLibraryProject.csproj b/vsintegration/ProjectTemplates/PortableLibraryProject/PortableLibraryProject.csproj
index 6e0987435f0..82f33cc8ac3 100644
--- a/vsintegration/ProjectTemplates/PortableLibraryProject/PortableLibraryProject.csproj
+++ b/vsintegration/ProjectTemplates/PortableLibraryProject/PortableLibraryProject.csproj
@@ -51,6 +51,7 @@
     
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.fsproj b/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.fsproj
index 1c7461cc795..dba3e128719 100644
--- a/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.fsproj
+++ b/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.fsproj
@@ -39,10 +39,15 @@
       FSharp.Core.dll
       $(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETPortable\$(TargetFSharpCoreVersion)\FSharp.Core.dll
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
   
   
     
     
+    
     
   
   
diff --git a/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.vstemplate b/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.vstemplate
index 9dffb0eafb7..ef42699a0f4 100644
--- a/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.vstemplate
+++ b/vsintegration/ProjectTemplates/PortableLibraryProject/Template/PortableLibrary.vstemplate
@@ -18,6 +18,7 @@
       AssemblyInfo.fs
       PortableLibrary1.fs
       Script.fsx
+      packages.config
     
   
 
diff --git a/vsintegration/ProjectTemplates/PortableLibraryProject/Template/packages.config b/vsintegration/ProjectTemplates/PortableLibraryProject/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/PortableLibraryProject/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj
index f1d23eacbaa..d2e6ae15561 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsproj
@@ -55,10 +55,15 @@
     $endif$
     
     
+    
+      ..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dll
+      True
+    
   
   
     
-  
+    
+   
   
     11
   
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx
index 213ec0335f0..9759959fa90 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.fsx
@@ -22,6 +22,7 @@
 //    - Booleans
 //    - Strings
 //    - Tuples
+//      struct Tuples
 //    - Lists and list processing
 //    - Classes
 //    - Generic classes
@@ -149,7 +150,29 @@ module Tuples =
     let tuple2 = (1, "fred", 3.1415)
 
     printfn "tuple1: %A    tuple2: %A" tuple1 tuple2
-    
+
+
+
+// ---------------------------------------------------------------
+//         Tuples (ordered sets of values)
+// ---------------------------------------------------------------
+
+module StructTuples = 
+
+    /// A simple tuple of integers
+    let tuple1 = struct (1, 2, 3)
+
+    /// A function that swaps the order of two values in a tuple. 
+    /// QuickInfo shows that the function is inferred to have a generic type.
+    let swapElems struct (a, b) = struct (b, a)
+
+    printfn "The result of swapping struct (1, 2) is %A" (swapElems struct (1,2))
+
+    /// A tuple consisting of an integer, a string, and a double-precision floating point number
+    let tuple2 = struct (1, "fred", 3.1415)
+
+    printfn "tuple1: %A    tuple2: %A" tuple1 tuple2
+
 
 
 // ---------------------------------------------------------------
@@ -601,7 +624,6 @@ module Events =
 
 
 
-
 #if COMPILED
 module BoilerPlateForForm = 
     []
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate
index 520a9837508..e02b29b756d 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/Tutorial.vstemplate
@@ -16,6 +16,7 @@
   
     
       Tutorial.fsx
+      packages.config
     
   
 
diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/packages.config b/vsintegration/ProjectTemplates/TutorialProject/Template/packages.config
new file mode 100644
index 00000000000..2688d2bafb3
--- /dev/null
+++ b/vsintegration/ProjectTemplates/TutorialProject/Template/packages.config
@@ -0,0 +1,4 @@
+
+
+  
+
\ No newline at end of file
diff --git a/vsintegration/ProjectTemplates/TutorialProject/TutorialProject.csproj b/vsintegration/ProjectTemplates/TutorialProject/TutorialProject.csproj
index a5a9595ea17..15caced7cac 100644
--- a/vsintegration/ProjectTemplates/TutorialProject/TutorialProject.csproj
+++ b/vsintegration/ProjectTemplates/TutorialProject/TutorialProject.csproj
@@ -43,6 +43,7 @@
   
     
     
+    
     
   
   
diff --git a/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs b/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs
index 8454370be55..77b8146d992 100644
--- a/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs
+++ b/vsintegration/src/FSharp.LanguageService/BackgroundRequests.fs
@@ -256,7 +256,7 @@ type internal FSharpLanguageServiceBackgroundRequests
     // Called before a Goto Definition to wait a moment to synchonize the parse
     member fls.TrySynchronizeParseFileInformation(view: IVsTextView, source: ISource, millisecondsTimeout:int) =
 
-        if (lastParseFileRequest = null || lastParseFileRequest.Timestamp <> source.ChangeCount) then
+        if isNull lastParseFileRequest || lastParseFileRequest.Timestamp <> source.ChangeCount then
             let req = fls.TriggerParseFile(view, source)
                     
             if req <> null && (req.IsSynchronous || req.Result <> null) then
diff --git a/vsintegration/src/FSharp.LanguageService/FSharpSource.fs b/vsintegration/src/FSharp.LanguageService/FSharpSource.fs
index 56df3d9fcd6..62d2c3c7337 100644
--- a/vsintegration/src/FSharp.LanguageService/FSharpSource.fs
+++ b/vsintegration/src/FSharp.LanguageService/FSharpSource.fs
@@ -438,7 +438,7 @@ type internal FSharpSource(service:LanguageService, textLines, colorizer, vsFile
         member source.HandleCompletionResponse(req) =
             match req with
             | null -> source.ResetFSharpIntelliSenseToAppearAdornment()
-            | _ when req.View = null || req.ResultIntellisenseInfo = null -> source.ResetFSharpIntelliSenseToAppearAdornment()
+            | _ when isNull req.View || isNull req.ResultIntellisenseInfo -> source.ResetFSharpIntelliSenseToAppearAdornment()
             | _ when (req.Timestamp <> source.ChangeCount) -> source.ResetFSharpIntelliSenseToAppearAdornment()
             | _ ->
                   source.HandleResponseHelper(req)
@@ -448,7 +448,7 @@ type internal FSharpSource(service:LanguageService, textLines, colorizer, vsFile
                   async {
                       let! decls = req.ResultIntellisenseInfo.GetDeclarations(req.Snapshot, req.Line, req.Col, reason)
                       do! Async.SwitchToContext UIThread.TheSynchronizationContext
-                      if (decls = null || decls.IsEmpty()) && req.Timestamp <> req.ResultTimestamp then
+                      if (isNull decls || decls.IsEmpty()) && req.Timestamp <> req.ResultTimestamp then
                           // Second chance intellisense: we didn't get any result and the basis typecheck was stale. We need to retrigger the completion.
                           source.Completion(req.View, req.TokenInfo, req.Reason, RequireFreshResults.Yes)
                       else
diff --git a/vsintegration/src/FSharp.LanguageService/QuickParse.fs b/vsintegration/src/FSharp.LanguageService/QuickParse.fs
index 28fa4fb3b1e..b31c3c2d76a 100644
--- a/vsintegration/src/FSharp.LanguageService/QuickParse.fs
+++ b/vsintegration/src/FSharp.LanguageService/QuickParse.fs
@@ -30,12 +30,12 @@ module internal QuickParse =
     // Adjusts the token tag for the given identifier
     // - if we're inside active pattern name (at the bar), correct the token TAG to be an identifier
     let CorrectIdentifierToken (s:string) tokenTag = 
-        if (s.EndsWith("|")) then (Microsoft.FSharp.Compiler.Parser.tagOfToken (Microsoft.FSharp.Compiler.Parser.token.IDENT s)) 
+        if s.EndsWith "|" then Microsoft.FSharp.Compiler.Parser.tagOfToken (Microsoft.FSharp.Compiler.Parser.token.IDENT s)
         else tokenTag
 
     let rec isValidStrippedName (name:string) idx = 
-        if (idx = name.Length) then false
-        elif (IsIdentifierPartCharacter name.[idx]) then true
+        if idx = name.Length then false
+        elif IsIdentifierPartCharacter name.[idx] then true
         else isValidStrippedName name (idx + 1)
 
     // Utility function that recognizes whether a name is valid active pattern name
@@ -76,7 +76,7 @@ module internal QuickParse =
     /// allow us to use find the correct qualified items rather than resorting
     /// to the more expensive and less accurate environment lookup.
     let GetCompleteIdentifierIslandImpl (s : string) (p : int) : (string*int*bool) option =
-        if p<0 || s = null || p>=s.Length then None 
+        if p < 0 || isNull s || p >= s.Length then None 
         else
             let fixup =
                 match () with
@@ -143,13 +143,13 @@ module internal QuickParse =
                     let l = searchLeft p
                     let r = searchRight p
                     let ident = s.Substring (l, r - l + 1)
-                    if (ident.IndexOf('|') <> -1 && not(isValidActivePatternName(ident))) then None else
-                        let pos   = r + magicalAdjustmentConstant 
+                    if ident.IndexOf('|') <> -1 && not(isValidActivePatternName(ident)) then None else
+                        let pos = r + magicalAdjustmentConstant 
                         Some(ident, pos, false)
                     )
 
     let GetCompleteIdentifierIsland (tolerateJustAfter:bool) (s : string) (p : int) : (string*int*bool) option =
-        if String.IsNullOrEmpty(s) then None
+        if String.IsNullOrEmpty s then None
         else     
             let directResult = GetCompleteIdentifierIslandImpl s p
             if tolerateJustAfter && directResult = None then 
@@ -157,37 +157,38 @@ module internal QuickParse =
             else 
                 directResult
 
+    let private defaultName = [],""
+
     /// Get the partial long name of the identifier to the left of index.
     let GetPartialLongName(line:string,index) =
-        if line = null then ([],"")
-        elif index<0 then ([],"")
-        elif index>=line.Length then ([],"")
+        if isNull line then defaultName
+        elif index < 0 then defaultName
+        elif index >= line.Length then defaultName
         else
-            let IsIdentifierPartCharacter(pos) = IsIdentifierPartCharacter(line.[pos])
-            let IsLongIdentifierPartCharacter(pos) = IsLongIdentifierPartCharacter(line.[pos])
-            let IsDot(pos) = line.[pos]='.'
+            let IsIdentifierPartCharacter pos = IsIdentifierPartCharacter line.[pos]
+            let IsLongIdentifierPartCharacter pos = IsLongIdentifierPartCharacter line.[pos]
+            let IsDot pos = line.[pos] = '.'
 
             let rec InLeadingIdentifier(pos,right,(prior,residue)) = 
-                let PushName() = 
-                    ((line.Substring(pos+1,right-pos-1))::prior),residue
+                let PushName() = ((line.Substring(pos+1,right-pos-1))::prior),residue
                 if pos < 0 then PushName()
-                elif IsIdentifierPartCharacter(pos) then InLeadingIdentifier(pos-1,right,(prior,residue))
-                elif IsDot(pos) then InLeadingIdentifier(pos-1,pos,PushName())
+                elif IsIdentifierPartCharacter pos then InLeadingIdentifier(pos-1,right,(prior,residue))
+                elif IsDot pos then InLeadingIdentifier(pos-1,pos,PushName())
                 else PushName()
 
             let rec InName(pos,startResidue,right) =
                 let NameAndResidue() = 
                     [line.Substring(pos+1,startResidue-pos-1)],(line.Substring(startResidue+1,right-startResidue))
                 if pos < 0 then [line.Substring(pos+1,startResidue-pos-1)],(line.Substring(startResidue+1,right-startResidue))
-                elif IsIdentifierPartCharacter(pos) then InName(pos-1,startResidue,right) 
-                elif IsDot(pos) then InLeadingIdentifier(pos-1,pos,NameAndResidue())
+                elif IsIdentifierPartCharacter pos then InName(pos-1,startResidue,right) 
+                elif IsDot pos then InLeadingIdentifier(pos-1,pos,NameAndResidue())
                 else NameAndResidue()
 
             let rec InResidue(pos,right) =
-                if pos < 0 then [],(line.Substring(pos+1,right-pos))
-                elif IsDot(pos) then InName(pos-1,pos,right)
-                elif IsLongIdentifierPartCharacter(pos) then InResidue(pos-1, right)
-                else [],(line.Substring(pos+1,right-pos))
+                if pos < 0 then [],line.Substring(pos+1,right-pos)
+                elif IsDot pos then InName(pos-1,pos,right)
+                elif IsLongIdentifierPartCharacter pos then InResidue(pos-1, right)
+                else [],line.Substring(pos+1,right-pos)
                 
             let result = InResidue(index,index)
             result
@@ -198,33 +199,32 @@ module internal QuickParse =
 
     /// Get the partial long name of the identifier to the left of index.
     let GetPartialLongNameEx(line:string,index) : (string list * string) =
-        if line = null then ([],"")
-        elif index<0 then ([],"")
-        elif index>=line.Length then ([],"")
+        if isNull line then defaultName
+        elif index < 0 then defaultName
+        elif index >= line.Length then defaultName
         else
-            let IsIdentifierPartCharacter(pos) = IsIdentifierPartCharacter(line.[pos])
-            let IsIdentifierStartCharacter(pos) = IsIdentifierPartCharacter(pos)
-            let IsDot(pos) = line.[pos]='.'
-            let IsTick(pos) = line.[pos]='`'
-            let IsEndOfComment(pos) = pos < index - 1 && line.[pos] = '*' && line.[pos + 1] = ')'
-            let IsStartOfComment(pos) = pos < index - 1 && line.[pos] = '(' && line.[pos + 1] = '*'
-            let IsWhitespace(pos) = Char.IsWhiteSpace(line.[pos])
+            let IsIdentifierPartCharacter pos = IsIdentifierPartCharacter line.[pos]
+            let IsIdentifierStartCharacter pos = IsIdentifierPartCharacter pos
+            let IsDot pos = line.[pos] = '.'
+            let IsTick pos = line.[pos] = '`'
+            let IsEndOfComment pos = pos < index - 1 && line.[pos] = '*' && line.[pos + 1] = ')'
+            let IsStartOfComment pos = pos < index - 1 && line.[pos] = '(' && line.[pos + 1] = '*'
+            let IsWhitespace pos = Char.IsWhiteSpace(line.[pos])
 
             let rec SkipWhitespaceBeforeDotIdentifier(pos, ident, current,throwAwayNext) =
-                if pos > index then [],""  // we're in whitespace after an identifier, if this is where the cursor is, there is no PLID here
-                elif IsWhitespace(pos) then SkipWhitespaceBeforeDotIdentifier(pos+1,ident,current,throwAwayNext)
-                elif IsDot(pos) then AtStartOfIdentifier(pos+1,ident::current,throwAwayNext)
+                if pos > index then defaultName  // we're in whitespace after an identifier, if this is where the cursor is, there is no PLID here
+                elif IsWhitespace pos then SkipWhitespaceBeforeDotIdentifier(pos+1,ident,current,throwAwayNext)
+                elif IsDot pos then AtStartOfIdentifier(pos+1,ident::current,throwAwayNext)
                 elif IsStartOfComment pos then EatComment(1, pos + 1, EatCommentCallContext.SkipWhiteSpaces(ident, current, throwAwayNext))
                 else AtStartOfIdentifier(pos,[],false) // Throw away what we have and start over.
 
             and EatComment (nesting, pos, callContext) = 
-                if pos > index then [], ""
-                else
-                if IsStartOfComment(pos) then
+                if pos > index then defaultName else
+                if IsStartOfComment pos then
                     // track balance of closing '*)'
                     EatComment(nesting + 1, pos + 2, callContext)
                 else
-                if IsEndOfComment(pos) then
+                if IsEndOfComment pos then
                     if nesting = 1 then 
                         // all right, we are at the end of comment, jump outside
                         match callContext with
@@ -241,42 +241,42 @@ module internal QuickParse =
 
             and InUnquotedIdentifier(left:int,pos:int,current,throwAwayNext) =
                 if pos > index then 
-                    if throwAwayNext then [],"" else current,(line.Substring(left,pos-left))
+                    if throwAwayNext then defaultName else current,line.Substring(left,pos-left)
                 else
-                    if IsIdentifierPartCharacter(pos) then InUnquotedIdentifier(left,pos+1,current,throwAwayNext)
-                    elif IsDot(pos) then 
+                    if IsIdentifierPartCharacter pos then InUnquotedIdentifier(left,pos+1,current,throwAwayNext)
+                    elif IsDot pos then 
                         let ident = line.Substring(left,pos-left)
                         AtStartOfIdentifier(pos+1,ident::current,throwAwayNext)
-                    elif IsWhitespace(pos) || IsStartOfComment(pos) then 
+                    elif IsWhitespace pos || IsStartOfComment pos then 
                         let ident = line.Substring(left,pos-left)
                         SkipWhitespaceBeforeDotIdentifier(pos, ident, current,throwAwayNext)
                     else AtStartOfIdentifier(pos,[],false) // Throw away what we have and start over.
 
             and InQuotedIdentifier(left:int,pos:int, current,throwAwayNext) =
                 if pos > index then 
-                    if throwAwayNext then [],"" else current,(line.Substring(left,pos-left))
+                    if throwAwayNext then defaultName else current,line.Substring(left,pos-left)
                 else
-                    let remainingLength = line.Length-pos
-                    if IsTick(pos) && remainingLength>1 && IsTick(pos+1) then 
+                    let remainingLength = line.Length - pos
+                    if IsTick pos && remainingLength > 1 && IsTick(pos+1) then 
                         let ident = line.Substring(left, pos-left)
                         SkipWhitespaceBeforeDotIdentifier(pos+2,ident,current,throwAwayNext) 
                     else InQuotedIdentifier(left,pos+1,current,throwAwayNext)                    
 
             and AtStartOfIdentifier(pos:int, current, throwAwayNext) =
                 if pos > index then 
-                    if throwAwayNext then [],"" else current,""
+                    if throwAwayNext then defaultName else current,""
                 else
-                    if IsWhitespace(pos) then AtStartOfIdentifier(pos+1,current,throwAwayNext)
+                    if IsWhitespace pos then AtStartOfIdentifier(pos+1,current,throwAwayNext)
                     else
-                        let remainingLength = line.Length-pos
-                        if IsTick(pos) && remainingLength>1 && IsTick(pos+1) then InQuotedIdentifier(pos+2,pos+2,current,throwAwayNext)
-                        elif IsStartOfComment(pos) then EatComment(1, pos + 1, EatCommentCallContext.StartIdentifier(current, throwAwayNext))
-                        elif IsIdentifierStartCharacter(pos) then InUnquotedIdentifier(pos,pos+1,current,throwAwayNext)
-                        elif IsDot(pos) then 
-                            if pos=0 then
+                        let remainingLength = line.Length - pos
+                        if IsTick pos && remainingLength > 1 && IsTick(pos+1) then InQuotedIdentifier(pos+2,pos+2,current,throwAwayNext)
+                        elif IsStartOfComment pos then EatComment(1, pos + 1, EatCommentCallContext.StartIdentifier(current, throwAwayNext))
+                        elif IsIdentifierStartCharacter pos then InUnquotedIdentifier(pos,pos+1,current,throwAwayNext)
+                        elif IsDot pos then 
+                            if pos = 0 then
                                 // dot on first char of line, currently treat it like empty identifier to the left
                                 AtStartOfIdentifier(pos+1,""::current,throwAwayNext)                            
-                            elif not(pos>0 && (IsIdentifierPartCharacter(pos-1) || IsWhitespace(pos-1))) then
+                            elif not (pos > 0 && (IsIdentifierPartCharacter(pos-1) || IsWhitespace(pos-1))) then
                                 // it's not dots as part.of.a.long.ident, it's e.g. the range operator (..), or some other multi-char operator ending in dot
                                 if line.[pos-1] = ')' then
                                     // one very problematic case is someCall(args).Name
@@ -290,15 +290,13 @@ module internal QuickParse =
                                 AtStartOfIdentifier(pos+1,""::current,throwAwayNext)                            
                         else AtStartOfIdentifier(pos+1,[],throwAwayNext)
             let plid, residue = AtStartOfIdentifier(0,[],false)
-            let plid = (List.rev plid)
+            let plid = List.rev plid
             match plid with
-            | s::_rest when s.Length > 0 && Char.IsDigit(s.[0]) -> ([],"")  // "2.0" is not a longId (this might not be right for ``2.0`` but good enough for common case)
+            | s::_rest when s.Length > 0 && Char.IsDigit(s.[0]) -> defaultName  // "2.0" is not a longId (this might not be right for ``2.0`` but good enough for common case)
             | _ -> plid, residue
-
-
     
     let TokenNameEquals (tokenInfo : FSharpTokenInfo) token2 = 
-        String.Compare(tokenInfo .TokenName, token2, StringComparison.OrdinalIgnoreCase)=0  
+        String.Compare(tokenInfo .TokenName, token2, StringComparison.OrdinalIgnoreCase) = 0  
     
     // The prefix of the sequence of token names to look for in TestMemberOrOverrideDeclaration, in reverse order
     let private expected = [ [|"dot"|]; [|"ident"|]; [|"member"; "override"|] ]
diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj b/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj
index 5552ba95c81..f5a21f30519 100644
--- a/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj
+++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/ProjectSystem.fsproj
@@ -96,12 +96,16 @@
       $(FSharpSourcesRoot)\..\packages\Microsoft.VisualFSharp.Msbuild.15.0.1.0.1\lib\net45\Microsoft.Build.Tasks.Core.dll
     
     
-    
+    
+      $(VS150COMNTOOLS)\..\IDE\PublicAssemblies\Microsoft.VisualStudio.Shell.Framework.dll
+    
     
-        $(VS150COMNTOOLS)\..\IDE\Microsoft.VisualStudio.Shell.UI.Internal.dll
+        $(VS150COMNTOOLS)\..\IDE\Microsoft.VisualStudio.Shell.UI.Internal.dll
+        $(VS150COMNTOOLS)\..\..\IDE\Microsoft.VisualStudio.Shell.UI.Internal.dll
     
     
-        $(VS150COMNTOOLS)\..\IDE\PublicAssemblies\Microsoft.VisualStudio.Shell.Immutable.$(VisualStudioVersion).dll
+        $(VS150COMNTOOLS)\..\IDE\PublicAssemblies\Microsoft.VisualStudio.Shell.Immutable.$(VisualStudioVersion).dll
+        $(VS150COMNTOOLS)\..\..\IDE\PublicAssemblies\Microsoft.VisualStudio.Shell.Immutable.$(VisualStudioVersion).dll
     
     
     
diff --git a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs
index 2accf112c0c..c27f56a8d5b 100644
--- a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs
+++ b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs
@@ -110,7 +110,7 @@ module internal Util =
         /// returns Some(value) if key/value exists, None otherwise
         let tryReadHKCU<'t> subkey valueName =
             use key = Registry.CurrentUser.OpenSubKey(subkey)
-            if key = null then None else
+            if isNull key then None else
             match key.GetValue(valueName) with
             | :? 't as valTyped -> Some(valTyped)
             | _ -> None
diff --git a/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs b/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs
index 1ed409382ab..7448072159b 100644
--- a/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs
+++ b/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs
@@ -202,7 +202,7 @@ type internal FsiLanguageService() =
     member this.Sessions with set x = sessions <- Some x
     
     override this.GetLanguagePreferences() =
-        if preferences = null then
+        if isNull preferences then
             preferences <- new LanguagePreferences(this.Site,
                                                    typeof.GUID,
                                                    this.Name)
@@ -211,7 +211,7 @@ type internal FsiLanguageService() =
         preferences
         
     override this.GetScanner(buffer:IVsTextLines) =
-        if scanner = null then
+        if isNull scanner then
             scanner <- (new FsiScanner(buffer) :> IScanner)
         scanner
         
diff --git a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs
index 29e14418558..e4ed7127423 100644
--- a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs
+++ b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs
@@ -116,7 +116,7 @@ type internal FsiToolWindow() as this =
 
     // The IP sample called GetService() to obtain the LanguageService.
     let fsiLangService = provider.GetService(typeof) |> unbox : FsiLanguageService
-    do  if box fsiLangService = null then
+    do  if isNull(box fsiLangService) then
             // This would be unexpected, since this package provides the service.
             System.Windows.Forms.MessageBox.Show(VFSIstrings.SR.couldNotObtainFSharpLS()) |> ignore
             failwith "No FsiLanguageService"
@@ -443,7 +443,7 @@ type internal FsiToolWindow() as this =
         let fsiProcId = sessions.ProcessID
         let dte = provider.GetService(typeof) :?> DTE
 
-        if dte.Debugger.DebuggedProcesses = null || dte.Debugger.DebuggedProcesses.Count = 0 then
+        if isNull dte.Debugger.DebuggedProcesses || dte.Debugger.DebuggedProcesses.Count = 0 then
             FsiDebuggerState.NotRunning, None
         else
             let debuggedFsi =
@@ -478,7 +478,7 @@ type internal FsiToolWindow() as this =
             let fsiProcId = sessions.ProcessID
             let dte = provider.GetService(typeof) :?> DTE
             let fsiProc = 
-                if dte.Debugger.LocalProcesses = null then None else
+                if isNull dte.Debugger.LocalProcesses then None else
                 dte.Debugger.LocalProcesses
                 |> Seq.cast
                 |> Seq.tryFind (fun p -> p.ProcessID = fsiProcId)
@@ -684,9 +684,9 @@ type internal FsiToolWindow() as this =
             let originalFilter = textView.AddCommandFilter(this :> IOleCommandTarget) |> throwOnFailure1
             // Create a command service that will use the previous command target
             // as parent target and will route to it the commands that it can not handle.
-            if commandService = null then
+            if isNull commandService then
                 commandService <-             
-                    if (null = originalFilter) then                    
+                    if isNull originalFilter then                    
                         new OleMenuCommandService(this)            
                     else
                         new OleMenuCommandService(this, originalFilter)
diff --git a/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj b/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj
index baeff9875cb..51cdacf1bd8 100644
--- a/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj
+++ b/vsintegration/tests/Salsa/VisualFSharp.Salsa.fsproj
@@ -66,11 +66,14 @@
     
     
     
-		$(VS150COMNTOOLS)\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.CommonIDE.dll
-	
+        $(VS150COMNTOOLS)\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.CommonIDE.dll
+        $(VS150COMNTOOLS)\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.CommonIDE.dll
+        ..\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.CommonIDE.dll
+    
     
-		$(VS150COMNTOOLS)\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.Text.Internal.dll
-	
+        $(VS150COMNTOOLS)\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.Text.Internal.dll
+        $(VS150COMNTOOLS)\..\..\IDE\PrivateAssemblies\Microsoft.VisualStudio.Text.Internal.dll
+    
     
     
     
diff --git a/vsintegration/tests/Salsa/VsMocks.fs b/vsintegration/tests/Salsa/VsMocks.fs
index c2b953ca33d..dfc6196eaee 100644
--- a/vsintegration/tests/Salsa/VsMocks.fs
+++ b/vsintegration/tests/Salsa/VsMocks.fs
@@ -1599,26 +1599,26 @@ module internal VsActual =
     // Since the editor exports MEF components, we can use those components directly from unit tests without having to load too many heavy
     // VS assemblies.  Use editor MEF components directly from the VS product.
 
+    open System.IO
     open System.ComponentModel.Composition.Hosting
     open System.ComponentModel.Composition.Primitives
     open Microsoft.VisualStudio.Text
 
     let vsInstallDir =
+        // use the environment variable to find the VS installdir
 #if VS_VERSION_DEV12
-        let key = @"SOFTWARE\Microsoft\VisualStudio\12.0"
+        let vsvar = System.Environment.GetEnvironmentVariable("VS120COMNTOOLS")
 #endif
 #if VS_VERSION_DEV14
-        let key = @"SOFTWARE\Microsoft\VisualStudio\14.0"
+        let vsvar = System.Environment.GetEnvironmentVariable("VS140COMNTOOLS")
 #endif
 #if VS_VERSION_DEV15
-        let key = @"SOFTWARE\Microsoft\VisualStudio\15.0"
+        let vsvar = System.Environment.GetEnvironmentVariable("VS150COMNTOOLS")
 #endif
-        let hklm = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry32)
-        let rkey = hklm.OpenSubKey(key)
-        rkey.GetValue("InstallDir") :?> string
+        Path.Combine(vsvar, "..")
 
     let CreateEditorCatalog() =
-        let root = vsInstallDir + @"\CommonExtensions\Microsoft\Editor"
+        let root = Path.Combine(vsInstallDir, @"IDE\CommonExtensions\Microsoft\Editor")
         let CreateAssemblyCatalog(root, file) =
             let fullPath = System.IO.Path.Combine(root, file)
             if System.IO.File.Exists(fullPath) then
@@ -1627,13 +1627,14 @@ module internal VsActual =
                 failwith("could not find " + fullPath)
 
         // copy this private assembly next to unit tests, otherwise assembly loader cannot find it
-        let neededLocalAssem = vsInstallDir + @"\PrivateAssemblies\Microsoft.VisualStudio.Platform.VSEditor.Interop.dll"
+        let neededLocalAssem = Path.Combine(vsInstallDir, @"IDE\PrivateAssemblies\Microsoft.VisualStudio.Platform.VSEditor.Interop.dll")
+
 #if NUNIT_2
-        let curDir = System.IO.Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.Load("nunit.util").EscapedCodeBase)).LocalPath)
+        let curDir = Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.Load("nunit.util").EscapedCodeBase)).LocalPath)
 #else
-        let curDir = System.IO.Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.Load("nunit.framework").EscapedCodeBase)).LocalPath)
+        let curDir = Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.Load("nunit.framework").EscapedCodeBase)).LocalPath)
 #endif
-        let localCopy = System.IO.Path.Combine(curDir, System.IO.Path.GetFileName(neededLocalAssem))
+        let localCopy = Path.Combine(curDir, System.IO.Path.GetFileName(neededLocalAssem))
         System.IO.File.Copy(neededLocalAssem, localCopy, true)
         
         let list = new ResizeArray()
diff --git a/vsintegration/tests/Salsa/salsa.fs b/vsintegration/tests/Salsa/salsa.fs
index 1991baf6fd1..7c7cf698e5f 100644
--- a/vsintegration/tests/Salsa/salsa.fs
+++ b/vsintegration/tests/Salsa/salsa.fs
@@ -615,7 +615,7 @@ module internal Salsa =
                  versionFile,
                  otherFlags:string,
                  otherProjMisc:string,
-                 targetFrameworkVersion:string) =        
+                 targetFrameworkVersion:string) =
 
             // Determine which FSharp.targets file to use. If we use the installed
             // targets file then we check the registry for F#'s install path. Otherwise
@@ -633,7 +633,7 @@ module internal Salsa =
 //            The salsa layer does Configuration/Platform in a kind of hacky way
 //            Append "        Debug"
 //            Append "        AnyCPU"
-            Append "        bin\Debug\"  
+            Append "        bin\Debug\"
             if versionFile<>null then Append (sprintf "        %s" versionFile)
             if otherFlags<>null then Append (sprintf "        %s --resolutions" otherFlags)
             if targetFrameworkVersion<>null then
@@ -690,10 +690,10 @@ module internal Salsa =
                 
             Append "    "
             Append otherProjMisc
-            
-            Append (sprintf "    " targetsFileFolder)
+
+            let t = targetsFileFolder.TrimEnd([|'\\'|])
+            Append (sprintf "    " t)
             Append ""
-            
             sb.ToString()
 
         type MSBuildBehaviorHooks(useInstalledTargets) = 
@@ -710,10 +710,9 @@ module internal Salsa =
             interface ProjectBehaviorHooks with 
                 member x.CreateProjectHook (projectName, files, references, projectReferences, disabledWarnings, defines, versionFile, otherFlags, preImportXml, targetFrameworkVersion : string) =
                     if File.Exists(projectName) then File.Delete(projectName)
-
                     let text = CreateMsBuildProjectText useInstalledTargets (files, references, projectReferences, disabledWarnings, defines, versionFile, otherFlags, preImportXml, targetFrameworkVersion)
-                    File.AppendAllText(projectName,text+"\r\n")
-            
+                    File.WriteAllText(projectName,text+"\r\n")
+
                 member x.InitializeProjectHook op = openProject <- Some(op:?>IOpenProject)
                 member x.MakeHierarchyHook (projdir, fullname, projectname, configChangeNotifier, serviceProvider) = 
                     let projectSite = NewMSBuildProjectSite(Conf, Plat, fullname)
diff --git a/vsintegration/tests/unittests/Tests.LanguageService.Script.fs b/vsintegration/tests/unittests/Tests.LanguageService.Script.fs
index f44237cfd7a..eea41cd6031 100644
--- a/vsintegration/tests/unittests/Tests.LanguageService.Script.fs
+++ b/vsintegration/tests/unittests/Tests.LanguageService.Script.fs
@@ -559,35 +559,14 @@ type UsingMSBuild() as this =
 
     []
     []
-    // 'mscorcfg' is loaded from the GAC _and_ it is available on XP and above.
+    // 'CustomMarshalers' is loaded from the GAC _and_ it is available on XP and above.
     member public this.``Fsx.NoError.HashR.ResolveFromGAC``() =  
         let fileContent = """
             #light
-            #r "mscorcfg"
+            #r "CustomMarshalers"
             """
         this.VerifyFSXNoErrorList(fileContent)
 
-    []
-    []
-
-    // 'Microsoft.VisualStudio.QualityTools.Common.dll' is resolved via AssemblyFoldersEx over recent VS releases
-    member public this.``Fsx.NoError.HashR.ResolveFromAssemblyFoldersEx``() =  
-        let fileContent = """
-            #light
-            #r "Microsoft.VisualStudio.QualityTools.Common.dll"
-            """
-        this.VerifyFSXNoErrorList(fileContent)
-
-    []
-    []
-    // Can be any assembly that is in AssemblyFolders but not AssemblyFoldersEx
-    member public this.``Fsx.NoError.HashR.ResolveFromAssemblyFolders``() = 
-        let fileContent = """
-            #light
-            #r "Microsoft.SqlServer.SString"
-            """
-        this.VerifyFSXNoErrorList(fileContent) 
-
     []
     []
     member public this.``Fsx.NoError.HashR.ResolveFromFullyQualifiedPath``() =         
@@ -974,8 +953,8 @@ type UsingMSBuild() as this =
     []
     member public this.``Fsx.HashR_QuickInfo.ResolveFromGAC``() = 
         this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile
-            """#r "mscorcfg" """        // 'mscorcfg' is loaded from the GAC _and_ it is available on XP and above.
-            "#r \"mscor" "Global Assembly Cache"
+            """#r "CustomMarshalers" """        // 'mscorcfg' is loaded from the GAC _and_ it is available on XP and above.
+            "#r \"Custo" ".NET Framework"
 
     []
     []
diff --git a/vsintegration/tests/unittests/Tests.ProjectSystem.Miscellaneous.fs b/vsintegration/tests/unittests/Tests.ProjectSystem.Miscellaneous.fs
index 7a584aa56d1..07d48aa4ee1 100644
--- a/vsintegration/tests/unittests/Tests.ProjectSystem.Miscellaneous.fs
+++ b/vsintegration/tests/unittests/Tests.ProjectSystem.Miscellaneous.fs
@@ -516,8 +516,6 @@ type Miscellaneous() =
     member public this.TestBuildActions () =
         DoWithTempFile "Test.fsproj" (fun file ->
             let text = TheTests.FsprojTextWithProjectReferences(["foo.fs";"Bar.resx"; "Bar.de.resx"; "Xyz\Baz.ru.resx"; "Abc.resources"],[],[],"")
-            // Use toolsversion 2.0 project to have predictable default set of BuildActions
-            let text = text.Replace("ToolsVersion='4.0'", "ToolsVersion='2.0'") 
             
             File.AppendAllText(file, text)
             let dirName = Path.GetDirectoryName(file)
diff --git a/vsintegration/tests/unittests/Tests.ProjectSystem.References.fs b/vsintegration/tests/unittests/Tests.ProjectSystem.References.fs
index 9d0bcbeb1d9..9c8df4aea38 100644
--- a/vsintegration/tests/unittests/Tests.ProjectSystem.References.fs
+++ b/vsintegration/tests/unittests/Tests.ProjectSystem.References.fs
@@ -47,7 +47,7 @@ type References() =
     static let GetReferenceContainerNode(project : ProjectNode) =
         let l = new List()
         project.FindNodesOfType(l)
-        l.[0]  
+        l.[0]
 
 
     []
@@ -505,8 +505,10 @@ type References() =
             AssertContains contents newPropVal
         )
 
-            
-    []
+    // Disabled due to: https://github.com/Microsoft/visualfsharp/issues/1460
+    // On DEV 15 Preview 4 the VS IDE Test fails with :
+    //     System.InvalidOperationException : Operation is not valid due to the current state of the object.
+    // []     // Disabled due to: https://github.com/Microsoft/visualfsharp/issues/1460
     member public this.``AddReference.COM`` () = 
         DoWithTempFile "Test.fsproj" (fun projFile ->
             File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [], ""))
@@ -549,7 +551,7 @@ type References() =
             printfn "%O" fsproj
             let xn s = fsproj.Root.GetDefaultNamespace().GetName(s)
             let comReferencesXml = fsproj.Descendants(xn "COMReference") |> Seq.toList
-
+            
             Assert.AreEqual(1, comReferencesXml |> List.length)
 
             let comRefXml = comReferencesXml |> List.head