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
[