diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props
index a1ba7ab156d..515de9bbdc7 100644
--- a/FSharpBuild.Directory.Build.props
+++ b/FSharpBuild.Directory.Build.props
@@ -11,8 +11,7 @@
$(RepoRoot)src
$(ArtifactsDir)\SymStore
- $(ArtifactsDir)\Bootstrap
- $(ArtifactsDir)/fsc/Proto/netcoreapp2.1
+ $(ArtifactsDir)\Bootstrap
4.4.0
1182;0025;$(WarningsAsErrors)
@@ -96,10 +95,10 @@
- $(ProtoOutputPath)\Microsoft.FSharp.Targets
- $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.props
- $(ProtoOutputPath)\Microsoft.FSharp.NetSdk.targets
- $(ProtoOutputPath)\Microsoft.FSharp.Overrides.NetSdk.targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.NetSdk.props
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.NetSdk.targets
+ $(ProtoOutputPath)\fsc\Microsoft.FSharp.Overrides.NetSdk.targets
diff --git a/FSharpTests.Directory.Build.props b/FSharpTests.Directory.Build.props
index 7c00805dda5..8a7a832a43e 100644
--- a/FSharpTests.Directory.Build.props
+++ b/FSharpTests.Directory.Build.props
@@ -32,9 +32,9 @@
- <_FSharpBuildTargetFramework Condition="'$(FSharpTestCompilerVersion)' == 'net40'">net472
- <_FSharpBuildTargetFramework Condition="'$(FSharpTestCompilerVersion)' == 'coreclr'">netcoreapp2.1
- <_FSharpBuildBinPath>$(MSBuildThisFileDirectory)artifacts\bin\FSharp.Build\$(Configuration)\$(_FSharpBuildTargetFramework)
+ <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'!='Core'">net472
+ <_FSharpBuildTargetFramework Condition="'$(MSBuildRuntimeType)'=='Core'">netcoreapp2.1
+ <_FSharpBuildBinPath>$(MSBuildThisFileDirectory)artifacts\bin\fsc\$(Configuration)\$(_FSharpBuildTargetFramework)
$(_FSharpBuildBinPath)\FSharp.Build.dll
diff --git a/eng/Build.ps1 b/eng/Build.ps1
index 034ea1aaa6e..04bee5a40d8 100644
--- a/eng/Build.ps1
+++ b/eng/Build.ps1
@@ -65,6 +65,7 @@ function Print-Usage() {
Write-Host ""
Write-Host "Actions:"
Write-Host " -restore Restore packages (short: -r)"
+ Write-Host " -norestore Don't restore packages"
Write-Host " -build Build main solution (short: -b)"
Write-Host " -rebuild Rebuild main solution"
Write-Host " -pack Build NuGet packages, VS insertion manifests and installer"
@@ -100,6 +101,7 @@ function Process-Arguments() {
Print-Usage
exit 0
}
+ $script:nodeReuse = $False;
if ($testAll) {
$script:testDesktop = $True
@@ -126,7 +128,7 @@ function Process-Arguments() {
}
function Update-Arguments() {
- if (-Not (Test-Path "$ArtifactsDir\Bootstrap\fsc.exe")) {
+ if (-Not (Test-Path "$ArtifactsDir\Bootstrap\fsc\fsc.exe")) {
$script:bootstrap = $True
}
}
@@ -160,10 +162,10 @@ function BuildSolution() {
/p:Publish=$publish `
/p:ContinuousIntegrationBuild=$ci `
/p:OfficialBuildId=$officialBuildId `
- /p:BootstrapBuildPath=$bootstrapDir `
/p:QuietRestore=$quietRestore `
/p:QuietRestoreBinaryLog=$binaryLog `
/p:TestTargetFrameworks=$testTargetFrameworks `
+ /v:$verbosity `
$suppressExtensionDeployment `
@properties
}
@@ -194,7 +196,7 @@ function UpdatePath() {
}
function VerifyAssemblyVersions() {
- $fsiPath = Join-Path $ArtifactsDir "bin\fsi\Proto\net472\fsi.exe"
+ $fsiPath = Join-Path $ArtifactsDir "bin\fsi\Proto\net472\publish\fsi.exe"
# Only verify versions on CI or official build
if ($ci -or $official) {
diff --git a/eng/build-utils.ps1 b/eng/build-utils.ps1
index d1e5dd85d55..f85a9007296 100644
--- a/eng/build-utils.ps1
+++ b/eng/build-utils.ps1
@@ -178,7 +178,7 @@ function Get-PackageDir([string]$name, [string]$version = "") {
return $p
}
-function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration) {
+function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration, [string]$verbosity = $script:verbosity) {
# Because we override the C#/VB toolset to build against our LKG package, it is important
# that we do not reuse MSBuild nodes from other jobs/builds on the machine. Otherwise,
# we'll run into issues such as https://github.com/dotnet/roslyn/issues/6211.
@@ -190,9 +190,9 @@ function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]
}
if ($summary) {
- $args += " /consoleloggerparameters:Verbosity=minimal;summary"
+ $args += " /consoleloggerparameters:Verbosity=$verbosity;summary"
} else {
- $args += " /consoleloggerparameters:Verbosity=minimal"
+ $args += " /consoleloggerparameters:Verbosity=$verbosity"
}
if ($parallel) {
@@ -216,10 +216,6 @@ function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]
$args += " /p:ContinuousIntegrationBuild=true"
}
- if ($bootstrapDir -ne "") {
- $args += " /p:BootstrapBuildPath=$bootstrapDir"
- }
-
$args += " $buildArgs"
$args += " $projectFilePath"
$args += " $properties"
@@ -241,15 +237,15 @@ function Make-BootstrapBuild() {
Create-Directory $dir
# prepare FsLex and Fsyacc
- Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Build" -logFileName "BuildTools" -configuration $bootstrapConfiguration
- Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\*" -Destination $dir
- Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\*" -Destination $dir
+ Run-MSBuild "$RepoRoot\src\buildtools\buildtools.proj" "/restore /t:Publish" -logFileName "BuildTools" -configuration $bootstrapConfiguration -verbosity $verbosity
+ Copy-Item "$ArtifactsDir\bin\fslex\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fslex" -Force -Recurse
+ Copy-Item "$ArtifactsDir\bin\fsyacc\$bootstrapConfiguration\netcoreapp2.1\publish" -Destination "$dir\fsyacc" -Force -Recurse
# prepare compiler
$projectPath = "$RepoRoot\proto.proj"
- Run-MSBuild $projectPath "/restore /t:Build" -logFileName "Bootstrap" -configuration $bootstrapConfiguration
- Copy-Item "$ArtifactsDir\bin\fsc\$bootstrapConfiguration\$bootstrapTfm\*" -Destination $dir
- Copy-Item "$ArtifactsDir\bin\fsi\$bootstrapConfiguration\$bootstrapTfm\*" -Destination $dir
+ Run-MSBuild $projectPath "/restore /t:Publish" -logFileName "Bootstrap" -configuration $bootstrapConfiguration -verbosity $verbosity
+ Copy-Item "$ArtifactsDir\bin\fsc\$bootstrapConfiguration\$bootstrapTfm\publish" -Destination "$dir\fsc" -Force -Recurse
+ Copy-Item "$ArtifactsDir\bin\fsi\$bootstrapConfiguration\$bootstrapTfm\publish" -Destination "$dir\fsi" -Force -Recurse
return $dir
}
diff --git a/eng/build.sh b/eng/build.sh
index 58b283ff39b..8a236373f37 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -13,7 +13,9 @@ usage()
echo " --binaryLog Create MSBuild binary log (short: -bl)"
echo ""
echo "Actions:"
+ echo " --bootstrap Force the build of the bootstrap compiler"
echo " --restore Restore projects required to build (short: -r)"
+ echo " --norestore Don't restore projects required to build"
echo " --build Build all projects (short: -b)"
echo " --rebuild Rebuild all projects"
echo " --pack Build nuget packages"
@@ -54,6 +56,7 @@ test_core_clr=false
configuration="Debug"
verbosity='minimal'
binary_log=false
+force_bootstrap=false
ci=false
skip_analyzers=false
prepare_machine=false
@@ -88,6 +91,9 @@ while [[ $# > 0 ]]; do
--binarylog|-bl)
binary_log=true
;;
+ --bootstrap)
+ force_bootstrap=true
+ ;;
--restore|-r)
restore=true
;;
@@ -205,21 +211,40 @@ function BuildSolution {
quiet_restore=true
fi
+ # Node reuse fails because multiple different versions of FSharp.Build.dll get loaded into MSBuild nodes
+ node_reuse=false
+
# build bootstrap tools
bootstrap_config=Proto
- MSBuild "$repo_root/src/buildtools/buildtools.proj" \
- /restore \
- /p:Configuration=$bootstrap_config \
- /t:Build
-
bootstrap_dir=$artifacts_dir/Bootstrap
- mkdir -p "$bootstrap_dir"
- cp $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp2.1/* $bootstrap_dir
- cp $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp2.1/* $bootstrap_dir
+ if [[ "$force_bootstrap" == true ]]; then
+ rm -fr $bootstrap_dir
+ fi
+ if [ ! -f "$bootstrap_dir/fslex.dll" ]; then
+ MSBuild "$repo_root/src/buildtools/buildtools.proj" \
+ /restore \
+ /v:$verbosity \
+ /p:Configuration=$bootstrap_config \
+ /t:Publish
+
+ mkdir -p "$bootstrap_dir"
+ cp -pr $artifacts_dir/bin/fslex/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fslex
+ cp -pr $artifacts_dir/bin/fsyacc/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fsyacc
+ fi
+ if [ ! -f "$bootstrap_dir/fsc.exe" ]; then
+ MSBuild "$repo_root/proto.proj" \
+ /restore \
+ /v:$verbosity \
+ /p:Configuration=$bootstrap_config \
+ /t:Publish
+
+ cp -pr $artifacts_dir/bin/fsc/$bootstrap_config/netcoreapp2.1/publish $bootstrap_dir/fsc
+ fi
# do real build
MSBuild $toolset_build_proj \
$bl \
+ /v:$verbosity \
/p:Configuration=$configuration \
/p:Projects="$projects" \
/p:RepoRoot="$repo_root" \
diff --git a/fcs/Directory.Build.props b/fcs/Directory.Build.props
index 596b06c0716..4c8aac0a5b6 100644
--- a/fcs/Directory.Build.props
+++ b/fcs/Directory.Build.props
@@ -20,9 +20,4 @@
$(ArtifactsObjDir)\fcs
true
-
-
-
- $(ArtifactsBinDir)\FSharp.Build\Proto\net472
-
diff --git a/proto.proj b/proto.proj
index 84103f6fdf8..b0ee288977f 100644
--- a/proto.proj
+++ b/proto.proj
@@ -28,6 +28,10 @@
+
+
+
+
diff --git a/src/buildtools/buildtools.proj b/src/buildtools/buildtools.proj
index 593f086dd07..630bb678561 100644
--- a/src/buildtools/buildtools.proj
+++ b/src/buildtools/buildtools.proj
@@ -2,7 +2,8 @@
Debug
-
+ true
+
@@ -10,23 +11,23 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/src/buildtools/buildtools.targets b/src/buildtools/buildtools.targets
index 303ab00825d..185fd4d0599 100644
--- a/src/buildtools/buildtools.targets
+++ b/src/buildtools/buildtools.targets
@@ -20,7 +20,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fslex.dll
+ $(ArtifactsDir)\Bootstrap\fslex\fslex.dll
@@ -43,7 +43,7 @@
BeforeTargets="CoreCompile">
- $(ArtifactsDir)\Bootstrap\fsyacc.dll
+ $(ArtifactsDir)\Bootstrap\fsyacc\fsyacc.dll
diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs
index a372de41e11..30c22a867c8 100644
--- a/src/fsharp/ConstraintSolver.fs
+++ b/src/fsharp/ConstraintSolver.fs
@@ -2752,112 +2752,29 @@ let AddCxTypeIsDelegate denv css m trace ty aty bty =
(fun res -> ErrorD (ErrorFromAddingConstraint(denv, res, m)))
|> RaiseOperationResult
-let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo: TraitConstraintInfo) argExprs = trackErrors {
- let css =
- { g = g
- amap = amap
- TcVal = tcVal
- ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
- InfoReader = new InfoReader(g, amap) }
-
+let CreateCodegenState tcVal g amap =
+ { g = g
+ amap = amap
+ TcVal = tcVal
+ ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
+ InfoReader = new InfoReader(g, amap) }
+
+let CodegenWitnessForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = trackErrors {
+ let css = CreateCodegenState tcVal g amap
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
let! _res = SolveMemberConstraint csenv true true 0 m NoTrace traitInfo
- let sln =
- match traitInfo.Solution with
- | None -> Choice5Of5()
- | Some sln ->
- match sln with
- | ILMethSln(origTy, extOpt, mref, minst) ->
- let metadataTy = convertToTypeWithMetadataIfPossible g origTy
- let tcref = tcrefOfAppTy g metadataTy
- let mdef = IL.resolveILMethodRef tcref.ILTyconRawMetadata mref
- let ilMethInfo =
- match extOpt with
- | None -> MethInfo.CreateILMeth(amap, m, origTy, mdef)
- | Some ilActualTypeRef ->
- let actualTyconRef = Import.ImportILTypeRef amap m ilActualTypeRef
- MethInfo.CreateILExtensionMeth(amap, m, origTy, actualTyconRef, None, mdef)
- Choice1Of5 (ilMethInfo, minst)
- | FSMethSln(ty, vref, minst) ->
- Choice1Of5 (FSMeth(g, ty, vref, None), minst)
- | FSRecdFieldSln(tinst, rfref, isSetProp) ->
- Choice2Of5 (tinst, rfref, isSetProp)
- | FSAnonRecdFieldSln(anonInfo, tinst, i) ->
- Choice3Of5 (anonInfo, tinst, i)
- | BuiltInSln ->
- Choice5Of5 ()
- | ClosedExprSln expr ->
- Choice4Of5 expr
- return!
- match sln with
- | Choice1Of5(minfo, methArgTys) ->
- let argExprs =
- // FIX for #421894 - typechecker assumes that coercion can be applied for the trait calls arguments but codegen doesn't emit coercion operations
- // result - generation of non-verifyable code
- // fix - apply coercion for the arguments (excluding 'receiver' argument in instance calls)
-
- // flatten list of argument types (looks like trait calls with curried arguments are not supported so we can just convert argument list in straighforward way)
- let argTypes =
- minfo.GetParamTypes(amap, m, methArgTys)
- |> List.concat
- // do not apply coercion to the 'receiver' argument
- let receiverArgOpt, argExprs =
- if minfo.IsInstance then
- match argExprs with
- | h :: t -> Some h, t
- | argExprs -> None, argExprs
- else None, argExprs
- let convertedArgs = (argExprs, argTypes) ||> List.map2 (fun expr expectedTy -> mkCoerceIfNeeded g expectedTy (tyOfExpr g expr) expr)
- match receiverArgOpt with
- | Some r -> r :: convertedArgs
- | None -> convertedArgs
-
- // Fix bug 1281: If we resolve to an instance method on a struct and we haven't yet taken
- // the address of the object then go do that
- if minfo.IsStruct && minfo.IsInstance && (match argExprs with [] -> false | h :: _ -> not (isByrefTy g (tyOfExpr g h))) then
- let h, t = List.headAndTail argExprs
- let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false PossiblyMutates h None m
- ResultD (Some (wrap (Expr.Op (TOp.TraitCall (traitInfo), [], (h' :: t), m))))
- else
- ResultD (Some (MakeMethInfoCall amap m minfo methArgTys argExprs ))
-
- | Choice2Of5 (tinst, rfref, isSet) ->
- let res =
- match isSet, rfref.RecdField.IsStatic, argExprs.Length with
- | true, true, 1 ->
- Some (mkStaticRecdFieldSet (rfref, tinst, argExprs.[0], m))
- | true, false, 2 ->
- // If we resolve to an instance field on a struct and we haven't yet taken
- // the address of the object then go do that
- if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then
- let h = List.head argExprs
- let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false DefinitelyMutates h None m
- Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m)))
- else
- Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m))
- | false, true, 0 ->
- Some (mkStaticRecdFieldGet (rfref, tinst, m))
- | false, false, 1 ->
- if rfref.Tycon.IsStructOrEnumTycon && isByrefTy g (tyOfExpr g argExprs.[0]) then
- Some (mkRecdFieldGetViaExprAddr (argExprs.[0], rfref, tinst, m))
- else
- Some (mkRecdFieldGet g (argExprs.[0], rfref, tinst, m))
- | _ -> None
- ResultD res
- | Choice3Of5 (anonInfo, tinst, i) ->
- let res =
- let tupInfo = anonInfo.TupInfo
- if evalTupInfoIsStruct tupInfo && isByrefTy g (tyOfExpr g argExprs.[0]) then
- Some (mkAnonRecdFieldGetViaExprAddr (anonInfo, argExprs.[0], tinst, i, m))
- else
- Some (mkAnonRecdFieldGet g (anonInfo, argExprs.[0], tinst, i, m))
- ResultD res
-
- | Choice4Of5 expr -> ResultD (Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m)))
-
- | Choice5Of5 () -> ResultD None
+ let sln = GenWitnessExpr amap g m traitInfo argExprs
+ return sln
}
+let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = trackErrors {
+ let css = CreateCodegenState tcVal g amap
+ let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
+ let ftps, _renaming, tinst = FreshenTypeInst m typars
+ let cxs = GetTraitConstraintInfosOfTypars g ftps
+ do! SolveTypeEqualsTypeEqns csenv 0 m NoTrace None tinst tyargs
+ return MethodCalls.GenNonGenericWitnessArgs amap g m cxs
+ }
let ChooseTyparSolutionAndSolve css denv tp =
let g = css.g
diff --git a/src/fsharp/ConstraintSolver.fsi b/src/fsharp/ConstraintSolver.fsi
index 4626c736bdb..43e96302774 100644
--- a/src/fsharp/ConstraintSolver.fsi
+++ b/src/fsharp/ConstraintSolver.fsi
@@ -140,7 +140,9 @@ val AddCxTypeIsUnmanaged : DisplayEnv -> ConstraintSolverSt
val AddCxTypeIsEnum : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> unit
val AddCxTypeIsDelegate : DisplayEnv -> ConstraintSolverState -> range -> OptionalTrace -> TType -> TType -> TType -> unit
-val CodegenWitnessThatTypeSupportsTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult
+val CodegenWitnessForTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult
+
+val CodegenWitnessesForTyparInst : TcValF -> TcGlobals -> ImportMap -> range -> Typars -> TType list -> OperationResult list>
val ChooseTyparSolutionAndSolve : ConstraintSolverState -> DisplayEnv -> Typar -> unit
diff --git a/src/fsharp/FSharp.Build/FSharp.Build.fsproj b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
index 0dad55058b0..17170e751d0 100644
--- a/src/fsharp/FSharp.Build/FSharp.Build.fsproj
+++ b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
@@ -32,6 +32,7 @@
+
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
index 6307f17baf3..5bc96e7ed2d 100644
--- a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
@@ -27,6 +27,7 @@
+
diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
index 9fef6d27589..b7ba0a23cd8 100644
--- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
+++ b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj
@@ -674,6 +674,7 @@
+
diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
index 75a7353bb96..8bd027a0623 100644
--- a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
+++ b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
@@ -20,6 +20,7 @@
+
diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs
index 68e8fde5fe6..da355578e97 100644
--- a/src/fsharp/FSharp.Core/Linq.fs
+++ b/src/fsharp/FSharp.Core/Linq.fs
@@ -249,119 +249,128 @@ module LeafExpressionConverter =
let minfo = (System.Reflection.MethodInfo.GetMethodFromHandle mhandle) :?> MethodInfo
SpecificCallToMethodInfo minfo
- let (|GenericEqualityQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.GenericEquality x y))
- let (|EqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x = y))
- let (|GreaterQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x > y))
- let (|GreaterEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x >= y))
- let (|LessQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x < y))
- let (|LessEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x <= y))
- let (|NotEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x <> y))
-
- let (|StaticEqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int, y:int) -> NonStructuralComparison.(=) x y))
- let (|StaticGreaterQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int, y:int) -> NonStructuralComparison.(>) x y))
- let (|StaticGreaterEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int, y:int) -> NonStructuralComparison.(>=) x y))
- let (|StaticLessQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int, y:int) -> NonStructuralComparison.(<) x y))
- let (|StaticLessEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int, y:int) -> NonStructuralComparison.(<=) x y))
- let (|StaticNotEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int, y:int) -> NonStructuralComparison.(<>) x y))
-
- let (|NullableEqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?= ) x y))
- let (|NullableNotEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?<> ) x y))
- let (|NullableGreaterQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?> ) x y))
- let (|NullableGreaterEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?>= ) x y))
- let (|NullableLessQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?< ) x y))
- let (|NullableLessEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?<= ) x y))
-
- let (|NullableEqualsNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?=? ) x y))
- let (|NullableNotEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?<>? ) x y))
- let (|NullableGreaterNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?>? ) x y))
- let (|NullableGreaterEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?>=? ) x y))
- let (|NullableLessNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ? ) x y))
- let (|NullableLessEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?<=? ) x y))
-
- let (|EqualsNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( =? ) x y))
- let (|NotEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( <>? ) x y))
- let (|GreaterNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( >? ) x y))
- let (|GreaterEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( >=? ) x y))
- let (|LessNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ) x y))
- let (|LessEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( <=? ) x y))
-
- let (|MakeDecimalQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (a1, a2, a3, a4, a5) -> LanguagePrimitives.IntrinsicFunctions.MakeDecimal a1 a2 a3 a4 a5))
-
- let (|NullablePlusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?+ ) x y))
- let (|NullablePlusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?+? ) x y))
- let (|PlusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( +? ) x y))
-
- let (|NullableMinusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?- ) x y))
- let (|NullableMinusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?-? ) x y))
- let (|MinusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( -? ) x y))
-
- let (|NullableMultiplyQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?* ) x y))
- let (|NullableMultiplyNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?*? ) x y))
- let (|MultiplyNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( *? ) x y))
-
- let (|NullableDivideQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?/ ) x y))
- let (|NullableDivideNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?/? ) x y))
- let (|DivideNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( /? ) x y))
-
- let (|NullableModuloQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?% ) x y))
- let (|NullableModuloNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( ?%? ) x y))
- let (|ModuloNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> NullableOperators.( %? ) x y))
-
- let (|NotQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> not x))
- let (|NegQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int) -> -x))
- let (|PlusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x + y))
- let (|DivideQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x / y))
- let (|MinusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x - y))
- let (|MultiplyQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x * y))
- let (|ModuloQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x % y))
- let (|ShiftLeftQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x <<< y))
- let (|ShiftRightQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x >>> y))
- let (|BitwiseAndQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x &&& y))
- let (|BitwiseOrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x ||| y))
- let (|BitwiseXorQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x ^^^ y))
- let (|BitwiseNotQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> ~~~ x))
- let (|CheckedNeg|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.( ~-) x))
- let (|CheckedPlusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> Checked.( + ) x y))
- let (|CheckedMinusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> Checked.( - ) x y))
- let (|CheckedMultiplyQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> Checked.( * ) x y))
-
- let (|ConvCharQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.char x))
- let (|ConvDecimalQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.decimal x))
- let (|ConvFloatQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.float x))
- let (|ConvFloat32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.float32 x))
- let (|ConvSByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.sbyte x))
-
- let (|ConvInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int16 x))
- let (|ConvInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int32 x))
- let (|ConvIntQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int x))
- let (|ConvInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int64 x))
- let (|ConvByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.byte x))
- let (|ConvUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.uint16 x))
- let (|ConvUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.uint32 x))
- let (|ConvUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.uint64 x))
-
- let (|ConvInt8Q|_|) = SpecificCallToMethodInfo (typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators").GetMethod("ToSByte"))
- let (|ConvUInt8Q|_|) = SpecificCallToMethodInfo (typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators").GetMethod("ToByte"))
- let (|ConvDoubleQ|_|) = SpecificCallToMethodInfo (typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators").GetMethod("ToDouble"))
- let (|ConvSingleQ|_|) = SpecificCallToMethodInfo (typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators").GetMethod("ToSingle"))
-
- let (|ConvNullableCharQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.char x))
- let (|ConvNullableDecimalQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.decimal x))
- let (|ConvNullableFloatQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.float x))
- let (|ConvNullableDoubleQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.double x))
- let (|ConvNullableFloat32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.float32 x))
- let (|ConvNullableSingleQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.single x))
- let (|ConvNullableSByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.sbyte x))
- let (|ConvNullableInt8Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int8 x))
- let (|ConvNullableInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int16 x))
- let (|ConvNullableInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int32 x))
- let (|ConvNullableIntQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int x))
- let (|ConvNullableInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int64 x))
- let (|ConvNullableByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.byte x))
- let (|ConvNullableUInt8Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint8 x))
- let (|ConvNullableUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint16 x))
- let (|ConvNullableUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint32 x))
- let (|ConvNullableUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint64 x))
+ let (|GenericEqualityQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> LanguagePrimitives.GenericEquality x y))
+ let (|EqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x = y))
+ let (|GreaterQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x > y))
+ let (|GreaterEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x >= y))
+ let (|LessQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x < y))
+ let (|LessEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x <= y))
+ let (|NotEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x <> y))
+
+ let (|StaticEqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int,y:int) -> NonStructuralComparison.(=) x y))
+ let (|StaticGreaterQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int,y:int) -> NonStructuralComparison.(>) x y))
+ let (|StaticGreaterEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int,y:int) -> NonStructuralComparison.(>=) x y))
+ let (|StaticLessQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int,y:int) -> NonStructuralComparison.(<) x y))
+ let (|StaticLessEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int,y:int) -> NonStructuralComparison.(<=) x y))
+ let (|StaticNotEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int,y:int) -> NonStructuralComparison.(<>) x y))
+
+ let (|NullableEqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?= ) x y))
+ let (|NullableNotEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?<> ) x y))
+ let (|NullableGreaterQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?> ) x y))
+ let (|NullableGreaterEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?>= ) x y))
+ let (|NullableLessQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?< ) x y))
+ let (|NullableLessEqQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?<= ) x y))
+
+ let (|NullableEqualsNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?=? ) x y))
+ let (|NullableNotEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?<>? ) x y))
+ let (|NullableGreaterNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?>? ) x y))
+ let (|NullableGreaterEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?>=? ) x y))
+ let (|NullableLessNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ? ) x y))
+ let (|NullableLessEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?<=? ) x y))
+
+ let (|EqualsNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( =? ) x y))
+ let (|NotEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( <>? ) x y))
+ let (|GreaterNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( >? ) x y))
+ let (|GreaterEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( >=? ) x y))
+ let (|LessNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ) x y))
+ let (|LessEqNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( <=? ) x y))
+
+ let (|MakeDecimalQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (a1,a2,a3,a4,a5) -> LanguagePrimitives.IntrinsicFunctions.MakeDecimal a1 a2 a3 a4 a5))
+
+
+ let (|NullablePlusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?+ ) x y))
+ let (|NullablePlusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?+? ) x y))
+ let (|PlusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( +? ) x y))
+
+ let (|NullableMinusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?- ) x y))
+ let (|NullableMinusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?-? ) x y))
+ let (|MinusNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( -? ) x y))
+
+ let (|NullableMultiplyQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?* ) x y))
+ let (|NullableMultiplyNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?*? ) x y))
+ let (|MultiplyNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( *? ) x y))
+
+ let (|NullableDivideQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?/ ) x y))
+ let (|NullableDivideNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?/? ) x y))
+ let (|DivideNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( /? ) x y))
+
+ let (|NullableModuloQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?% ) x y))
+ let (|NullableModuloNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( ?%? ) x y))
+ let (|ModuloNullableQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> NullableOperators.( %? ) x y))
+
+ let (|NotQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> not x))
+ let (|NegQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x:int) -> -x))
+ let (|PlusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x + y))
+ let (|DivideQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x / y))
+ let (|MinusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x - y))
+ let (|MultiplyQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x * y))
+ let (|ModuloQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x % y))
+ let (|ShiftLeftQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x <<< y))
+ let (|ShiftRightQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x >>> y))
+ let (|BitwiseAndQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x &&& y))
+ let (|BitwiseOrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x ||| y))
+ let (|BitwiseXorQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> x ^^^ y))
+ let (|BitwiseNotQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> ~~~ x))
+ let (|CheckedNeg|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.( ~-) x))
+ let (|CheckedPlusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> Checked.( + ) x y))
+ let (|CheckedMinusQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> Checked.( - ) x y))
+ let (|CheckedMultiplyQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x,y) -> Checked.( * ) x y))
+
+ let (|ConvCharQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.char x))
+ let (|ConvDecimalQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.decimal x))
+ let (|ConvFloatQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.float x))
+ let (|ConvFloat32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.float32 x))
+ let (|ConvSByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.sbyte x))
+
+
+ let (|ConvInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int16 x))
+ let (|ConvInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int32 x))
+ let (|ConvIntQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int x))
+ let (|ConvInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.int64 x))
+ let (|ConvByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.byte x))
+ let (|ConvUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.uint16 x))
+ let (|ConvUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.uint32 x))
+ let (|ConvUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.uint64 x))
+
+ /// Get the version of the method that does not carry witnesses
+ let nonWitnessMethodInfo nm (ms: MethodInfo[]) =
+ ms |> Array.pick (fun m -> if m.Name = nm && m.GetParameters().Length = 1 then Some m else None)
+
+ let ExtraOperatorsTy = typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators")
+ let ExtraOperatorsCheckedTy = typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked")
+
+ let (|ConvInt8Q|_|) = SpecificCallToMethodInfo (ExtraOperatorsTy.GetMethods() |> nonWitnessMethodInfo "ToSByte")
+ let (|ConvUInt8Q|_|) = SpecificCallToMethodInfo (ExtraOperatorsTy.GetMethods() |> nonWitnessMethodInfo "ToByte")
+ let (|ConvDoubleQ|_|) = SpecificCallToMethodInfo (ExtraOperatorsTy.GetMethods() |> nonWitnessMethodInfo "ToDouble")
+ let (|ConvSingleQ|_|) = SpecificCallToMethodInfo (ExtraOperatorsTy.GetMethods() |> nonWitnessMethodInfo "ToSingle")
+
+ let (|ConvNullableCharQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.char x))
+ let (|ConvNullableDecimalQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.decimal x))
+ let (|ConvNullableFloatQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.float x))
+ let (|ConvNullableDoubleQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.double x))
+ let (|ConvNullableFloat32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.float32 x))
+ let (|ConvNullableSingleQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.single x))
+ let (|ConvNullableSByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.sbyte x))
+ let (|ConvNullableInt8Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int8 x))
+ let (|ConvNullableInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int16 x))
+ let (|ConvNullableInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int32 x))
+ let (|ConvNullableIntQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int x))
+ let (|ConvNullableInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.int64 x))
+ let (|ConvNullableByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.byte x))
+ let (|ConvNullableUInt8Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint8 x))
+ let (|ConvNullableUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint16 x))
+ let (|ConvNullableUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint32 x))
+ let (|ConvNullableUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.uint64 x))
// LINQ expressions can't do native integer operations, so we don't convert these
//let (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.nativeint x))
//let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.unativeint x))
@@ -371,8 +380,8 @@ module LeafExpressionConverter =
let (|TypeTestGeneric|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric x))
let (|CheckedConvCharQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.char x))
let (|CheckedConvSByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.sbyte x))
- let (|CheckedConvInt8Q|_|) = SpecificCallToMethodInfo (typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked").GetMethod("ToSByte"))
- let (|CheckedConvUInt8Q|_|) = SpecificCallToMethodInfo (typeof.Assembly.GetType("Microsoft.FSharp.Core.ExtraTopLevelOperators+Checked").GetMethod("ToByte"))
+ let (|CheckedConvInt8Q|_|) = SpecificCallToMethodInfo (ExtraOperatorsCheckedTy.GetMethods() |> nonWitnessMethodInfo "ToSByte")
+ let (|CheckedConvUInt8Q|_|) = SpecificCallToMethodInfo (ExtraOperatorsCheckedTy.GetMethods() |> nonWitnessMethodInfo "ToByte")
let (|CheckedConvInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.int16 x))
let (|CheckedConvInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.int32 x))
let (|CheckedConvInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.int64 x))
@@ -508,94 +517,92 @@ module LeafExpressionConverter =
let argsR = ConvExprsToLinq env args
let props = ctor.DeclaringType.GetProperties()
Expression.New(ctor, argsR, [| for p in props -> (p :> MemberInfo) |]) |> asExpr
-
-
- // Do the same thing as C# compiler for string addition
- | PlusQ (_, [ty1; ty2; ty3], [x1; x2]) when (ty1 = typeof) && (ty2 = typeof) && (ty3 = typeof) ->
+
+ // Do the same thing as C# compiler for string addition
+ | PlusQ (_, [ty1;ty2;ty3],[x1;x2]) when (ty1 = typeof) && (ty2 = typeof) && (ty3 = typeof) ->
Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr
- | GenericEqualityQ (_, _, [x1; x2])
- | EqualsQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Equal
- | NotEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.NotEqual
- | GreaterQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThan
- | GreaterEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThanOrEqual
- | LessQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThan
- | LessEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThanOrEqual
- | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr
-
- | StaticEqualsQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Equal
- | StaticNotEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.NotEqual
- | StaticGreaterQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThan
- | StaticGreaterEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThanOrEqual
- | StaticLessQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThan
- | StaticLessEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThanOrEqual
-
- | NullableEqualsQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Equal
- | NullableNotEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.NotEqual
- | NullableGreaterQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.GreaterThan
- | NullableGreaterEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.GreaterThanOrEqual
- | NullableLessQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.LessThan
- | NullableLessEqQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.LessThanOrEqual
-
- | EqualsNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Equal
- | NotEqNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.NotEqual
- | GreaterNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.GreaterThan
- | GreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.GreaterThanOrEqual
- | LessNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.LessThan
- | LessEqNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.LessThanOrEqual
-
- | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Equal
- | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.NotEqual
- | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThan
- | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.GreaterThanOrEqual
- | NullableLessNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThan
- | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LessThanOrEqual
-
+ | GenericEqualityQ _
+ | EqualsQ _ -> transBinOp env false args false Expression.Equal
+ | NotEqQ _ -> transBinOp env false args false Expression.NotEqual
+ | GreaterQ _ -> transBinOp env false args false Expression.GreaterThan
+ | GreaterEqQ _ -> transBinOp env false args false Expression.GreaterThanOrEqual
+ | LessQ _ -> transBinOp env false args false Expression.LessThan
+ | LessEqQ _ -> transBinOp env false args false Expression.LessThanOrEqual
+ | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr
+
+ | StaticEqualsQ _ -> transBinOp env false args false Expression.Equal
+ | StaticNotEqQ _ -> transBinOp env false args false Expression.NotEqual
+ | StaticGreaterQ _ -> transBinOp env false args false Expression.GreaterThan
+ | StaticGreaterEqQ _ -> transBinOp env false args false Expression.GreaterThanOrEqual
+ | StaticLessQ _ -> transBinOp env false args false Expression.LessThan
+ | StaticLessEqQ _ -> transBinOp env false args false Expression.LessThanOrEqual
+
+ | NullableEqualsQ _ -> transBinOp env false args true Expression.Equal
+ | NullableNotEqQ _ -> transBinOp env false args true Expression.NotEqual
+ | NullableGreaterQ _ -> transBinOp env false args true Expression.GreaterThan
+ | NullableGreaterEqQ _ -> transBinOp env false args true Expression.GreaterThanOrEqual
+ | NullableLessQ _ -> transBinOp env false args true Expression.LessThan
+ | NullableLessEqQ _ -> transBinOp env false args true Expression.LessThanOrEqual
+
+ | EqualsNullableQ _ -> transBinOp env true args false Expression.Equal
+ | NotEqNullableQ _ -> transBinOp env true args false Expression.NotEqual
+ | GreaterNullableQ _ -> transBinOp env true args false Expression.GreaterThan
+ | GreaterEqNullableQ _ -> transBinOp env true args false Expression.GreaterThanOrEqual
+ | LessNullableQ _ -> transBinOp env true args false Expression.LessThan
+ | LessEqNullableQ _ -> transBinOp env true args false Expression.LessThanOrEqual
+
+ | NullableEqualsNullableQ _ -> transBinOp env false args false Expression.Equal
+ | NullableNotEqNullableQ _ -> transBinOp env false args false Expression.NotEqual
+ | NullableGreaterNullableQ _ -> transBinOp env false args false Expression.GreaterThan
+ | NullableGreaterEqNullableQ _ -> transBinOp env false args false Expression.GreaterThanOrEqual
+ | NullableLessNullableQ _ -> transBinOp env false args false Expression.LessThan
+ | NullableLessEqNullableQ _ -> transBinOp env false args false Expression.LessThanOrEqual
+
// Detect the F# quotation encoding of decimal literals
- | MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) ->
- Expression.Constant (new System.Decimal(lo, med, hi, isNegative, scale)) |> asExpr
-
- | NegQ (_, _, [x1]) -> Expression.Negate(ConvExprToLinqInContext env x1) |> asExpr
- | PlusQ (_, _, [x1; x2]) -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | DivideQ (_, _, [x1; x2]) -> Expression.Divide (ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | MinusQ (_, _, [x1; x2]) -> Expression.Subtract(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | MultiplyQ (_, _, [x1; x2]) -> Expression.Multiply(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | ModuloQ (_, _, [x1; x2]) -> Expression.Modulo (ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
-
- | ShiftLeftQ (_, _, [x1; x2]) -> Expression.LeftShift(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | ShiftRightQ (_, _, [x1; x2]) -> Expression.RightShift(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | BitwiseAndQ (_, _, [x1; x2]) -> Expression.And(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | BitwiseOrQ (_, _, [x1; x2]) -> Expression.Or(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | BitwiseXorQ (_, _, [x1; x2]) -> Expression.ExclusiveOr(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
+ | MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) ->
+ Expression.Constant(new System.Decimal(lo,med,hi,isNegative,scale)) |> asExpr
+
+ | NegQ (_, _, [x1]) -> Expression.Negate(ConvExprToLinqInContext env x1) |> asExpr
+ | PlusQ _ -> transBinOp env false args false Expression.Add
+ | DivideQ _ -> transBinOp env false args false Expression.Divide
+ | MinusQ _ -> transBinOp env false args false Expression.Subtract
+ | MultiplyQ _ -> transBinOp env false args false Expression.Multiply
+ | ModuloQ _ -> transBinOp env false args false Expression.Modulo
+
+ | ShiftLeftQ _ -> transBinOp env false args false Expression.LeftShift
+ | ShiftRightQ _ -> transBinOp env false args false Expression.RightShift
+ | BitwiseAndQ _ -> transBinOp env false args false Expression.And
+ | BitwiseOrQ _ -> transBinOp env false args false Expression.Or
+ | BitwiseXorQ _ -> transBinOp env false args false Expression.ExclusiveOr
| BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr
-
- | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr
- | CheckedPlusQ (_, _, [x1; x2]) -> Expression.AddChecked(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | CheckedMinusQ (_, _, [x1; x2]) -> Expression.SubtractChecked(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
- | CheckedMultiplyQ (_, _, [x1; x2]) -> Expression.MultiplyChecked(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr
-
-
- | NullablePlusQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Add
- | PlusNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Add
- | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Add
-
- | NullableMinusQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Subtract
- | MinusNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Subtract
- | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Subtract
-
- | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Multiply
- | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Multiply
- | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Multiply
-
- | NullableDivideQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Divide
- | DivideNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Divide
- | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Divide
-
- | NullableModuloQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Modulo
- | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Modulo
- | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Modulo
-
- | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr
+
+ | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr
+ | CheckedPlusQ _ -> transBinOp env false args false Expression.AddChecked
+ | CheckedMinusQ _ -> transBinOp env false args false Expression.SubtractChecked
+ | CheckedMultiplyQ _ -> transBinOp env false args false Expression.MultiplyChecked
+
+ | NullablePlusQ _ -> transBinOp env false args true Expression.Add
+ | PlusNullableQ _ -> transBinOp env true args false Expression.Add
+ | NullablePlusNullableQ _ -> transBinOp env false args false Expression.Add
+
+ | NullableMinusQ _ -> transBinOp env false args true Expression.Subtract
+ | MinusNullableQ _ -> transBinOp env true args false Expression.Subtract
+ | NullableMinusNullableQ _ -> transBinOp env false args false Expression.Subtract
+
+ | NullableMultiplyQ _ -> transBinOp env false args true Expression.Multiply
+ | MultiplyNullableQ _ -> transBinOp env true args false Expression.Multiply
+ | NullableMultiplyNullableQ _ -> transBinOp env false args false Expression.Multiply
+
+ | NullableDivideQ _ -> transBinOp env false args true Expression.Divide
+ | DivideNullableQ _ -> transBinOp env true args false Expression.Divide
+ | NullableDivideNullableQ _ -> transBinOp env false args false Expression.Divide
+
+ | NullableModuloQ _ -> transBinOp env false args true Expression.Modulo
+ | ModuloNullableQ _ -> transBinOp env true args false Expression.Modulo
+ | NullableModuloNullableQ _ -> transBinOp env false args false Expression.Modulo
+
+ | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr
| ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr
| ConvNullableFloatQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr
| ConvNullableDoubleQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr
@@ -651,10 +658,18 @@ module LeafExpressionConverter =
// Throw away markers inserted to satisfy C#'s design where they pass an argument
// or type T to an argument expecting Expression.
| ImplicitExpressionConversionHelperQ (_, [_], [x1]) -> ConvExprToLinqInContext env x1
-
- | _ ->
- let argsP = ConvExprsToLinq env args
- Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr
+
+ | CallWithWitnesses (objArgOpt, _, minfo2, witnessArgs, args) ->
+ let fullArgs = witnessArgs @ args
+ let replacementExpr =
+ match objArgOpt with
+ | None -> Expr.Call(minfo2, fullArgs)
+ | Some objArg -> Expr.Call(objArg, minfo2, fullArgs)
+ ConvExprToLinqInContext env replacementExpr
+
+ | _ ->
+ let argsP = ConvExprsToLinq env args
+ Expression.Call(ConvObjArg env objOpt None, minfo, argsP) |> asExpr
#if !NO_CURRIED_FUNCTION_OPTIMIZATIONS
// f x1 x2 x3 x4 --> InvokeFast4
@@ -804,13 +819,15 @@ module LeafExpressionConverter =
| _ ->
raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp))
- and transBinOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor : _ * _ -> _) =
- let e1 = ConvExprToLinqInContext env x1
- let e2 = ConvExprToLinqInContext env x2
- let e1 = if addConvertLeft then Expression.Convert(e1, typedefof>.MakeGenericType [| e1.Type |]) |> asExpr else e1
- let e2 = if addConvertRight then Expression.Convert(e2, typedefof>.MakeGenericType [| e2.Type |]) |> asExpr else e2
- exprErasedConstructor(e1, e2) |> asExpr
-
+ and transBinOp env addConvertLeft args addConvertRight (exprErasedConstructor : _ * _ -> _) =
+ match args with
+ | [x1; x2] ->
+ let e1 = ConvExprToLinqInContext env x1
+ let e2 = ConvExprToLinqInContext env x2
+ let e1 = if addConvertLeft then Expression.Convert(e1, typedefof>.MakeGenericType [| e1.Type |]) |> asExpr else e1
+ let e2 = if addConvertRight then Expression.Convert(e2, typedefof>.MakeGenericType [| e2.Type |]) |> asExpr else e2
+ exprErasedConstructor(e1, e2) |> asExpr
+ | _ -> raise (new NotSupportedException(Printf.sprintf "unexpected missing args in binary operator"))
and ConvObjArg env objOpt coerceTo : Expression =
match objOpt with
diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs
index 2e91dec124f..e048af1e72d 100644
--- a/src/fsharp/FSharp.Core/prim-types.fs
+++ b/src/fsharp/FSharp.Core/prim-types.fs
@@ -301,10 +301,15 @@ namespace Microsoft.FSharp.Core
[]
[]
- type NoDynamicInvocationAttribute() =
+ type NoDynamicInvocationAttribute(legacy: bool) =
+
inherit System.Attribute()
- []
+ new () = NoDynamicInvocationAttribute(false)
+
+ member x.IsLegacy = legacy
+
+ []
[]
type OptionalArgumentAttribute() =
inherit System.Attribute()
@@ -388,8 +393,8 @@ namespace Microsoft.FSharp.Core
member inline this.IsSealed = this.GetTypeInfo().IsSealed
member inline this.IsAssignableFrom(otherType: Type) = this.GetTypeInfo().IsAssignableFrom(otherType.GetTypeInfo())
member inline this.GetGenericArguments() = this.GetTypeInfo().GenericTypeArguments
- member inline this.GetProperty(name) = this.GetRuntimeProperty(name)
- member inline this.GetMethod(name, parameterTypes) = this.GetRuntimeMethod(name, parameterTypes)
+ member inline this.GetProperty(name) = this.GetTypeInfo().GetProperty(name)
+ member inline this.GetMethod(name:string, parameterTypes: Type[]) = this.GetTypeInfo().GetMethod(name, parameterTypes)
member inline this.GetCustomAttributes(attributeType: Type, inherits: bool) : obj[] =
unboxPrim<_> (box (CustomAttributeExtensions.GetCustomAttributes(this.GetTypeInfo(), attributeType, inherits).ToArray()))
@@ -414,7 +419,7 @@ namespace Microsoft.FSharp.Core
let inline (+..) (x:uint64) (y:uint64) = (# "add" x y : uint64 #)
let inline ( *. ) (x:int64) (y:int64) = (# "mul" x y : int64 #)
let inline ( *.. ) (x:uint64) (y:uint64) = (# "mul" x y : uint64 #)
- let inline (^) (x:string) (y:string) = System.String.Concat(x,y)
+ let inline (^) (x:string) (y:string) = String.Concat(x,y)
let inline (<<<) (x:int) (y:int) = (# "shl" x y : int #)
let inline ( * ) (x:int) (y:int) = (# "mul" x y : int #)
let inline (-) (x:int) (y:int) = (# "sub" x y : int #)
@@ -463,14 +468,14 @@ namespace Microsoft.FSharp.Core
let inline iscastPrim<'T when 'T : not struct>(x:obj) = (# "isinst !0" type ('T) x : 'T #)
+ let inline mask (n:int) (m:int) = (# "and" n m : int #)
open BasicInlinedOperations
module TupleUtils =
- // adapted from System.Tuple :: CombineHashCodes
- let inline mask (n:int) (m:int) = (# "and" n m : int #)
+ // adapted from System.Tuple::CombineHashCodes
let inline opshl (x:int) (n:int) : int = (# "shl" x (mask n 31) : int #)
let inline opxor (x:int) (y:int) : int = (# "xor" x y : int32 #)
let inline combineTupleHashes (h1 : int) (h2 : int) = (opxor ((opshl h1 5) + h1) h2)
@@ -595,7 +600,7 @@ namespace Microsoft.FSharp.Core
then TypeNullnessSemantics_NullNotLiked
else TypeNullnessSemantics_NullTrueValue
- []
+
type TypeInfo<'T>() =
// Compute an on-demand per-instantiation static field
static let info = getTypeInfo typeof<'T>
@@ -829,7 +834,7 @@ namespace Microsoft.FSharp.Core
// Use Ordinal comparison for strings
| (:? string as x),(:? string as y) ->
- System.String.CompareOrdinal(x, y)
+ String.CompareOrdinal(x, y)
// Permit structural comparison on arrays
| (:? System.Array as arr1),_ ->
@@ -1103,10 +1108,10 @@ namespace Microsoft.FSharp.Core
else GenericComparisonWithComparerIntrinsic comp x y
when 'T : char = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : string =
- // NOTE: we don't have to null check here because System.String.CompareOrdinal
+ // NOTE: we don't have to null check here because String.CompareOrdinal
// gives reliable results on null values.
- System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))
- when 'T : decimal = System.Decimal.Compare((# "" x:decimal #), (# "" y:decimal #))
+ String.CompareOrdinal((# "" x : string #),(# "" y : string #))
+ when 'T : decimal = Decimal.Compare((# "" x:decimal #), (# "" y:decimal #))
/// Generic comparison. Implements ER mode (where "0" is returned when NaNs are compared)
@@ -1181,10 +1186,10 @@ namespace Microsoft.FSharp.Core
else (# "ceq" x x : int #)
when 'T : char = if (# "clt.un" x y : bool #) then (-1) else (# "cgt.un" x y : int #)
when 'T : string =
- // NOTE: we don't have to null check here because System.String.CompareOrdinal
+ // NOTE: we don't have to null check here because String.CompareOrdinal
// gives reliable results on null values.
- System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))
- when 'T : decimal = System.Decimal.Compare((# "" x:decimal #), (# "" y:decimal #))
+ String.CompareOrdinal((# "" x : string #),(# "" y : string #))
+ when 'T : decimal = Decimal.Compare((# "" x:decimal #), (# "" y:decimal #))
/// Generic less-than with static optimizations for some well-known cases.
let inline GenericLessThanFast (x:'T) (y:'T) =
@@ -1203,7 +1208,7 @@ namespace Microsoft.FSharp.Core
when 'T : float = (# "clt" x y : bool #)
when 'T : float32= (# "clt" x y : bool #)
when 'T : char = (# "clt" x y : bool #)
- when 'T : decimal = System.Decimal.op_LessThan ((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : decimal = Decimal.op_LessThan ((# "" x:decimal #), (# "" y:decimal #))
/// Generic greater-than with static optimizations for some well-known cases.
let inline GenericGreaterThanFast (x:'T) (y:'T) =
@@ -1222,7 +1227,7 @@ namespace Microsoft.FSharp.Core
when 'T : float = (# "cgt" x y : bool #)
when 'T : float32 = (# "cgt" x y : bool #)
when 'T : char = (# "cgt" x y : bool #)
- when 'T : decimal = System.Decimal.op_GreaterThan ((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : decimal = Decimal.op_GreaterThan ((# "" x:decimal #), (# "" y:decimal #))
/// Generic less-than-or-equal with static optimizations for some well-known cases.
let inline GenericLessOrEqualFast (x:'T) (y:'T) =
@@ -1241,7 +1246,7 @@ namespace Microsoft.FSharp.Core
when 'T : float = not (# "cgt.un" x y : bool #)
when 'T : float32 = not (# "cgt.un" x y : bool #)
when 'T : char = not(# "cgt" x y : bool #)
- when 'T : decimal = System.Decimal.op_LessThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : decimal = Decimal.op_LessThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
/// Generic greater-than-or-equal with static optimizations for some well-known cases.
let inline GenericGreaterOrEqualFast (x:'T) (y:'T) =
@@ -1260,7 +1265,7 @@ namespace Microsoft.FSharp.Core
when 'T : float = not (# "clt.un" x y : bool #)
when 'T : float32 = not (# "clt.un" x y : bool #)
when 'T : char = not (# "clt" x y : bool #)
- when 'T : decimal = System.Decimal.op_GreaterThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : decimal = Decimal.op_GreaterThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
//-------------------------------------------------------------------------
@@ -1376,7 +1381,7 @@ namespace Microsoft.FSharp.Core
| null,null -> true
| null,_ -> false
| _,null -> false
- | (:? string as xs),(:? string as ys) -> System.String.Equals(xs,ys)
+ | (:? string as xs),(:? string as ys) -> String.Equals(xs,ys)
// Permit structural equality on arrays
| (:? System.Array as arr1),_ ->
match arr1,yobj with
@@ -1601,8 +1606,8 @@ namespace Microsoft.FSharp.Core
else
not (# "ceq" x x : bool #) && not (# "ceq" y y : bool #)
when 'T : char = (# "ceq" x y : bool #)
- when 'T : string = System.String.Equals((# "" x : string #),(# "" y : string #))
- when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : string = String.Equals((# "" x : string #),(# "" y : string #))
+ when 'T : decimal = Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
/// Implements generic equality between two values, with PER semantics for NaN (so equality on two NaN values returns false)
//
@@ -1623,8 +1628,8 @@ namespace Microsoft.FSharp.Core
when 'T : char = (# "ceq" x y : bool #)
when 'T : nativeint = (# "ceq" x y : bool #)
when 'T : unativeint = (# "ceq" x y : bool #)
- when 'T : string = System.String.Equals((# "" x : string #),(# "" y : string #))
- when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : string = String.Equals((# "" x : string #),(# "" y : string #))
+ when 'T : decimal = Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
/// A compiler intrinsic generated during optimization of calls to GenericEqualityIntrinsic on tuple values.
//
@@ -1649,8 +1654,8 @@ namespace Microsoft.FSharp.Core
when 'T : char = (# "ceq" x y : bool #)
when 'T : nativeint = (# "ceq" x y : bool #)
when 'T : unativeint = (# "ceq" x y : bool #)
- when 'T : string = System.String.Equals((# "" x : string #),(# "" y : string #))
- when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
+ when 'T : string = String.Equals((# "" x : string #),(# "" y : string #))
+ when 'T : decimal = Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
let inline GenericInequalityFast (x:'T) (y:'T) = (not(GenericEqualityFast x y) : bool)
@@ -2334,13 +2339,13 @@ namespace Microsoft.FSharp.Core
let inline EnumOfValue (value : 'T) : 'Enum when 'Enum : enum<'T> =
unboxPrim<'Enum>(box value)
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever 'Enum is resolved to a nominal type
+ // this condition is used whenever 'Enum is resolved to a nominal type or witnesses are available
when 'Enum : 'Enum = (retype value : 'Enum)
let inline EnumToValue (enum : 'Enum) : 'T when 'Enum : enum<'T> =
unboxPrim<'T>(box enum)
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever 'Enum is resolved to a nominal type
+ // this condition is used whenever 'Enum is resolved to a nominal type or witnesses are available
when 'Enum : 'Enum = (retype enum : 'T)
//-------------------------------------------------------------------------
@@ -2469,8 +2474,540 @@ namespace Microsoft.FSharp.Core
| 'o' -> parseOctalUInt64 s p l
| _ -> UInt64.Parse(s.Substring(p), NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)
+ let inline ParseByte (s:string) = (# "conv.ovf.u1" (ParseUInt32 s) : byte #)
+
+ let inline ParseSByte (s:string) = (# "conv.ovf.i1" (ParseInt32 s) : sbyte #)
+
+ let inline ParseInt16 (s:string) = (# "conv.ovf.i2" (ParseInt32 s) : int16 #)
+
+ let inline ParseUInt16 (s:string) = (# "conv.ovf.u2" (ParseUInt32 s) : uint16 #)
+
+ let inline ParseIntPtr (s:string) = (# "conv.ovf.i" (ParseInt64 s) : nativeint #)
+
+ let inline ParseUIntPtr (s:string) = (# "conv.ovf.u" (ParseInt64 s) : unativeint #)
+
+ let inline ParseDouble (s:string) = Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
+
+ let inline ParseSingle (s:string) = Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
+
+ type BuiltInWitnesses =
+#if BUILDING_WITH_LKG
+ static member NoUseOfWitnessesAllowedInProto() = ()
+#else
+ static member inline op_Addition(x: int32, y: int32) = (# "add" x y : int32 #)
+ static member inline op_Addition(x: float, y: float) = (# "add" x y : float #)
+ static member inline op_Addition(x: float32, y: float32) = (# "add" x y : float32 #)
+ static member inline op_Addition(x: int64, y: int64) = (# "add" x y : int64 #)
+ static member inline op_Addition(x: uint64, y: uint64) = (# "add" x y : uint64 #)
+ static member inline op_Addition(x: uint32, y: uint32) = (# "add" x y : uint32 #)
+ static member inline op_Addition(x: nativeint, y: nativeint) = (# "add" x y : nativeint #)
+ static member inline op_Addition(x: unativeint, y: unativeint) = (# "add" x y : unativeint #)
+ static member inline op_Addition(x: int16, y: int16) = (# "conv.i2" (# "add" x y : int32 #) : int16 #)
+ static member inline op_Addition(x: uint16, y: uint16) = (# "conv.u2" (# "add" x y : uint32 #) : uint16 #)
+ static member inline op_Addition(x: char, y: char) = (# "conv.u2" (# "add" x y : uint32 #) : char #)
+ static member inline op_Addition(x: sbyte, y: sbyte) = (# "conv.i1" (# "add" x y : int32 #) : sbyte #)
+ static member inline op_Addition(x: byte, y: byte) = (# "conv.u1" (# "add" x y : uint32 #) : byte #)
+ static member inline op_Addition(x: string, y: string) = String.Concat(x, y)
+ static member inline op_Addition(x: decimal, y: decimal) = Decimal.op_Addition(x, y)
+
+ static member inline op_Multiply(x: int32, y: int32) = (# "mul" x y : int32 #)
+ static member inline op_Multiply(x: float, y: float) = (# "mul" x y : float #)
+ static member inline op_Multiply(x: float32, y: float32) = (# "mul" x y : float32 #)
+ static member inline op_Multiply(x: int64, y: int64) = (# "mul" x y : int64 #)
+ static member inline op_Multiply(x: uint64, y: uint64) = (# "mul" x y : uint64 #)
+ static member inline op_Multiply(x: uint32, y: uint32) = (# "mul" x y : uint32 #)
+ static member inline op_Multiply(x: nativeint, y: nativeint) = (# "mul" x y : nativeint #)
+ static member inline op_Multiply(x: unativeint, y: unativeint) = (# "mul" x y : unativeint #)
+ static member inline op_Multiply(x: int16, y: int16) = (# "conv.i2" (# "mul" x y : int32 #) : int16 #)
+ static member inline op_Multiply(x: uint16, y: uint16) = (# "conv.u2" (# "mul" x y : uint32 #) : uint16 #)
+ static member inline op_Multiply(x: sbyte, y: sbyte) = (# "conv.i1" (# "mul" x y : int32 #) : sbyte #)
+ static member inline op_Multiply(x: byte, y: byte) = (# "conv.u1" (# "mul" x y : uint32 #) : byte #)
+ static member inline op_Multiply(x: decimal, y: decimal) = Decimal.op_Multiply(x, y)
+
+ static member inline op_UnaryNegation(value: int32) = (# "neg" value : int32 #)
+ static member inline op_UnaryNegation(value: float) = (# "neg" value : float #)
+ static member inline op_UnaryNegation(value: float32) = (# "neg" value : float32 #)
+ static member inline op_UnaryNegation(value: int64) = (# "neg" value : int64 #)
+ static member inline op_UnaryNegation(value: int16) = (# "neg" value : int16 #)
+ static member inline op_UnaryNegation(value: nativeint) = (# "neg" value : nativeint #)
+ static member inline op_UnaryNegation(value: sbyte) = (# "neg" value : sbyte #)
+ static member inline op_UnaryNegation(value: decimal) = Decimal.op_UnaryNegation(value)
+
+ static member inline op_Subtraction(x: int32, y: int32) = (# "sub" x y : int32 #)
+ static member inline op_Subtraction(x: float, y: float) = (# "sub" x y : float #)
+ static member inline op_Subtraction(x: float32, y: float32) = (# "sub" x y : float32 #)
+ static member inline op_Subtraction(x: int64, y: int64) = (# "sub" x y : int64 #)
+ static member inline op_Subtraction(x: uint64, y: uint64) = (# "sub" x y : uint64 #)
+ static member inline op_Subtraction(x: uint32, y: uint32) = (# "sub" x y : uint32 #)
+ static member inline op_Subtraction(x: nativeint, y: nativeint) = (# "sub" x y : nativeint #)
+ static member inline op_Subtraction(x: unativeint, y: unativeint) = (# "sub" x y : unativeint #)
+ static member inline op_Subtraction(x: int16, y: int16) = (# "conv.i2" (# "sub" x y : int32 #) : int16 #)
+ static member inline op_Subtraction(x: uint16, y: uint16) = (# "conv.u2" (# "sub" x y : uint32 #) : uint16 #)
+ static member inline op_Subtraction(x: sbyte, y: sbyte) = (# "conv.i1" (# "sub" x y : int32 #) : sbyte #)
+ static member inline op_Subtraction(x: byte, y: byte) = (# "conv.u1" (# "sub" x y : uint32 #) : byte #)
+ static member inline op_Subtraction(x: decimal, y: decimal) = Decimal.op_Subtraction(x, y)
+
+ static member inline op_Division(x: int32, y: int32) = (# "div" x y : int32 #)
+ static member inline op_Division(x: float, y: float) = (# "div" x y : float #)
+ static member inline op_Division(x: float32, y: float32) = (# "div" x y : float32 #)
+ static member inline op_Division(x: int64, y: int64) = (# "div" x y : int64 #)
+ static member inline op_Division(x: uint64, y: uint64) = (# "div.un" x y : uint64 #)
+ static member inline op_Division(x: uint32, y: uint32) = (# "div.un" x y : uint32 #)
+ static member inline op_Division(x: nativeint, y: nativeint) = (# "div" x y : nativeint #)
+ static member inline op_Division(x: unativeint, y: unativeint) = (# "div.un" x y : unativeint #)
+ static member inline op_Division(x: int16, y: int16) = (# "conv.i2" (# "div" x y : int32 #) : int16 #)
+ static member inline op_Division(x: uint16, y: uint16) = (# "conv.u2" (# "div.un" x y : uint32 #) : uint16 #)
+ static member inline op_Division(x: sbyte, y: sbyte) = (# "conv.i1" (# "div" x y : int32 #) : sbyte #)
+ static member inline op_Division(x: byte, y: byte) = (# "conv.u1" (# "div.un" x y : uint32 #) : byte #)
+ static member inline op_Division(x: decimal, y: decimal) = Decimal.op_Division(x, y)
+
+ static member inline op_Modulus(x: int32, y: int32) = (# "rem" x y : int32 #)
+ static member inline op_Modulus(x: float, y: float) = (# "rem" x y : float #)
+ static member inline op_Modulus(x: float32, y: float32) = (# "rem" x y : float32 #)
+ static member inline op_Modulus(x: int64, y: int64) = (# "rem" x y : int64 #)
+ static member inline op_Modulus(x: uint64, y: uint64) = (# "rem.un" x y : uint64 #)
+ static member inline op_Modulus(x: uint32, y: uint32) = (# "rem.un" x y : uint32 #)
+ static member inline op_Modulus(x: nativeint, y: nativeint) = (# "rem" x y : nativeint #)
+ static member inline op_Modulus(x: unativeint, y: unativeint) = (# "rem.un" x y : unativeint #)
+ static member inline op_Modulus(x: int16, y: int16) = (# "conv.i2" (# "rem" x y : int32 #) : int16 #)
+ static member inline op_Modulus(x: uint16, y: uint16) = (# "conv.u2" (# "rem.un" x y : uint32 #) : uint16 #)
+ static member inline op_Modulus(x: sbyte, y: sbyte) = (# "conv.i1" (# "rem" x y : int32 #) : sbyte #)
+ static member inline op_Modulus(x: byte, y: byte) = (# "conv.u1" (# "rem.un" x y : uint32 #) : byte #)
+ static member inline op_Modulus(x: decimal, y: decimal) = Decimal.op_Modulus(x, y)
+
+ static member inline op_CheckedAddition(x: int32, y: int32) = (# "add.ovf" x y : int32 #)
+ static member inline op_CheckedAddition(x: float, y: float) = (# "add" x y : float #)
+ static member inline op_CheckedAddition(x: float32, y: float32) = (# "add" x y : float32 #)
+ static member inline op_CheckedAddition(x: int64, y: int64) = (# "add.ovf" x y : int64 #)
+ static member inline op_CheckedAddition(x: uint64, y: uint64) = (# "add.ovf.un" x y : uint64 #)
+ static member inline op_CheckedAddition(x: uint32, y: uint32) = (# "add.ovf.un" x y : uint32 #)
+ static member inline op_CheckedAddition(x: nativeint, y: nativeint) = (# "add.ovf" x y : nativeint #)
+ static member inline op_CheckedAddition(x: unativeint, y: unativeint) = (# "add.ovf.un" x y : unativeint #)
+ static member inline op_CheckedAddition(x: int16, y: int16) = (# "conv.ovf.i2" (# "add.ovf" x y : int32 #) : int16 #)
+ static member inline op_CheckedAddition(x: uint16, y: uint16) = (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : uint16 #)
+ static member inline op_CheckedAddition(x: char, y: char) = (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : char #)
+ static member inline op_CheckedAddition(x: sbyte, y: sbyte) = (# "conv.ovf.i1" (# "add.ovf" x y : int32 #) : sbyte #)
+ static member inline op_CheckedAddition(x: byte, y: byte) = (# "conv.ovf.u1.un" (# "add.ovf.un" x y : uint32 #) : byte #)
+ static member inline op_CheckedAddition(x: string, y: string) = String.Concat(x, y)
+
+ static member inline op_CheckedSubtraction(x: int32, y: int32) = (# "sub.ovf" x y : int32 #)
+ static member inline op_CheckedSubtraction(x: float, y: float) = (# "sub" x y : float #)
+ static member inline op_CheckedSubtraction(x: float32, y: float32) = (# "sub" x y : float32 #)
+ static member inline op_CheckedSubtraction(x: int64, y: int64) = (# "sub.ovf" x y : int64 #)
+ static member inline op_CheckedSubtraction(x: uint64, y: uint64) = (# "sub.ovf.un" x y : uint64 #)
+ static member inline op_CheckedSubtraction(x: uint32, y: uint32) = (# "sub.ovf.un" x y : uint32 #)
+ static member inline op_CheckedSubtraction(x: nativeint, y: nativeint) = (# "sub.ovf" x y : nativeint #)
+ static member inline op_CheckedSubtraction(x: unativeint, y: unativeint) = (# "sub.ovf.un" x y : unativeint #)
+ static member inline op_CheckedSubtraction(x: int16, y: int16) = (# "conv.ovf.i2" (# "sub.ovf" x y : int32 #) : int16 #)
+ static member inline op_CheckedSubtraction(x: uint16, y: uint16) = (# "conv.ovf.u2.un" (# "sub.ovf.un" x y : uint32 #) : uint16 #)
+ static member inline op_CheckedSubtraction(x: sbyte, y: sbyte) = (# "conv.ovf.i1" (# "sub.ovf" x y : int32 #) : sbyte #)
+ static member inline op_CheckedSubtraction(x: byte, y: byte) = (# "conv.ovf.u1.un" (# "sub.ovf.un" x y : uint32 #) : byte #)
+
+ static member inline op_CheckedMultiply(x: int32, y: int32) = (# "mul.ovf" x y : int32 #)
+ static member inline op_CheckedMultiply(x: float, y: float) = (# "mul" x y : float #)
+ static member inline op_CheckedMultiply(x: float32, y: float32) = (# "mul" x y : float32 #)
+ static member inline op_CheckedMultiply(x: int64, y: int64) = (# "mul.ovf" x y : int64 #)
+ static member inline op_CheckedMultiply(x: uint64, y: uint64) = (# "mul.ovf.un" x y : uint64 #)
+ static member inline op_CheckedMultiply(x: uint32, y: uint32) = (# "mul.ovf.un" x y : uint32 #)
+ static member inline op_CheckedMultiply(x: nativeint, y: nativeint) = (# "mul.ovf" x y : nativeint #)
+ static member inline op_CheckedMultiply(x: unativeint, y: unativeint) = (# "mul.ovf.un" x y : unativeint #)
+ static member inline op_CheckedMultiply(x: int16, y: int16) = (# "conv.ovf.i2" (# "mul.ovf" x y : int32 #) : int16 #)
+ static member inline op_CheckedMultiply(x: uint16, y: uint16) = (# "conv.ovf.u2.un" (# "mul.ovf.un" x y : uint16 #) : uint16 #)
+ static member inline op_CheckedMultiply(x: sbyte, y: sbyte) = (# "conv.ovf.i1" (# "mul.ovf" x y : int32 #) : sbyte #)
+ static member inline op_CheckedMultiply(x: byte, y: byte) = (# "conv.ovf.u1.un" (# "mul.ovf.un" x y : uint32 #) : byte #)
+
+ static member inline op_CheckedUnaryNegation(value: int32) = (# "sub.ovf" 0 value : int32 #)
+ static member inline op_CheckedUnaryNegation(value: float) = (# "neg" value : float #)
+ static member inline op_CheckedUnaryNegation(value: float32) = (# "neg" value : float32 #)
+ static member inline op_CheckedUnaryNegation(value: int64) = (# "sub.ovf" 0L value : int64 #)
+ static member inline op_CheckedUnaryNegation(value: int16) = (# "sub.ovf" 0s value : int16 #)
+ static member inline op_CheckedUnaryNegation(value: nativeint) = (# "sub.ovf" 0n value : nativeint #)
+ static member inline op_CheckedUnaryNegation(value: sbyte) = (# "sub.ovf" 0y value : sbyte #)
+
+ static member inline op_LeftShift(value: int32, shift: int32) = (# "shl" value (mask shift 31) : int #)
+ static member inline op_LeftShift(value: uint32, shift: int32) = (# "shl" value (mask shift 31) : uint32 #)
+ static member inline op_LeftShift(value: int64, shift: int32) = (# "shl" value (mask shift 63) : int64 #)
+ static member inline op_LeftShift(value: uint64, shift: int32) = (# "shl" value (mask shift 63) : uint64 #)
+ static member inline op_LeftShift(value: nativeint, shift: int32) = (# "shl" value shift : nativeint #)
+ static member inline op_LeftShift(value: unativeint, shift: int32) = (# "shl" value shift : unativeint #)
+ static member inline op_LeftShift(value: int16, shift: int32) = (# "conv.i2" (# "shl" value (mask shift 15) : int32 #) : int16 #)
+ static member inline op_LeftShift(value: uint16, shift: int32) = (# "conv.u2" (# "shl" value (mask shift 15) : uint32 #) : uint16 #)
+ static member inline op_LeftShift(value: sbyte, shift: int32) = (# "conv.i1" (# "shl" value (mask shift 7) : int32 #) : sbyte #)
+ static member inline op_LeftShift(value: byte, shift: int32) = (# "conv.u1" (# "shl" value (mask shift 7) : uint32 #) : byte #)
+
+ static member inline op_RightShift(value: sbyte, shift: int32) = (# "conv.i1" (# "shr" value (mask shift 7 ) : int32 #) : sbyte #)
+ static member inline op_RightShift(value: byte, shift: int32) = (# "conv.u1" (# "shr.un" value (mask shift 7 ) : uint32 #) : byte #)
+ static member inline op_RightShift(value: int16, shift: int32) = (# "conv.i2" (# "shr" value (mask shift 15) : int32 #) : int16 #)
+ static member inline op_RightShift(value: uint16, shift: int32) = (# "conv.u2" (# "shr.un" value (mask shift 15) : uint32 #) : uint16 #)
+ static member inline op_RightShift(value: int32, shift: int32) = (# "shr" value (mask shift 31) : int32 #)
+ static member inline op_RightShift(value: uint32, shift: int32) = (# "shr.un" value (mask shift 31) : uint32 #)
+ static member inline op_RightShift(value: int64, shift: int32) = (# "shr" value (mask shift 63) : int64 #)
+ static member inline op_RightShift(value: uint64, shift: int32) = (# "shr.un" value (mask shift 63) : uint64 #)
+ static member inline op_RightShift(value: nativeint, shift: int32) = (# "shr" value shift : nativeint #)
+ static member inline op_RightShift(value: unativeint, shift: int32) = (# "shr.un" value shift : unativeint #)
+
+ static member inline op_BitwiseAnd(x: sbyte, y: sbyte) = (# "and" x y : sbyte #)
+ static member inline op_BitwiseAnd(x: byte, y: byte) = (# "and" x y : byte #)
+ static member inline op_BitwiseAnd(x: int16, y: int16) = (# "and" x y : int16 #)
+ static member inline op_BitwiseAnd(x: uint16, y: uint16) = (# "and" x y : uint16 #)
+ static member inline op_BitwiseAnd(x: int32, y: int32) = (# "and" x y : int32 #)
+ static member inline op_BitwiseAnd(x: uint32, y: uint32) = (# "and" x y : uint32 #)
+ static member inline op_BitwiseAnd(x: int64, y: int64) = (# "and" x y : int64 #)
+ static member inline op_BitwiseAnd(x: uint64, y: uint64) = (# "and" x y : uint64 #)
+ static member inline op_BitwiseAnd(x: nativeint, y: nativeint) = (# "and" x y : nativeint #)
+ static member inline op_BitwiseAnd(x: unativeint, y: unativeint) = (# "and" x y : unativeint #)
+
+ static member inline op_BitwiseOr(x: sbyte, y: sbyte) = (# "or" x y : sbyte #)
+ static member inline op_BitwiseOr(x: byte, y: byte) = (# "or" x y : byte #)
+ static member inline op_BitwiseOr(x: int16, y: int16) = (# "or" x y : int16 #)
+ static member inline op_BitwiseOr(x: uint16, y: uint16) = (# "or" x y : uint16 #)
+ static member inline op_BitwiseOr(x: int32, y: int32) = (# "or" x y : int32 #)
+ static member inline op_BitwiseOr(x: uint32, y: uint32) = (# "or" x y : uint32 #)
+ static member inline op_BitwiseOr(x: int64, y: int64) = (# "or" x y : int64 #)
+ static member inline op_BitwiseOr(x: uint64, y: uint64) = (# "or" x y : uint64 #)
+ static member inline op_BitwiseOr(x: nativeint, y: nativeint) = (# "or" x y : nativeint #)
+ static member inline op_BitwiseOr(x: unativeint, y: unativeint) = (# "or" x y : unativeint #)
+
+ static member inline op_ExclusiveOr(x: sbyte, y: sbyte) = (# "xor" x y : sbyte #)
+ static member inline op_ExclusiveOr(x: byte, y: byte) = (# "xor" x y : byte #)
+ static member inline op_ExclusiveOr(x: int16, y: int16) = (# "xor" x y : int16 #)
+ static member inline op_ExclusiveOr(x: uint16, y: uint16) = (# "xor" x y : uint16 #)
+ static member inline op_ExclusiveOr(x: int32, y: int32) = (# "xor" x y : int32 #)
+ static member inline op_ExclusiveOr(x: uint32, y: uint32) = (# "xor" x y : uint32 #)
+ static member inline op_ExclusiveOr(x: int64, y: int64) = (# "xor" x y : int64 #)
+ static member inline op_ExclusiveOr(x: uint64, y: uint64) = (# "xor" x y : uint64 #)
+ static member inline op_ExclusiveOr(x: nativeint, y: nativeint) = (# "xor" x y : nativeint #)
+ static member inline op_ExclusiveOr(x: unativeint, y: unativeint) = (# "xor" x y : unativeint #)
+
+ static member inline op_LogicalNot(value: sbyte) = (# "conv.i1" (# "not" value : int32 #) : sbyte #)
+ static member inline op_LogicalNot(value: byte) = (# "conv.u1" (# "not" value : uint32 #) : byte #)
+ static member inline op_LogicalNot(value: int16) = (# "conv.i2" (# "not" value : int32 #) : int16 #)
+ static member inline op_LogicalNot(value: uint16) = (# "conv.u2" (# "not" value : uint32 #) : uint16 #)
+ static member inline op_LogicalNot(value: int32) = (# "not" value : int32 #)
+ static member inline op_LogicalNot(value: uint32) = (# "not" value : uint32 #)
+ static member inline op_LogicalNot(value: int64) = (# "not" value : int64 #)
+ static member inline op_LogicalNot(value: uint64) = (# "not" value : uint64 #)
+ static member inline op_LogicalNot(value: nativeint) = (# "not" value : nativeint #)
+ static member inline op_LogicalNot(value: unativeint) = (# "not" value : unativeint #)
+
+ static member inline op_Explicit(value: sbyte) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: byte) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: int16) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: uint16) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: int32) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: uint32) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: int64) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: uint64) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: nativeint) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: unativeint) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: float) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: float32) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: char) : byte = (# "conv.u1" value : byte #)
+ static member inline op_Explicit(value: string) : byte = ParseByte value
+
+ static member inline op_Explicit(value: string) : sbyte = ParseSByte value
+ static member inline op_Explicit(value: float) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: float32) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: int64) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: int32) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: int16) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: nativeint) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: sbyte) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: uint64) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: uint32) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: uint16) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: char) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: unativeint) : sbyte = (# "conv.i1" value : sbyte #)
+ static member inline op_Explicit(value: byte) : sbyte = (# "conv.i1" value : sbyte #)
+
+ static member inline op_Explicit(value: string) : uint16 = ParseUInt16 value
+ static member inline op_Explicit(value: float) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: float32) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: int64) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: int32) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: int16) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: nativeint) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: sbyte) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: uint64) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: uint32) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: uint16) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: char) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: unativeint) : uint16 = (# "conv.u2" value : uint16 #)
+ static member inline op_Explicit(value: byte) : uint16 = (# "conv.u2" value : uint16 #)
+
+ static member inline op_Explicit(value: string) : int16 = ParseInt16 value
+ static member inline op_Explicit(value: float) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: float32) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: int64) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: int32) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: int16) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: nativeint) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: sbyte) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: uint64) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: uint32) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: uint16) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: char) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: unativeint) : int16 = (# "conv.i2" value : int16 #)
+ static member inline op_Explicit(value: byte) : int16 = (# "conv.i2" value : int16 #)
+
+ static member inline op_Explicit(value: string) : uint32 = ParseUInt32 value
+ static member inline op_Explicit(value: float) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: float32) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: int64) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: nativeint) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: int32) : uint32 = (# "" value : uint32 #)
+ static member inline op_Explicit(value: int16) : uint32 = (# "" value : uint32 #)
+ static member inline op_Explicit(value: sbyte) : uint32 = (# "" value : uint32 #)
+ static member inline op_Explicit(value: uint64) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: uint32) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: uint16) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: char) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: unativeint) : uint32 = (# "conv.u4" value : uint32 #)
+ static member inline op_Explicit(value: byte) : uint32 = (# "conv.u4" value : uint32 #)
+
+ static member inline op_Explicit(value: string) : int32 = ParseInt32 value
+ static member inline op_Explicit(value: float) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: float32) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: int64) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: nativeint) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: int32) : int32 = (# "" value : int32 #)
+ static member inline op_Explicit(value: int16) : int32 = (# "" value : int32 #)
+ static member inline op_Explicit(value: sbyte) : int32 = (# "" value : int32 #)
+ static member inline op_Explicit(value: uint64) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: uint32) : int32 = (# "" value : int32 #)
+ static member inline op_Explicit(value: uint16) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: char) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: unativeint) : int32 = (# "conv.i4" value : int32 #)
+ static member inline op_Explicit(value: byte) : int32 = (# "conv.i4" value : int32 #)
+
+ static member inline op_Explicit(value: string) : uint64 = ParseUInt64 value
+ static member inline op_Explicit(value: float) : uint64 = (# "conv.u8" value : uint64 #)
+ static member inline op_Explicit(value: float32) : uint64 = (# "conv.u8" value : uint64 #)
+ static member inline op_Explicit(value: int64) : uint64 = (# "" value : uint64 #)
+ static member inline op_Explicit(value: int32) : uint64 = (# "conv.i8" value : uint64 #)
+ static member inline op_Explicit(value: int16) : uint64 = (# "conv.i8" value : uint64 #)
+ static member inline op_Explicit(value: nativeint) : uint64 = (# "conv.i8" value : uint64 #)
+ static member inline op_Explicit(value: sbyte) : uint64 = (# "conv.i8" value : uint64 #)
+ static member inline op_Explicit(value: uint64) : uint64 = (# "" value : uint64 #)
+ static member inline op_Explicit(value: uint32) : uint64 = (# "conv.u8" value : uint64 #)
+ static member inline op_Explicit(value: uint16) : uint64 = (# "conv.u8" value : uint64 #)
+ static member inline op_Explicit(value: char) : uint64 = (# "conv.u8" value : uint64 #)
+ static member inline op_Explicit(value: unativeint) : uint64 = (# "conv.u8" value : uint64 #)
+ static member inline op_Explicit(value: byte) : uint64 = (# "conv.u8" value : uint64 #)
+
+ static member inline op_Explicit(value: string) : int64 = ParseInt64 value
+ static member inline op_Explicit(value: float) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: float32) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: int64) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: int32) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: int16) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: nativeint) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: sbyte) : int64 = (# "conv.i8" value : int64 #)
+ static member inline op_Explicit(value: uint64) : int64 = (# "" value : int64 #)
+ static member inline op_Explicit(value: uint32) : int64 = (# "conv.u8" value : int64 #)
+ static member inline op_Explicit(value: uint16) : int64 = (# "conv.u8" value : int64 #)
+ static member inline op_Explicit(value: char) : int64 = (# "conv.u8" value : int64 #)
+ static member inline op_Explicit(value: unativeint) : int64 = (# "conv.u8" value : int64 #)
+ static member inline op_Explicit(value: byte) : int64 = (# "conv.u8" value : int64 #)
+
+ static member inline op_Explicit(value: string) : float32 = ParseSingle value
+ static member inline op_Explicit(value: float) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: float32) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: int64) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: int32) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: int16) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: nativeint) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: sbyte) : float32 = (# "conv.r4" value : float32 #)
+ static member inline op_Explicit(value: uint64) : float32 = (# "conv.r.un conv.r4" value : float32 #)
+ static member inline op_Explicit(value: uint32) : float32 = (# "conv.r.un conv.r4" value : float32 #)
+ static member inline op_Explicit(value: uint16) : float32 = (# "conv.r.un conv.r4" value : float32 #)
+ static member inline op_Explicit(value: char) : float32 = (# "conv.r.un conv.r4" value : float32 #)
+ static member inline op_Explicit(value: unativeint) : float32 = (# "conv.r.un conv.r4" value : float32 #)
+ static member inline op_Explicit(value: byte) : float32 = (# "conv.r.un conv.r4" value : float32 #)
+
+ static member inline op_Explicit(value: string) : float = ParseDouble value
+ static member inline op_Explicit(value: float) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: float32) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: int64) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: int32) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: int16) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: nativeint) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: sbyte) : float = (# "conv.r8" value : float #)
+ static member inline op_Explicit(value: uint64) : float = (# "conv.r.un conv.r8" value : float #)
+ static member inline op_Explicit(value: uint32) : float = (# "conv.r.un conv.r8" value : float #)
+ static member inline op_Explicit(value: uint16) : float = (# "conv.r.un conv.r8" value : float #)
+ static member inline op_Explicit(value: char) : float = (# "conv.r.un conv.r8" value : float #)
+ static member inline op_Explicit(value: unativeint) : float = (# "conv.r.un conv.r8" value : float #)
+ static member inline op_Explicit(value: byte) : float = (# "conv.r.un conv.r8" value : float #)
+ static member inline op_Explicit(value: decimal) : float = Convert.ToDouble(value)
+
+ static member inline op_Explicit(value: string) : decimal = Decimal.Parse(value,NumberStyles.Float,CultureInfo.InvariantCulture)
+ static member inline op_Explicit(value: float) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: float32) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: int64) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: int32) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: int16) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: nativeint) : decimal = Convert.ToDecimal(BuiltInWitnesses.op_Explicit value : int64)
+ static member inline op_Explicit(value: sbyte) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: uint64) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: uint32) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: uint16) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: unativeint) : decimal = Convert.ToDecimal(BuiltInWitnesses.op_Explicit value : uint64)
+ static member inline op_Explicit(value: byte) : decimal = Convert.ToDecimal(value)
+ static member inline op_Explicit(value: decimal) : decimal = value
+
+ static member inline op_Explicit(value: string) : unativeint = ParseUIntPtr value
+ static member inline op_Explicit(value: float) : unativeint = (# "conv.u" value : unativeint #)
+ static member inline op_Explicit(value: float32) : unativeint = (# "conv.u" value : unativeint #)
+ static member inline op_Explicit(value: int64) : unativeint = (# "conv.i" value : unativeint #)
+ static member inline op_Explicit(value: int32) : unativeint = (# "conv.i" value : unativeint #)
+ static member inline op_Explicit(value: int16) : unativeint = (# "conv.i" value : unativeint #)
+ static member inline op_Explicit(value: nativeint) : unativeint = (# "" value : unativeint #)
+ static member inline op_Explicit(value: sbyte) : unativeint = (# "conv.i" value : unativeint #)
+ static member inline op_Explicit(value: uint64) : unativeint = (# "conv.u" value : unativeint #)
+ static member inline op_Explicit(value: uint32) : unativeint = (# "conv.u" value : unativeint #)
+ static member inline op_Explicit(value: uint16) : unativeint = (# "conv.u" value : unativeint #)
+ static member inline op_Explicit(value: char) : unativeint = (# "conv.u" value : unativeint #)
+ static member inline op_Explicit(value: unativeint) : unativeint = (# "" value : unativeint #)
+ static member inline op_Explicit(value: byte) : unativeint = (# "conv.u" value : unativeint #)
+
+ static member inline op_Explicit(value: string) : nativeint = ParseIntPtr value
+ static member inline op_Explicit(value: float) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: float32) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: int64) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: int32) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: int16) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: nativeint) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: sbyte) : nativeint = (# "conv.i" value : nativeint #)
+ static member inline op_Explicit(value: uint64) : nativeint = (# "conv.u" value : nativeint #)
+ static member inline op_Explicit(value: uint32) : nativeint = (# "conv.u" value : nativeint #)
+ static member inline op_Explicit(value: uint16) : nativeint = (# "conv.u" value : nativeint #)
+ static member inline op_Explicit(value: char) : nativeint = (# "conv.u" value : nativeint #)
+ static member inline op_Explicit(value: unativeint) : nativeint = (# "" value : nativeint #)
+ static member inline op_Explicit(value: byte) : nativeint = (# "conv.i" value : nativeint #)
+
+ static member inline op_Explicit(value: string) : char = (System.Char.Parse value)
+ static member inline op_Explicit(value: float) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: float32) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: int64) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: int32) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: int16) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: nativeint) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: sbyte) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: uint64) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: uint32) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: uint16) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: char) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: unativeint) : char = (# "conv.u2" value : char #)
+ static member inline op_Explicit(value: byte) : char = (# "conv.u2" value : char #)
+
+ static member inline op_LessThan(x: bool, y: bool) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: sbyte, y: sbyte) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: int16, y: int16) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: int32, y: int32) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: int64, y: int64) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: byte, y: byte) = (# "clt.un" x y : bool #)
+ static member inline op_LessThan(x: uint16, y: uint16) = (# "clt.un" x y : bool #)
+ static member inline op_LessThan(x: uint32, y: uint32) = (# "clt.un" x y : bool #)
+ static member inline op_LessThan(x: uint64, y: uint64) = (# "clt.un" x y : bool #)
+ static member inline op_LessThan(x: unativeint, y: unativeint) = (# "clt.un" x y : bool #)
+ static member inline op_LessThan(x: nativeint, y: nativeint) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: float, y: float) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: float32, y: float32) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: char, y: char) = (# "clt" x y : bool #)
+ static member inline op_LessThan(x: decimal, y: decimal) = Decimal.op_LessThan (x, y)
+ static member inline op_LessThan(x: string, y: string) = (# "clt" (String.CompareOrdinal(x,y)) 0 : bool #)
+
+ static member inline op_GreaterThan(x: bool, y: bool) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: sbyte, y: sbyte) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: int16, y: int16) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: int32, y: int32) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: int64, y: int64) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: nativeint, y: nativeint) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: byte, y: byte) = (# "cgt.un" x y : bool #)
+ static member inline op_GreaterThan(x: uint16, y: uint16) = (# "cgt.un" x y : bool #)
+ static member inline op_GreaterThan(x: uint32, y: uint32) = (# "cgt.un" x y : bool #)
+ static member inline op_GreaterThan(x: uint64, y: uint64) = (# "cgt.un" x y : bool #)
+ static member inline op_GreaterThan(x: unativeint, y: unativeint) = (# "cgt.un" x y : bool #)
+ static member inline op_GreaterThan(x: float, y: float) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: float32, y: float32) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: char, y: char) = (# "cgt" x y : bool #)
+ static member inline op_GreaterThan(x: decimal, y: decimal) = Decimal.op_GreaterThan (x, y)
+ static member inline op_GreaterThan(x: string, y: string) = (# "cgt" (String.CompareOrdinal(x, y)) 0 : bool #)
+
+ static member inline op_LessThanOrEqual(x: bool, y: bool) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: sbyte, y: sbyte) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: int16, y: int16) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: int32, y: int32) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: int64, y: int64) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: nativeint, y: nativeint) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: byte, y: byte) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: uint16, y: uint16) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: uint32, y: uint32) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: uint64, y: uint64) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: unativeint, y: unativeint) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: float, y: float) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: float32, y: float32) = not (# "cgt.un" x y : bool #)
+ static member inline op_LessThanOrEqual(x: char, y: char) = not (# "cgt" x y : bool #)
+ static member inline op_LessThanOrEqual(x: decimal, y: decimal) = Decimal.op_LessThanOrEqual (x, y)
+ static member inline op_LessThanOrEqual(x: string, y: string) = not (# "cgt" (String.CompareOrdinal(x, y)) 0 : bool #)
+
+ static member inline op_GreaterThanOrEqual(x: bool, y: bool) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: sbyte, y: sbyte) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: int16, y: int16) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: int32, y: int32) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: int64, y: int64) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: nativeint, y: nativeint) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: byte, y: byte) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: uint16, y: uint16) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: uint32, y: uint32) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: uint64, y: uint64) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: unativeint, y: unativeint) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: float, y: float) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: float32, y: float32) = not (# "clt.un" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: char, y: char) = not (# "clt" x y : bool #)
+ static member inline op_GreaterThanOrEqual(x: decimal, y: decimal) = Decimal.op_GreaterThanOrEqual (x, y)
+ static member inline op_GreaterThanOrEqual(x: string, y: string) = not (# "clt" (String.CompareOrdinal(x, y)) 0 : bool #)
+
+ static member inline op_Equality(x: bool, y: bool) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: sbyte, y: sbyte) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: int16, y: int16) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: int32, y: int32) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: int64, y: int64) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: byte, y: byte) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: uint16, y: uint16) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: uint32, y: uint32) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: uint64, y: uint64) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: float, y: float) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: float32, y: float32) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: char, y: char) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: nativeint, y: nativeint) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: unativeint, y: unativeint) = (# "ceq" x y : bool #)
+ static member inline op_Equality(x: string, y: string) = String.Equals(x, y)
+ static member inline op_Equality(x: decimal, y: decimal) = Decimal.op_Equality(x, y)
+
+ static member inline op_Inequality(x: bool, y: bool) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: sbyte, y: sbyte) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: int16, y: int16) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: int32, y: int32) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: int64, y: int64) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: byte, y: byte) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: uint16, y: uint16) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: uint32, y: uint32) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: uint64, y: uint64) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: float, y: float) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: float32, y: float32) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: char, y: char) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: nativeint, y: nativeint) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: unativeint, y: unativeint) = not (# "ceq" x y : bool #)
+ static member inline op_Inequality(x: string, y: string) = not (String.Equals(x, y))
+ static member inline op_Inequality(x: decimal, y: decimal) = Decimal.op_Inequality(x, y)
+
+ static member inline DivideByInt (x: decimal, n: int) = Decimal.Divide(x, Convert.ToDecimal(n))
+ static member inline DivideByInt (x: float, n: int) = (# "div" x ((# "conv.r8" n : float #)) : float #)
+ static member inline DivideByInt (x: float32, n:int) = (# "div" x ((# "conv.r4" n : float32 #)) : float32 #)
+#endif
- []
type GenericZeroDynamicImplTable<'T>() =
static let result : 'T =
// The dynamic implementation
@@ -2489,11 +3026,11 @@ namespace Microsoft.FSharp.Core
elif aty.Equals(typeof) then unboxPrim<'T> (box 0.0)
elif aty.Equals(typeof) then unboxPrim<'T> (box 0.0f)
else
- let pinfo = aty.GetProperty("Zero")
+ let pinfo = aty.GetTypeInfo().GetProperty("Zero")
unboxPrim<'T> (pinfo.GetValue(null,null))
static member Result : 'T = result
- []
+ // TODO: rationalise these
type GenericOneDynamicImplTable<'T>() =
static let result : 'T =
// The dynamic implementation
@@ -2513,7 +3050,7 @@ namespace Microsoft.FSharp.Core
elif aty.Equals(typeof) then unboxPrim<'T> (box 1.0)
elif aty.Equals(typeof) then unboxPrim<'T> (box 1.0f)
else
- let pinfo = aty.GetProperty("One")
+ let pinfo = aty.GetTypeInfo().GetProperty("One")
unboxPrim<'T> (pinfo.GetValue(null,null))
static member Result : 'T = result
@@ -2521,6 +3058,7 @@ namespace Microsoft.FSharp.Core
let GenericZeroDynamic<'T>() : 'T = GenericZeroDynamicImplTable<'T>.Result
let GenericOneDynamic<'T>() : 'T = GenericOneDynamicImplTable<'T>.Result
+ // TODO: rationalise these
let inline GenericZero< ^T when ^T : (static member Zero : ^T) > : ^T =
GenericZeroDynamic<(^T)>()
when ^T : int32 = 0
@@ -2537,10 +3075,10 @@ namespace Microsoft.FSharp.Core
when ^T : byte = 0uy
when ^T : decimal = 0M
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever ^T is resolved to a nominal type
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
when ^T : ^T = (^T : (static member Zero : ^T) ())
-
+ // TODO: rationalise these
let inline GenericOne< ^T when ^T : (static member One : ^T) > : ^T =
GenericOneDynamic<(^T)>()
when ^T : int32 = 1
@@ -2558,201 +3096,225 @@ namespace Microsoft.FSharp.Core
when ^T : byte = 1uy
when ^T : decimal = 1M
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever ^T is resolved to a nominal type
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
// That is, not in the generic implementation of '+'
when ^T : ^T = (^T : (static member One : ^T) ())
- []
- type GenericDivideByIntDynamicImplTable<'T>() =
- static let result : ('T -> int -> 'T) =
+ let UnaryDynamicImpl nm : ('T -> 'U) =
+ let aty = typeof<'T>
+#if FX_RESHAPED_REFLECTION
+ let minfo = aty.GetMethod(nm, [| aty |])
+#else
+ let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
+ let minfo = aty.GetMethod(nm, staticBindingFlags, null, [| aty |], null )
+#endif
+ (fun x -> unboxPrim<_>(minfo.Invoke(null,[| box x|])))
+
+ let BinaryDynamicImpl nm : ('T -> 'U -> 'V) =
+ let aty = typeof<'T>
+ let bty = typeof<'U>
+#if FX_RESHAPED_REFLECTION
+ let minfo = aty.GetMethod(nm,[| aty;bty |])
+#else
+ let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
+ let minfo = aty.GetMethod(nm, staticBindingFlags, null, [| aty; bty |], null )
+#endif
+ (fun x y -> unboxPrim<_>(minfo.Invoke(null,[| box x; box y|])))
+
+ // Dynamic implementation of operator resolution, using BuiltInWitnesses as backing data
+ type UnaryOpDynamicImplTable<'OpInfo,'T,'U>() =
+ static let impl : ('T -> 'U) =
// The dynamic implementation
let aty = typeof<'T>
- if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:decimal) (n:int) -> System.Decimal.Divide(x, System.Convert.ToDecimal(n))))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (n:int) -> (# "div" x ((# "conv.r8" n : float #)) : float #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (n:int) -> (# "div" x ((# "conv.r4" n : float32 #)) : float32 #)))
- else
- match aty.GetMethod("DivideByInt",[| aty; typeof |]) with
- | null -> raise (NotSupportedException (SR.GetString(SR.dyInvDivByIntCoerce)))
- | m -> (fun x n -> unboxPrim<_> (m.Invoke(null,[| box x; box n |])))
-
- static member Result : ('T -> int -> 'T) = result
+ let bty = typeof<'U>
- let DivideByIntDynamic<'T> x y = GenericDivideByIntDynamicImplTable<('T)>.Result x y
+ // Find the operator name
+#if FX_RESHAPED_REFLECTION
+ let opNameMeth = typeof<'OpInfo>.GetMethod("get_Name", [| |])
+#else
+ let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
+ let opNameMeth = typeof<'OpInfo>.GetMethod("get_Name", staticBindingFlags, null, [| |], null)
+#endif
+ let opName = opNameMeth.Invoke(null, [| |]) :?> string
+#if FX_RESHAPED_REFLECTION
+ let builtinNameMeth = typeof<'OpInfo>.GetTypeInfo().GetMethod("get_BuiltInName", [| |])
+#else
+ let builtinNameMeth = typeof<'OpInfo>.GetMethod("get_BuiltInName", staticBindingFlags, null, [| |], null)
+#endif
+ let builtinName = match builtinNameMeth with null -> opName | _ -> builtinNameMeth.Invoke(null, [| |]) :?> string
+
+ let meth =
+ let witnessesTy = typeof
+ let cmeth =
+ if builtinName.Equals("op_Explicit") then
+ let meths = witnessesTy.GetRuntimeMethods( (* staticBindingFlags *) )
+ let mutable res = null
+ for meth in meths do
+ if meth.Name.Equals(builtinName) then
+ if (IntrinsicFunctions.GetArray (meth.GetParameters()) 0).ParameterType.Equals(aty) then
+ if meth.ReturnType.Equals(bty) then
+ res <- meth
+ res
+ else
+#if FX_RESHAPED_REFLECTION
+ witnessesTy.GetMethod(builtinName, [| aty |])
+#else
+ witnessesTy.GetMethod(builtinName, staticBindingFlags, null, [| aty |], null)
+#endif
- let inline DivideByInt< ^T when ^T : (static member DivideByInt : ^T * int -> ^T) > (x:^T) (y:int) : ^T =
- DivideByIntDynamic<'T> x y
- when ^T : float = (# "div" x ((# "conv.r8" (y:int) : float #)) : float #)
- when ^T : float32 = (# "div" x ((# "conv.r4" (y:int) : float32 #)) : float32 #)
- when ^T : decimal = System.Decimal.Divide((retype x:decimal), System.Convert.ToDecimal(y))
- when ^T : ^T = (^T : (static member DivideByInt : ^T * int -> ^T) (x, y))
+ match cmeth with
+ | null ->
+#if FX_RESHAPED_REFLECTION
+ let ameth = aty.GetMethod(opName, [| aty |])
+#else
+ let ameth = aty.GetMethod(opName, staticBindingFlags, null, [| aty |], null)
+#endif
+ match ameth with
+ | null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce)))
+ | res -> res
+ | res -> res
+ (fun x -> unboxPrim<_> (meth.Invoke(null,[| box x |])))
+ static member Impl : ('T -> 'U) = impl
- // Dynamic implementation of addition operator resolution
- []
- type AdditionDynamicImplTable<'T,'U,'V>() =
+ // Dynamic implementation of operator resolution, using BuiltInWitnesses as backing data
+ type BinaryOpDynamicImplTable<'OpInfo,'T,'U,'V>() =
static let impl : ('T -> 'U -> 'V) =
// The dynamic implementation
let aty = typeof<'T>
let bty = typeof<'U>
- let cty = typeof<'V>
- let dyn() =
- let ameth = aty.GetMethod("op_Addition",[| aty; bty |])
- let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Addition",[| aty; bty |])
- match ameth,bmeth with
- | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce)))
- | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |])))
- | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddOverload)))
-
- if aty.Equals(bty) && bty.Equals(cty) then
- if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.i1" (# "add" x y : int32 #) : sbyte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.i2" (# "add" x y : int32 #) : int16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "add" x y : int32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "add" x y : int64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "add" x y : nativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.u1" (# "add" x y : uint32 #) : byte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.u2" (# "add" x y : uint32 #) : uint16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "add" x y : uint32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "add" x y : uint64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "add" x y : unativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "add" x y : float #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "add" x y : float32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y)))
- else dyn()
- else dyn()
+
+ // Find the operator name
+#if FX_RESHAPED_REFLECTION
+ let opNameMeth = typeof<'OpInfo>.GetMethod("get_Name", [| |])
+#else
+ let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
+ let opNameMeth = typeof<'OpInfo>.GetMethod("get_Name", staticBindingFlags, null, [| |], null)
+#endif
+ let opName = opNameMeth.Invoke(null, [| |]) :?> string
+#if FX_RESHAPED_REFLECTION
+ let builtinNameMeth = typeof<'OpInfo>.GetMethod("get_BuiltInName", [| |])
+#else
+ let builtinNameMeth = typeof<'OpInfo>.GetMethod("get_BuiltInName", staticBindingFlags, null, [| |], null)
+#endif
+ let builtinName = match builtinNameMeth with null -> opName | _ -> builtinNameMeth.Invoke(null, [| |]) :?> string
+
+ let meth =
+ let witnessesTy = typeof
+#if FX_RESHAPED_REFLECTION
+ let cmeth = witnessesTy.GetMethod(builtinName, [| aty; bty |])
+#else
+ let cmeth = witnessesTy.GetMethod(builtinName, staticBindingFlags, null, [| aty; bty |], null)
+#endif
+ match cmeth with
+ | null ->
+#if FX_RESHAPED_REFLECTION
+ let ameth = aty.GetMethod(opName, [| aty; bty |])
+#else
+ let ameth = aty.GetMethod(opName, staticBindingFlags, null, [| aty; bty |], null)
+#endif
+ let bmeth =
+ if aty.Equals(bty) then null else
+#if FX_RESHAPED_REFLECTION
+ bty.GetMethod(opName, [| aty; bty |])
+#else
+ bty.GetMethod(opName, staticBindingFlags, null, [| aty; bty |], null)
+#endif
+ match ameth, bmeth with
+ | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce)))
+ | m, null | null, m -> m
+ | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddOverload)))
+ | res -> res
+ (fun x y -> unboxPrim<_> (meth.Invoke(null,[| box x; box y |])))
static member Impl : ('T -> 'U -> 'V) = impl
- let AdditionDynamic<'T,'U,'V> x y = AdditionDynamicImplTable<'T,'U,'V>.Impl x y
+ type OpAdditionInfo = static member Name = "op_Addition"
+ let AdditionDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- // Dynamic implementation of checked addition operator resolution
- []
- type CheckedAdditionDynamicImplTable<'T,'U,'V>() =
- static let impl : ('T -> 'U -> 'V) =
- // The dynamic implementation
- let aty = typeof<'T>
- let bty = typeof<'U>
- let cty = typeof<'V>
- let dyn() =
- let ameth = aty.GetMethod("op_Addition",[| aty; bty |])
- let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Addition",[| aty; bty |])
- match ameth,bmeth with
- | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce)))
- | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |])))
- | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddOverload)))
-
- if aty.Equals(bty) && bty.Equals(cty) then
- if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.ovf.i1" (# "add.ovf" x y : int32 #) : sbyte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.ovf.i2" (# "add.ovf" x y : int32 #) : int16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "add.ovf" x y : int32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "add.ovf" x y : int64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "add.ovf" x y : nativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.ovf.u1.un" (# "add.ovf.un" x y : uint32 #) : byte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : uint16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:char) (y:char) -> (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : char #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "add.ovf.un" x y : uint32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "add.ovf.un" x y : uint64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "add.ovf.un" x y : unativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "add" x y : float #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "add" x y : float32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y)))
- else dyn()
- else dyn()
+ type OpSubtractionInfo = static member Name = "op_Subtraction"
+ let SubtractionDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+ type OpMultiplyInfo = static member Name = "op_Multiply"
+ let MultiplyDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- static member Impl : ('T -> 'U -> 'V) = impl
+ type OpDivisionInfo = static member Name = "op_Division"
+ let DivisionDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- let CheckedAdditionDynamic<'T,'U,'V> x y = CheckedAdditionDynamicImplTable<'T,'U,'V>.Impl x y
+ type OpModulusInfo = static member Name = "op_Modulus"
+ let ModulusDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+ type OpUnaryNegationInfo = static member Name = "op_UnaryNegation"
+ let UnaryNegationDynamic<'T,'U> value = UnaryOpDynamicImplTable.Impl value
- // Dynamic implementation of addition operator resolution
- []
- type MultiplyDynamicImplTable<'T,'U,'V>() =
- static let impl : ('T -> 'U -> 'V) =
- // The dynamic implementation
- let aty = typeof<'T>
- let bty = typeof<'U>
- let cty = typeof<'V>
- let dyn() =
- let ameth = aty.GetMethod("op_Multiply",[| aty; bty |])
- let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Multiply",[| aty; bty |])
- match ameth,bmeth with
- | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultCoerce)))
- | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |])))
- | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultOverload)))
-
- if aty.Equals(bty) && bty.Equals(cty) then
- if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.i1" (# "mul" x y : int32 #) : sbyte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.i2" (# "mul" x y : int32 #) : int16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "mul" x y : int32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "mul" x y : int64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "mul" x y : nativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.u1" (# "mul" x y : uint32 #) : byte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.u2" (# "mul" x y : uint32 #) : uint16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "mul" x y : uint32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "mul" x y : uint64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "mul" x y : unativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "mul" x y : float #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "mul" x y : float32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y)))
- else dyn()
- else dyn()
+ type OpCheckedAdditionInfo =
+ static member Name = "op_Addition"
+ static member BuiltInName = "op_CheckedAddition"
+ let CheckedAdditionDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- static member Impl : ('T -> 'U -> 'V) = impl
+ type OpCheckedSubtractionInfo =
+ static member Name = "op_Subtraction"
+ static member BuiltInName = "op_CheckedSubtraction"
+ let CheckedSubtractionDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- let MultiplyDynamic<'T,'U,'V> x y = MultiplyDynamicImplTable<'T,'U,'V>.Impl x y
+ type OpCheckedMultiplyInfo =
+ static member Name = "op_Multiply"
+ static member BuiltInName = "op_CheckedMultiply"
+ let CheckedMultiplyDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- // Dynamic implementation of checked addition operator resolution
- []
- type CheckedMultiplyDynamicImplTable<'T,'U,'V>() =
- static let impl : ('T -> 'U -> 'V) =
- // The dynamic implementation
- let aty = typeof<'T>
- let bty = typeof<'U>
- let cty = typeof<'V>
- let dyn() =
- let ameth = aty.GetMethod("op_Multiply",[| aty; bty |])
- let bmeth = if aty.Equals(bty) then null else bty.GetMethod("op_Multiply",[| aty; bty |])
- match ameth,bmeth with
- | null, null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultCoerce)))
- | m,null | null,m -> (fun x y -> unboxPrim<_> (m.Invoke(null,[| box x; box y |])))
- | _ -> raise (NotSupportedException (SR.GetString(SR.dyInvOpMultOverload)))
-
- if aty.Equals(bty) && bty.Equals(cty) then
- if aty.Equals(typeof) then unboxPrim<_> (box (fun (x:sbyte) (y:sbyte) -> (# "conv.ovf.i1" (# "mul.ovf" x y : int32 #) : sbyte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int16) (y:int16) -> (# "conv.ovf.i2" (# "mul.ovf" x y : int32 #) : int16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int32) (y:int32) -> (# "mul.ovf" x y : int32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:int64) (y:int64) -> (# "mul.ovf" x y : int64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:nativeint) (y:nativeint) -> (# "mul.ovf" x y : nativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:byte) (y:byte) -> (# "conv.ovf.u1.un" (# "mul.ovf.un" x y : uint32 #) : byte #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint16) (y:uint16) -> (# "conv.ovf.u2.un" (# "mul.ovf.un" x y : uint16 #) : uint16 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint32) (y:uint32) -> (# "mul.ovf.un" x y : uint32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:uint64) (y:uint64) -> (# "mul.ovf.un" x y : uint64 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:unativeint) (y:unativeint) -> (# "mul.ovf.un" x y : unativeint #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float) (y:float) -> (# "mul" x y : float #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:float32) (y:float32) -> (# "mul" x y : float32 #)))
- elif aty.Equals(typeof) then unboxPrim<_> (box (fun (x:string) (y:string) -> System.String.Concat(x,y)))
- else dyn()
- else dyn()
+ type OpCheckedUnaryNegationInfo =
+ static member Name = "op_UnaryNegation"
+ static member BuiltInName = "op_CheckedUnaryNegation"
+ let CheckedUnaryNegationDynamic<'T,'U> value = UnaryOpDynamicImplTable.Impl value
- static member Impl : ('T -> 'U -> 'V) = impl
+ type OpLeftShiftInfo = static member Name = "op_LeftShift"
+ let OpLeftShiftDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- let CheckedMultiplyDynamic<'T,'U,'V> x y = CheckedMultiplyDynamicImplTable<'T,'U,'V>.Impl x y
+ type OpRightShiftInfo = static member Name = "op_RightShift"
+ let OpRightShiftDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+ type OpBitwiseAndInfo = static member Name = "op_BitwiseAnd"
+ let OpBitwiseAndDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
-namespace System
+ type OpBitwiseOrInfo = static member Name = "op_BitwiseOr"
+ let OpBitwiseOrDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
- open System
- open System.Collections
- open System.Collections.Generic
- open System.Diagnostics
- open System.Globalization
- open System.Text
- open Microsoft.FSharp.Core
- open Microsoft.FSharp.Core.BasicInlinedOperations
- open Microsoft.FSharp.Core.LanguagePrimitives
- open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
- open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions
+ type OpBitwiseExclusiveOrInfo = static member Name = "op_ExclusiveOr"
+ let OpBitwiseExclusiveOrDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type OpLogicalNotInfo = static member Name = "op_LogicalNot"
+ let OpLogicalNotDynamic<'T,'U> x = UnaryOpDynamicImplTable.Impl x
+ type OpExplicitInfo = static member Name = "op_Explicit"
+ let OpExplicitDynamic<'T,'U> x = UnaryOpDynamicImplTable.Impl x
+
+ type OpLessThanInfo = static member Name = "op_LessThan"
+ let OpLessThanDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type OpGreaterThanInfo = static member Name = "op_GreaterThan"
+ let OpGreaterThanDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type OpLessThanOrEqualInfo = static member Name = "op_LessThanOrEqual"
+ let OpLessThanOrEqualDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type OpGreaterThanOrEqualInfo = static member Name = "op_GreaterThanOrEqual"
+ let OpGreaterThanOrEqualDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type OpEqualityInfo = static member Name = "op_Equality"
+ let OpEqualityDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type OpInequalityInfo = static member Name = "op_Inequality"
+ let OpInequalityDynamic<'T,'U,'V> x y = BinaryOpDynamicImplTable.Impl x y
+
+ type DivideByIntInfo = static member Name = "DivideByInt"
+ let DivideByIntDynamic<'T> x y = BinaryOpDynamicImplTable.Impl x y
+
+ let inline DivideByInt< ^T when ^T : (static member DivideByInt : ^T * int -> ^T) > (x: ^T) (y: int) : ^T =
+ DivideByIntDynamic<'T> x y
+ when ^T : float = (# "div" x ((# "conv.r8" y : float #)) : float #)
+ when ^T : float32 = (# "div" x ((# "conv.r4" y : float32 #)) : float32 #)
+ when ^T : decimal = Decimal.Divide((# "" x : decimal #), Convert.ToDecimal(y))
+ when ^T : ^T = (^T : (static member DivideByInt : ^T * int -> ^T) (x, y))
namespace Microsoft.FSharp.Core
@@ -3117,10 +3679,7 @@ namespace Microsoft.FSharp.Core
namespace Microsoft.FSharp.Collections
- //-------------------------------------------------------------------------
- // Lists
- //-------------------------------------------------------------------------
-
+ open System
open System.Collections.Generic
open System.Diagnostics
open Microsoft.FSharp.Core
@@ -3180,10 +3739,6 @@ namespace Microsoft.FSharp.Collections
type ResizeArray<'T> = System.Collections.Generic.List<'T>
- //-------------------------------------------------------------------------
- // List (augmentation)
- //-------------------------------------------------------------------------
-
module PrivateListHelpers =
let notStarted() = raise (new System.InvalidOperationException(SR.GetString(SR.enumerationNotStarted)))
@@ -3293,7 +3848,7 @@ namespace Microsoft.FSharp.Collections
let n = l.Length
let txt =
if n > 1000 then "Length > 1000"
- else System.String.Concat( [| "Length = "; n.ToString() |])
+ else String.Concat( [| "Length = "; n.ToString() |])
txt
member l.Head = match l with a :: _ -> a | [] -> raise (System.InvalidOperationException(SR.GetString(SR.inputListWasEmpty)))
@@ -3477,7 +4032,7 @@ namespace Microsoft.FSharp.Core
let inline (<<) func2 func1 x = func2 (func1 x)
- let (^) (s1: string) (s2: string) = System.String.Concat(s1, s2)
+ let (^) (s1: string) (s2: string) = String.Concat(s1, s2)
[]
let defaultArg arg defaultValue = match arg with None -> defaultValue | Some v -> v
@@ -3485,9 +4040,8 @@ namespace Microsoft.FSharp.Core
[]
let defaultValueArg arg defaultValue = match arg with ValueNone -> defaultValue | ValueSome v -> v
- []
let inline (~-) (n: ^T) : ^T =
- (^T : (static member (~-) : ^T -> ^T) (n))
+ UnaryNegationDynamic<(^T), (^T)> n
when ^T : int32 = (# "neg" n : int32 #)
when ^T : float = (# "neg" n : float #)
when ^T : float32 = (# "neg" n : float32 #)
@@ -3495,8 +4049,11 @@ namespace Microsoft.FSharp.Core
when ^T : int16 = (# "neg" n : int16 #)
when ^T : nativeint = (# "neg" n : nativeint #)
when ^T : sbyte = (# "neg" n : sbyte #)
- when ^T : decimal = (# "" (System.Decimal.op_UnaryNegation((# "" n : decimal #))) : ^T #)
-
+ when ^T : decimal = (# "" (Decimal.op_UnaryNegation((# "" n : decimal #))) : ^T #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member (~-) : ^T -> ^T) (n))
let inline (+) (x: ^T) (y: ^U) : ^V =
AdditionDynamic<(^T),(^U),(^V)> x y
@@ -3513,17 +4070,14 @@ namespace Microsoft.FSharp.Core
when ^T : char and ^U : char = (# "conv.u2" (# "add" x y : uint32 #) : char #)
when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "add" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.u1" (# "add" x y : uint32 #) : byte #)
- when ^T : string and ^U : string = (# "" (System.String.Concat((# "" x : string #),(# "" y : string #))) : ^T #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Addition((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
-
+ when ^T : string and ^U : string = (# "" (String.Concat((# "" x : string #),(# "" y : string #))) : ^T #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Addition((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever ^T is resolved to a nominal type
- // That is, not in the generic implementation of '+'
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
when ^T : ^T = ((^T or ^U): (static member (+) : ^T * ^U -> ^V) (x,y))
- []
let inline (-) (x: ^T) (y: ^U) : ^V =
- ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y))
+ SubtractionDynamic<(^T),(^U),(^V)> x y
when ^T : int32 and ^U : int32 = (# "sub" x y : int32 #)
when ^T : float and ^U : float = (# "sub" x y : float #)
when ^T : float32 and ^U : float32 = (# "sub" x y : float32 #)
@@ -3536,8 +4090,10 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 and ^U : uint16 = (# "conv.u2" (# "sub" x y : uint32 #) : uint16 #)
when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "sub" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.u1" (# "sub" x y : uint32 #) : byte #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Subtraction((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
-
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Subtraction((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y))
let inline ( * ) (x: ^T) (y: ^U) : ^V =
MultiplyDynamic<(^T),(^U),(^V)> x y
@@ -3553,15 +4109,13 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 and ^U : uint16 = (# "conv.u2" (# "mul" x y : uint32 #) : uint16 #)
when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "mul" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.u1" (# "mul" x y : uint32 #) : byte #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Multiply((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Multiply((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever ^T is resolved to a nominal type
- // That is, not in the generic implementation of '*'
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
when ^T : ^T = ((^T or ^U): (static member (*) : ^T * ^U -> ^V) (x,y))
- []
let inline ( / ) (x: ^T) (y: ^U) : ^V =
- ((^T or ^U): (static member (/) : ^T * ^U -> ^V) (x,y))
+ DivisionDynamic<(^T),(^U),(^V)> x y
when ^T : int32 and ^U : int32 = (# "div" x y : int32 #)
when ^T : float and ^U : float = (# "div" x y : float #)
when ^T : float32 and ^U : float32 = (# "div" x y : float32 #)
@@ -3574,11 +4128,13 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 and ^U : uint16 = (# "conv.u2" (# "div.un" x y : uint32 #) : uint16 #)
when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "div" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.u1" (# "div.un" x y : uint32 #) : byte #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Division((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Division((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (/) : ^T * ^U -> ^V) (x,y))
- []
let inline ( % ) (x: ^T) (y: ^U) : ^V =
- ((^T or ^U): (static member (%) : ^T * ^U -> ^V) (x,y))
+ ModulusDynamic<(^T),(^U),(^V)> x y
when ^T : int32 and ^U : int32 = (# "rem" x y : int32 #)
when ^T : float and ^U : float = (# "rem" x y : float #)
when ^T : float32 and ^U : float32 = (# "rem" x y : float32 #)
@@ -3591,11 +4147,13 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 and ^U : uint16 = (# "conv.u2" (# "rem.un" x y : uint32 #) : uint16 #)
when ^T : sbyte and ^U : sbyte = (# "conv.i1" (# "rem" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.u1" (# "rem.un" x y : uint32 #) : byte #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Modulus((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Modulus((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (%) : ^T * ^U -> ^V) (x,y))
- []
let inline (~+) (value: ^T) : ^T =
- (^T: (static member (~+) : ^T -> ^T) (value))
+ value
when ^T : int32 = value
when ^T : float = value
when ^T : float32 = value
@@ -3609,12 +4167,10 @@ namespace Microsoft.FSharp.Core
when ^T : sbyte = value
when ^T : byte = value
when ^T : decimal = value
+ when ^T : ^T = (^T: (static member (~+) : ^T -> ^T) (value))
- let inline mask (n:int) (m:int) = (# "and" n m : int #)
-
- []
let inline (<<<) (value: ^T) (shift:int) : ^T =
- (^T: (static member (<<<) : ^T * int -> ^T) (value,shift))
+ OpLeftShiftDynamic<(^T),int,(^T)> value shift
when ^T : int32 = (# "shl" value (mask shift 31) : int #)
when ^T : uint32 = (# "shl" value (mask shift 31) : uint32 #)
when ^T : int64 = (# "shl" value (mask shift 63) : int64 #)
@@ -3625,10 +4181,12 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 = (# "conv.u2" (# "shl" value (mask shift 15) : uint32 #) : uint16 #)
when ^T : sbyte = (# "conv.i1" (# "shl" value (mask shift 7 ) : int32 #) : sbyte #)
when ^T : byte = (# "conv.u1" (# "shl" value (mask shift 7 ) : uint32 #) : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T: (static member (<<<) : ^T * int -> ^T) (value,shift))
- []
let inline (>>>) (value: ^T) (shift:int) : ^T =
- (^T: (static member (>>>) : ^T * int -> ^T) (value,shift))
+ OpRightShiftDynamic<(^T),int,(^T)> value shift
when ^T : int32 = (# "shr" value (mask shift 31) : int32 #)
when ^T : uint32 = (# "shr.un" value (mask shift 31) : uint32 #)
when ^T : int64 = (# "shr" value (mask shift 63) : int64 #)
@@ -3639,10 +4197,12 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 = (# "conv.u2" (# "shr.un" value (mask shift 15) : uint32 #) : uint16 #)
when ^T : sbyte = (# "conv.i1" (# "shr" value (mask shift 7 ) : int32 #) : sbyte #)
when ^T : byte = (# "conv.u1" (# "shr.un" value (mask shift 7 ) : uint32 #) : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T: (static member (>>>) : ^T * int -> ^T) (value, shift))
- []
let inline (&&&) (x: ^T) (y: ^T) : ^T =
- (^T: (static member (&&&) : ^T * ^T -> ^T) (x,y))
+ OpBitwiseAndDynamic<(^T),(^T),(^T)> x y
when ^T : int32 = (# "and" x y : int32 #)
when ^T : int64 = (# "and" x y : int64 #)
when ^T : uint64 = (# "and" x y : uint64 #)
@@ -3653,10 +4213,12 @@ namespace Microsoft.FSharp.Core
when ^T : unativeint = (# "and" x y : unativeint #)
when ^T : sbyte = (# "and" x y : sbyte #)
when ^T : byte = (# "and" x y : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T: (static member (&&&) : ^T * ^T -> ^T) (x, y))
- []
let inline (|||) (x: ^T) (y: ^T) : ^T =
- (^T: (static member (|||) : ^T * ^T -> ^T) (x,y))
+ OpBitwiseOrDynamic<(^T),(^T),(^T)> x y
when ^T : int32 = (# "or" x y : int32 #)
when ^T : int64 = (# "or" x y : int64 #)
when ^T : uint64 = (# "or" x y : uint64 #)
@@ -3667,10 +4229,12 @@ namespace Microsoft.FSharp.Core
when ^T : unativeint = (# "or" x y : unativeint #)
when ^T : sbyte = (# "or" x y : sbyte #)
when ^T : byte = (# "or" x y : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T: (static member (|||) : ^T * ^T -> ^T) (x, y))
- []
let inline (^^^) (x: ^T) (y: ^T) : ^T =
- (^T: (static member (^^^) : ^T * ^T -> ^T) (x,y))
+ OpBitwiseExclusiveOrDynamic<(^T),(^T),(^T)> x y
when ^T : int32 = (# "xor" x y : int32 #)
when ^T : int64 = (# "xor" x y : int64 #)
when ^T : uint64 = (# "xor" x y : uint64 #)
@@ -3681,10 +4245,12 @@ namespace Microsoft.FSharp.Core
when ^T : unativeint = (# "xor" x y : unativeint #)
when ^T : sbyte = (# "xor" x y : sbyte #)
when ^T : byte = (# "xor" x y : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T: (static member (^^^) : ^T * ^T -> ^T) (x, y))
- []
let inline (~~~) (value: ^T) : ^T =
- (^T: (static member (~~~) : ^T -> ^T) (value))
+ OpLogicalNotDynamic<(^T),(^T)> value
when ^T : int32 = (# "not" value : int32 #)
when ^T : int64 = (# "not" value : int64 #)
when ^T : uint64 = (# "not" value : uint64 #)
@@ -3695,6 +4261,9 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 = (# "conv.u2" (# "not" value : uint32 #) : uint16 #)
when ^T : sbyte = (# "conv.i1" (# "not" value : int32 #) : sbyte #)
when ^T : byte = (# "conv.u1" (# "not" value : uint32 #) : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T: (static member (~~~) : ^T -> ^T) (value))
let inline castToString (x:'T) = (# "" x : string #) // internal
@@ -3723,21 +4292,10 @@ namespace Microsoft.FSharp.Core
[]
let exit (exitcode:int) = System.Environment.Exit(exitcode); failwith "System.Environment.Exit did not exit!"
- let inline parseByte (s:string) = (# "conv.ovf.u1" (ParseUInt32 s) : byte #)
- let inline ParseSByte (s:string) = (# "conv.ovf.i1" (ParseInt32 s) : sbyte #)
- let inline ParseInt16 (s:string) = (# "conv.ovf.i2" (ParseInt32 s) : int16 #)
- let inline ParseUInt16 (s:string) = (# "conv.ovf.u2" (ParseUInt32 s) : uint16 #)
- let inline ParseIntPtr (s:string) = (# "conv.ovf.i" (ParseInt64 s) : nativeint #)
- let inline ParseUIntPtr (s:string) = (# "conv.ovf.u" (ParseInt64 s) : unativeint #)
- let inline ParseDouble (s:string) = Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
- let inline ParseSingle (s:string) = Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
-
-
- []
[]
let inline byte (value: ^T) =
- (^T : (static member op_Explicit: ^T -> byte) (value))
- when ^T : string = parseByte (castToString value)
+ OpExplicitDynamic<(^T), byte> value
+ when ^T : string = ParseByte (castToString value)
when ^T : float = (# "conv.u1" value : byte #)
when ^T : float32 = (# "conv.u1" value : byte #)
when ^T : int64 = (# "conv.u1" value : byte #)
@@ -3751,11 +4309,13 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.u1" value : byte #)
when ^T : unativeint = (# "conv.u1" value : byte #)
when ^T : byte = (# "conv.u1" value : byte #)
-
- []
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> byte) (value))
+
[]
let inline sbyte (value: ^T) =
- (^T : (static member op_Explicit: ^T -> sbyte) (value))
+ OpExplicitDynamic<(^T), sbyte> value
when ^T : string = ParseSByte (castToString value)
when ^T : float = (# "conv.i1" value : sbyte #)
when ^T : float32 = (# "conv.i1" value : sbyte #)
@@ -3770,11 +4330,13 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.i1" value : sbyte #)
when ^T : unativeint = (# "conv.i1" value : sbyte #)
when ^T : byte = (# "conv.i1" value : sbyte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> sbyte) (value))
- []
[]
let inline uint16 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> uint16) (value))
+ OpExplicitDynamic<(^T), uint16> value
when ^T : string = ParseUInt16 (castToString value)
when ^T : float = (# "conv.u2" value : uint16 #)
when ^T : float32 = (# "conv.u2" value : uint16 #)
@@ -3789,11 +4351,13 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.u2" value : uint16 #)
when ^T : unativeint = (# "conv.u2" value : uint16 #)
when ^T : byte = (# "conv.u2" value : uint16 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint16) (value))
- []
[]
let inline int16 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> int16) (value))
+ OpExplicitDynamic<(^T), int16> value
when ^T : string = ParseInt16 (castToString value)
when ^T : float = (# "conv.i2" value : int16 #)
when ^T : float32 = (# "conv.i2" value : int16 #)
@@ -3808,18 +4372,18 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.i2" value : int16 #)
when ^T : unativeint = (# "conv.i2" value : int16 #)
when ^T : byte = (# "conv.i2" value : int16 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> int16) (value))
- []
[]
let inline uint32 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> uint32) (value))
+ OpExplicitDynamic<(^T), uint32> value
when ^T : string = ParseUInt32 (castToString value)
when ^T : float = (# "conv.u4" value : uint32 #)
when ^T : float32 = (# "conv.u4" value : uint32 #)
-
when ^T : int64 = (# "conv.u4" value : uint32 #)
when ^T : nativeint = (# "conv.u4" value : uint32 #)
-
// For integers shorter that 32 bits, we must first
// sign-widen the signed integer to 32 bits, and then
// "convert" from signed int32 to unsigned int32
@@ -3827,36 +4391,38 @@ namespace Microsoft.FSharp.Core
when ^T : int32 = (# "" value : uint32 #)
when ^T : int16 = (# "" value : uint32 #)
when ^T : sbyte = (# "" value : uint32 #)
-
when ^T : uint64 = (# "conv.u4" value : uint32 #)
when ^T : uint32 = (# "conv.u4" value : uint32 #)
when ^T : uint16 = (# "conv.u4" value : uint32 #)
when ^T : char = (# "conv.u4" value : uint32 #)
when ^T : unativeint = (# "conv.u4" value : uint32 #)
when ^T : byte = (# "conv.u4" value : uint32 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint32) (value))
- []
[]
let inline int32 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> int32) (value))
+ OpExplicitDynamic<(^T), int32> value
when ^T : string = ParseInt32 (castToString value)
when ^T : float = (# "conv.i4" value : int32 #)
when ^T : float32 = (# "conv.i4" value : int32 #)
when ^T : int64 = (# "conv.i4" value : int32 #)
when ^T : nativeint = (# "conv.i4" value : int32 #)
-
// For integers shorter that 32 bits, we sign-widen the signed integer to 32 bits
// This is a no-op on IL stack (ECMA 335 Part III 1.5 Tables 8 & 9)
when ^T : int32 = (# "" value : int32 #)
when ^T : int16 = (# "" value : int32 #)
when ^T : sbyte = (# "" value : int32 #)
-
when ^T : uint64 = (# "conv.i4" value : int32 #)
when ^T : uint32 = (# "" value : int32 #) // Signed<->Unsigned conversion is a no-op on IL stack
when ^T : uint16 = (# "conv.i4" value : int32 #)
when ^T : char = (# "conv.i4" value : int32 #)
when ^T : unativeint = (# "conv.i4" value : int32 #)
when ^T : byte = (# "conv.i4" value : int32 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> int32) (value))
[]
let inline int value = int32 value
@@ -3879,14 +4445,12 @@ namespace Microsoft.FSharp.Core
[]
let nanf = System.Single.NaN
- []
[]
let inline uint64 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> uint64) (value))
+ OpExplicitDynamic<(^T), uint64> value
when ^T : string = ParseUInt64 (castToString value)
when ^T : float = (# "conv.u8" value : uint64 #)
when ^T : float32 = (# "conv.u8" value : uint64 #)
-
// we must first sign-widen the signed integer to 64 bits, and then
// "convert" from signed int64 to unsigned int64
// conv.i8 sign-widens the input, and on IL stack,
@@ -3896,19 +4460,19 @@ namespace Microsoft.FSharp.Core
when ^T : int16 = (# "conv.i8" value : uint64 #)
when ^T : nativeint = (# "conv.i8" value : uint64 #)
when ^T : sbyte = (# "conv.i8" value : uint64 #)
-
-
when ^T : uint64 = (# "" value : uint64 #)
when ^T : uint32 = (# "conv.u8" value : uint64 #)
when ^T : uint16 = (# "conv.u8" value : uint64 #)
when ^T : char = (# "conv.u8" value : uint64 #)
when ^T : unativeint = (# "conv.u8" value : uint64 #)
when ^T : byte = (# "conv.u8" value : uint64 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint64) (value))
- []
[]
let inline int64 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> int64) (value))
+ OpExplicitDynamic<(^T), int64> value
when ^T : string = ParseInt64 (castToString value)
when ^T : float = (# "conv.i8" value : int64 #)
when ^T : float32 = (# "conv.i8" value : int64 #)
@@ -3917,7 +4481,6 @@ namespace Microsoft.FSharp.Core
when ^T : int16 = (# "conv.i8" value : int64 #)
when ^T : nativeint = (# "conv.i8" value : int64 #)
when ^T : sbyte = (# "conv.i8" value : int64 #)
-
// When converting unsigned integer, we should zero-widen them, NOT sign-widen
// No-op for uint64, conv.u8 for uint32, for smaller types conv.u8 and conv.i8 are identical.
// For nativeint, conv.u8 works correctly both in 32 bit and 64 bit case.
@@ -3927,11 +4490,13 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.u8" value : int64 #)
when ^T : unativeint = (# "conv.u8" value : int64 #)
when ^T : byte = (# "conv.u8" value : int64 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> int64) (value))
- []
[]
let inline float32 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> float32) (value))
+ OpExplicitDynamic<(^T), float32> value
when ^T : string = ParseSingle (castToString value)
when ^T : float = (# "conv.r4" value : float32 #)
// NOTE: float32 should convert its argument to 32-bit float even when applied to a higher precision float stored in a register. See devdiv2#49888.
@@ -3947,11 +4512,13 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.r.un conv.r4" value : float32 #)
when ^T : unativeint = (# "conv.r.un conv.r4" value : float32 #)
when ^T : byte = (# "conv.r.un conv.r4" value : float32 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> float32) (value))
- []
[]
let inline float (value: ^T) =
- (^T : (static member op_Explicit: ^T -> float) (value))
+ OpExplicitDynamic<(^T), float> value
when ^T : string = ParseDouble (castToString value)
// NOTE: float should convert its argument to 64-bit float even when applied to a higher precision float stored in a register. See devdiv2#49888.
when ^T : float = (# "conv.r8" value : float #)
@@ -3967,40 +4534,38 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.r.un conv.r8" value : float #)
when ^T : unativeint = (# "conv.r.un conv.r8" value : float #)
when ^T : byte = (# "conv.r.un conv.r8" value : float #)
- when ^T : decimal = (System.Convert.ToDouble((# "" value : decimal #)))
+ when ^T : decimal = (Convert.ToDouble((# "" value : decimal #)))
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> float) (value))
- []
[]
let inline decimal (value: ^T) =
- (^T : (static member op_Explicit: ^T -> decimal) (value))
- when ^T : string = (System.Decimal.Parse(castToString value,NumberStyles.Float,CultureInfo.InvariantCulture))
- when ^T : float = (System.Convert.ToDecimal((# "" value : float #)))
- when ^T : float32 = (System.Convert.ToDecimal((# "" value : float32 #)))
- when ^T : int64 = (System.Convert.ToDecimal((# "" value : int64 #)))
- when ^T : int32 = (System.Convert.ToDecimal((# "" value : int32 #)))
- when ^T : int16 = (System.Convert.ToDecimal((# "" value : int16 #)))
- when ^T : nativeint = (System.Convert.ToDecimal(int64 (# "" value : nativeint #)))
- when ^T : sbyte = (System.Convert.ToDecimal((# "" value : sbyte #)))
- when ^T : uint64 = (System.Convert.ToDecimal((# "" value : uint64 #)))
- when ^T : uint32 = (System.Convert.ToDecimal((# "" value : uint32 #)))
- when ^T : uint16 = (System.Convert.ToDecimal((# "" value : uint16 #)))
- when ^T : unativeint = (System.Convert.ToDecimal(uint64 (# "" value : unativeint #)))
- when ^T : byte = (System.Convert.ToDecimal((# "" value : byte #)))
+ OpExplicitDynamic<(^T), decimal> value
+ when ^T : string = (Decimal.Parse(castToString value,NumberStyles.Float,CultureInfo.InvariantCulture))
+ when ^T : float = (Convert.ToDecimal((# "" value : float #)))
+ when ^T : float32 = (Convert.ToDecimal((# "" value : float32 #)))
+ when ^T : int64 = (Convert.ToDecimal((# "" value : int64 #)))
+ when ^T : int32 = (Convert.ToDecimal((# "" value : int32 #)))
+ when ^T : int16 = (Convert.ToDecimal((# "" value : int16 #)))
+ when ^T : nativeint = (Convert.ToDecimal(int64 (# "" value : nativeint #)))
+ when ^T : sbyte = (Convert.ToDecimal((# "" value : sbyte #)))
+ when ^T : uint64 = (Convert.ToDecimal((# "" value : uint64 #)))
+ when ^T : uint32 = (Convert.ToDecimal((# "" value : uint32 #)))
+ when ^T : uint16 = (Convert.ToDecimal((# "" value : uint16 #)))
+ when ^T : unativeint = (Convert.ToDecimal(uint64 (# "" value : unativeint #)))
+ when ^T : byte = (Convert.ToDecimal((# "" value : byte #)))
when ^T : decimal = (# "" value : decimal #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> decimal) (value))
- // Recall type names.
- // Framework names: sbyte, byte, int16, uint16, int32, uint32, int64, uint64, single, double.
- // C# names: sbyte, byte, short, ushort, int, uint, long, ulong, single, double.
- // F# names: sbyte, byte, int16, uint16, int, uint32, int64, uint64, float32, float.
-
- []
[]
let inline unativeint (value: ^T) =
- (^T : (static member op_Explicit: ^T -> unativeint) (value))
+ OpExplicitDynamic<(^T), unativeint> value
when ^T : string = ParseUIntPtr (castToString value)
when ^T : float = (# "conv.u" value : unativeint #)
when ^T : float32 = (# "conv.u" value : unativeint #)
-
// Narrower signed types we sign-extend.
// Same length signed types we leave as such (so -1 gets reinterpreted as unsigned MaxValue).
// Wider signed types we truncate.
@@ -4010,28 +4575,27 @@ namespace Microsoft.FSharp.Core
when ^T : int16 = (# "conv.i" value : unativeint #)
when ^T : nativeint = (# "" value : unativeint #)
when ^T : sbyte = (# "conv.i" value : unativeint #)
-
when ^T : uint64 = (# "conv.u" value : unativeint #)
when ^T : uint32 = (# "conv.u" value : unativeint #)
when ^T : uint16 = (# "conv.u" value : unativeint #)
when ^T : char = (# "conv.u" value : unativeint #)
when ^T : unativeint = (# "" value : unativeint #)
when ^T : byte = (# "conv.u" value : unativeint #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value))
- []
[]
let inline nativeint (value: ^T) =
- (^T : (static member op_Explicit: ^T -> nativeint) (value))
+ OpExplicitDynamic<(^T), nativeint> value
when ^T : string = ParseIntPtr (castToString value)
when ^T : float = (# "conv.i" value : nativeint #)
when ^T : float32 = (# "conv.i" value : nativeint #)
-
when ^T : int64 = (# "conv.i" value : nativeint #)
when ^T : int32 = (# "conv.i" value : nativeint #)
when ^T : int16 = (# "conv.i" value : nativeint #)
when ^T : nativeint = (# "conv.i" value : nativeint #)
when ^T : sbyte = (# "conv.i" value : nativeint #)
-
// Narrower unsigned types we zero-extend.
// Same length unsigned types we leave as such (so unsigned MaxValue (all-bits-set) gets reinterpreted as -1).
// Wider unsigned types we truncate.
@@ -4042,6 +4606,9 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.u" value : nativeint #)
when ^T : unativeint = (# "" value : nativeint #)
when ^T : byte = (# "conv.i" value : nativeint #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value))
[]
let inline string (value: ^T) =
@@ -4062,10 +4629,9 @@ namespace Microsoft.FSharp.Core
when ^T : unativeint = (# "" value : unativeint #).ToString()
when ^T : byte = (# "" value : byte #).ToString("g",CultureInfo.InvariantCulture)
- []
[]
let inline char (value: ^T) =
- (^T : (static member op_Explicit: ^T -> char) (value))
+ OpExplicitDynamic<(^T), char> value
when ^T : string = (System.Char.Parse(castToString value))
when ^T : float = (# "conv.u2" value : char #)
when ^T : float32 = (# "conv.u2" value : char #)
@@ -4080,12 +4646,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.u2" value : char #)
when ^T : unativeint = (# "conv.u2" value : char #)
when ^T : byte = (# "conv.u2" value : char #)
-
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> char) (value))
module NonStructuralComparison =
/// Static less-than with static optimizations for some well-known cases.
let inline (<) (x:^T) (y:^U) =
- ((^T or ^U): (static member (<) : ^T * ^U -> bool) (x,y))
+ OpLessThanDynamic<(^T), (^U), bool> x y
when ^T : bool = (# "clt" x y : bool #)
when ^T : sbyte = (# "clt" x y : bool #)
when ^T : int16 = (# "clt" x y : bool #)
@@ -4100,12 +4668,15 @@ namespace Microsoft.FSharp.Core
when ^T : float = (# "clt" x y : bool #)
when ^T : float32= (# "clt" x y : bool #)
when ^T : char = (# "clt" x y : bool #)
- when ^T : decimal = System.Decimal.op_LessThan ((# "" x:decimal #), (# "" y:decimal #))
- when ^T : string = (# "clt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ when ^T : decimal = Decimal.op_LessThan ((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : string = (# "clt" (String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (<) : ^T * ^U -> bool) (x,y))
/// Static greater-than with static optimizations for some well-known cases.
let inline (>) (x:^T) (y:^U) =
- ((^T or ^U): (static member (>) : ^T * ^U -> bool) (x,y))
+ OpGreaterThanDynamic<(^T), (^U), bool> x y
when 'T : bool = (# "cgt" x y : bool #)
when 'T : sbyte = (# "cgt" x y : bool #)
when 'T : int16 = (# "cgt" x y : bool #)
@@ -4120,12 +4691,15 @@ namespace Microsoft.FSharp.Core
when 'T : float = (# "cgt" x y : bool #)
when 'T : float32 = (# "cgt" x y : bool #)
when 'T : char = (# "cgt" x y : bool #)
- when 'T : decimal = System.Decimal.op_GreaterThan ((# "" x:decimal #), (# "" y:decimal #))
- when ^T : string = (# "cgt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ when 'T : decimal = Decimal.op_GreaterThan ((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : string = (# "cgt" (String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (>) : ^T * ^U -> bool) (x,y))
/// Static less-than-or-equal with static optimizations for some well-known cases.
let inline (<=) (x:^T) (y:^U) =
- ((^T or ^U): (static member (<=) : ^T * ^U -> bool) (x,y))
+ OpLessThanOrEqualDynamic<(^T), (^U), bool> x y
when 'T : bool = not (# "cgt" x y : bool #)
when 'T : sbyte = not (# "cgt" x y : bool #)
when 'T : int16 = not (# "cgt" x y : bool #)
@@ -4140,12 +4714,15 @@ namespace Microsoft.FSharp.Core
when 'T : float = not (# "cgt.un" x y : bool #)
when 'T : float32 = not (# "cgt.un" x y : bool #)
when 'T : char = not (# "cgt" x y : bool #)
- when 'T : decimal = System.Decimal.op_LessThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
- when ^T : string = not (# "cgt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ when 'T : decimal = Decimal.op_LessThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : string = not (# "cgt" (String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (<=) : ^T * ^U -> bool) (x,y))
/// Static greater-than-or-equal with static optimizations for some well-known cases.
let inline (>=) (x:^T) (y:^U) =
- ((^T or ^U): (static member (>=) : ^T * ^U -> bool) (x,y))
+ OpGreaterThanOrEqualDynamic<(^T), (^U), bool> x y
when 'T : bool = not (# "clt" x y : bool #)
when 'T : sbyte = not (# "clt" x y : bool #)
when 'T : int16 = not (# "clt" x y : bool #)
@@ -4160,13 +4737,15 @@ namespace Microsoft.FSharp.Core
when 'T : float = not (# "clt.un" x y : bool #)
when 'T : float32 = not (# "clt.un" x y : bool #)
when 'T : char = not (# "clt" x y : bool #)
- when 'T : decimal = System.Decimal.op_GreaterThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
- when ^T : string = not (# "clt" (System.String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
-
+ when 'T : decimal = Decimal.op_GreaterThanOrEqual ((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : string = not (# "clt" (String.CompareOrdinal((# "" x : string #),(# "" y : string #))) 0 : bool #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (>=) : ^T * ^U -> bool) (x,y))
/// Static greater-than-or-equal with static optimizations for some well-known cases.
let inline (=) (x:^T) (y:^T) =
- (^T : (static member (=) : ^T * ^T -> bool) (x,y))
+ OpEqualityDynamic<(^T), (^T), bool> x y
when ^T : bool = (# "ceq" x y : bool #)
when ^T : sbyte = (# "ceq" x y : bool #)
when ^T : int16 = (# "ceq" x y : bool #)
@@ -4181,11 +4760,12 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "ceq" x y : bool #)
when ^T : nativeint = (# "ceq" x y : bool #)
when ^T : unativeint = (# "ceq" x y : bool #)
- when ^T : string = System.String.Equals((# "" x : string #),(# "" y : string #))
- when ^T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : string = String.Equals((# "" x : string #),(# "" y : string #))
+ when ^T : decimal = Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : ^T = (^T : (static member (=) : ^T * ^T -> bool) (x,y))
let inline (<>) (x:^T) (y:^T) =
- (^T : (static member (<>) : ^T * ^T -> bool) (x,y))
+ OpInequalityDynamic<(^T), (^T), bool> x y
when ^T : bool = not (# "ceq" x y : bool #)
when ^T : sbyte = not (# "ceq" x y : bool #)
when ^T : int16 = not (# "ceq" x y : bool #)
@@ -4200,9 +4780,9 @@ namespace Microsoft.FSharp.Core
when ^T : char = not (# "ceq" x y : bool #)
when ^T : nativeint = not (# "ceq" x y : bool #)
when ^T : unativeint = not (# "ceq" x y : bool #)
- when ^T : string = not (System.String.Equals((# "" x : string #),(# "" y : string #)))
- when ^T : decimal = System.Decimal.op_Inequality((# "" x:decimal #), (# "" y:decimal #))
-
+ when ^T : string = not (String.Equals((# "" x : string #),(# "" y : string #)))
+ when ^T : decimal = Decimal.op_Inequality((# "" x:decimal #), (# "" y:decimal #))
+ when ^T : ^T = (^T : (static member (<>) : ^T * ^T -> bool) (x,y))
// static comparison (ER mode) with static optimizations for some well-known cases
[]
@@ -4231,10 +4811,10 @@ namespace Microsoft.FSharp.Core
else (# "ceq" e1 e1 : int #)
when ^T : char = if (# "clt.un" e1 e2 : bool #) then (-1) else (# "cgt.un" e1 e2 : int #)
when ^T : string =
- // NOTE: we don't have to null check here because System.String.CompareOrdinal
+ // NOTE: we don't have to null check here because String.CompareOrdinal
// gives reliable results on null values.
- System.String.CompareOrdinal((# "" e1 : string #),(# "" e2 : string #))
- when ^T : decimal = System.Decimal.Compare((# "" e1:decimal #), (# "" e2:decimal #))
+ String.CompareOrdinal((# "" e1 : string #),(# "" e2 : string #))
+ when ^T : decimal = Decimal.Compare((# "" e1:decimal #), (# "" e2:decimal #))
[]
let inline max (e1: ^T) (e2: ^T) =
@@ -4385,16 +4965,14 @@ namespace Microsoft.FSharp.Core
when ^T : char and ^U : char = (# "conv.ovf.u2.un" (# "add.ovf.un" x y : uint32 #) : char #)
when ^T : sbyte and ^U : sbyte = (# "conv.ovf.i1" (# "add.ovf" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.ovf.u1.un" (# "add.ovf.un" x y : uint32 #) : byte #)
- when ^T : string and ^U : string = (# "" (System.String.Concat((# "" x : string #),(# "" y : string #))) : ^T #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Addition((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ when ^T : string and ^U : string = (# "" (String.Concat((# "" x : string #),(# "" y : string #))) : ^T #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Addition((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever ^T is resolved to a nominal type
- // That is, not in the generic implementation of '+'
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
when ^T : ^T = ((^T or ^U): (static member (+) : ^T * ^U -> ^V) (x,y))
- []
let inline (-) (x: ^T) (y: ^U) : ^V =
- ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y))
+ CheckedSubtractionDynamic<(^T),(^U),(^V)> x y
when ^T : int32 and ^U : int32 = (# "sub.ovf" x y : int32 #)
when ^T : float and ^U : float = (# "sub" x y : float #)
when ^T : float32 and ^U : float32 = (# "sub" x y : float32 #)
@@ -4407,11 +4985,13 @@ namespace Microsoft.FSharp.Core
when ^T : uint16 and ^U : uint16 = (# "conv.ovf.u2.un" (# "sub.ovf.un" x y : uint32 #) : uint16 #)
when ^T : sbyte and ^U : sbyte = (# "conv.ovf.i1" (# "sub.ovf" x y : int32 #) : sbyte #)
when ^T : byte and ^U : byte = (# "conv.ovf.u1.un" (# "sub.ovf.un" x y : uint32 #) : byte #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Subtraction((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Subtraction((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = ((^T or ^U): (static member (-) : ^T * ^U -> ^V) (x,y))
- []
let inline (~-) (value: ^T) : ^T =
- (^T : (static member (~-) : ^T -> ^T) (value))
+ CheckedUnaryNegationDynamic<(^T),(^T)> value
when ^T : int32 = (# "sub.ovf" 0 value : int32 #)
when ^T : float = (# "neg" value : float #)
when ^T : float32 = (# "neg" value : float32 #)
@@ -4419,7 +4999,10 @@ namespace Microsoft.FSharp.Core
when ^T : int16 = (# "sub.ovf" 0s value : int16 #)
when ^T : nativeint = (# "sub.ovf" 0n value : nativeint #)
when ^T : sbyte = (# "sub.ovf" 0y value : sbyte #)
- when ^T : decimal = (# "" (System.Decimal.op_UnaryNegation((# "" value : decimal #))) : ^T #)
+ when ^T : decimal = (# "" (Decimal.op_UnaryNegation((# "" value : decimal #))) : ^T #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ when ^T : ^T = (^T : (static member (~-) : ^T -> ^T) (value))
let inline ( * ) (x: ^T) (y: ^U) : ^V =
CheckedMultiplyDynamic<(^T),(^U),(^V)> x y
@@ -4435,17 +5018,16 @@ namespace Microsoft.FSharp.Core
when ^T : unativeint and ^U : unativeint = (# "mul.ovf.un" x y : unativeint #)
when ^T : float and ^U : float = (# "mul" x y : float #)
when ^T : float32 and ^U : float32 = (# "mul" x y : float32 #)
- when ^T : decimal and ^U : decimal = (# "" (System.Decimal.op_Multiply((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
+ when ^T : decimal and ^U : decimal = (# "" (Decimal.op_Multiply((# "" x : decimal #),(# "" y : decimal #))) : ^V #)
// According to the somewhat subtle rules of static optimizations,
- // this condition is used whenever ^T is resolved to a nominal type
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
// That is, not in the generic implementation of '*'
when ^T : ^T = ((^T or ^U): (static member (*) : ^T * ^U -> ^V) (x,y))
- []
[]
let inline byte (value: ^T) =
- (^T : (static member op_Explicit: ^T -> byte) (value))
- when ^T : string = parseByte (castToString value)
+ OpExplicitDynamic<(^T),byte> value
+ when ^T : string = ParseByte (castToString value)
when ^T : float = (# "conv.ovf.u1" value : byte #)
when ^T : float32 = (# "conv.ovf.u1" value : byte #)
when ^T : int64 = (# "conv.ovf.u1" value : byte #)
@@ -4459,11 +5041,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.u1.un" value : byte #)
when ^T : unativeint = (# "conv.ovf.u1.un" value : byte #)
when ^T : byte = (# "conv.ovf.u1.un" value : byte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> byte) (value))
- []
[]
let inline sbyte (value: ^T) =
- (^T : (static member op_Explicit: ^T -> sbyte) (value))
+ OpExplicitDynamic<(^T),sbyte> value
when ^T : string = ParseSByte (castToString value)
when ^T : float = (# "conv.ovf.i1" value : sbyte #)
when ^T : float32 = (# "conv.ovf.i1" value : sbyte #)
@@ -4478,11 +5063,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.i1.un" value : sbyte #)
when ^T : unativeint = (# "conv.ovf.i1.un" value : sbyte #)
when ^T : byte = (# "conv.ovf.i1.un" value : sbyte #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> sbyte) (value))
- []
[]
let inline uint16 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> uint16) (value))
+ OpExplicitDynamic<(^T),uint16> value
when ^T : string = ParseUInt16 (castToString value)
when ^T : float = (# "conv.ovf.u2" value : uint16 #)
when ^T : float32 = (# "conv.ovf.u2" value : uint16 #)
@@ -4497,11 +5085,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.u2.un" value : uint16 #)
when ^T : unativeint = (# "conv.ovf.u2.un" value : uint16 #)
when ^T : byte = (# "conv.ovf.u2.un" value : uint16 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint16) (value))
- []
[]
let inline char (value: ^T) =
- (^T : (static member op_Explicit: ^T -> char) (value))
+ OpExplicitDynamic<(^T), char> value
when ^T : string = (System.Char.Parse(castToString value))
when ^T : float = (# "conv.ovf.u2" value : char #)
when ^T : float32 = (# "conv.ovf.u2" value : char #)
@@ -4516,11 +5107,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.u2.un" value : char #)
when ^T : unativeint = (# "conv.ovf.u2.un" value : char #)
when ^T : byte = (# "conv.ovf.u2.un" value : char #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> char) (value))
- []
[]
let inline int16 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> int16) (value))
+ OpExplicitDynamic<(^T), int16> value
when ^T : string = ParseInt16 (castToString value)
when ^T : float = (# "conv.ovf.i2" value : int16 #)
when ^T : float32 = (# "conv.ovf.i2" value : int16 #)
@@ -4535,11 +5129,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.i2.un" value : int16 #)
when ^T : unativeint = (# "conv.ovf.i2.un" value : int16 #)
when ^T : byte = (# "conv.ovf.i2.un" value : int16 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> int16) (value))
- []
[]
let inline uint32 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> uint32) (value))
+ OpExplicitDynamic<(^T), uint32> value
when ^T : string = ParseUInt32 (castToString value)
when ^T : float = (# "conv.ovf.u4" value : uint32 #)
when ^T : float32 = (# "conv.ovf.u4" value : uint32 #)
@@ -4554,11 +5151,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.u4.un" value : uint32 #)
when ^T : unativeint = (# "conv.ovf.u4.un" value : uint32 #)
when ^T : byte = (# "conv.ovf.u4.un" value : uint32 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint32) (value))
- []
[]
let inline int32 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> int32) (value))
+ OpExplicitDynamic<(^T), int32> value
when ^T : string = ParseInt32 (castToString value)
when ^T : float = (# "conv.ovf.i4" value : int32 #)
when ^T : float32 = (# "conv.ovf.i4" value : int32 #)
@@ -4573,15 +5173,17 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.i4.un" value : int32 #)
when ^T : unativeint = (# "conv.ovf.i4.un" value : int32 #)
when ^T : byte = (# "conv.ovf.i4.un" value : int32 #)
-
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> int32) (value))
[]
let inline int value = int32 value
- []
[]
let inline uint64 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> uint64) (value))
+ OpExplicitDynamic<(^T), uint64> value
when ^T : string = ParseUInt64 (castToString value)
when ^T : float = (# "conv.ovf.u8" value : uint64 #)
when ^T : float32 = (# "conv.ovf.u8" value : uint64 #)
@@ -4596,11 +5198,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.u8.un" value : uint64 #)
when ^T : unativeint = (# "conv.ovf.u8.un" value : uint64 #)
when ^T : byte = (# "conv.ovf.u8.un" value : uint64 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint64) (value))
- []
[]
let inline int64 (value: ^T) =
- (^T : (static member op_Explicit: ^T -> int64) (value))
+ OpExplicitDynamic<(^T), int64> value
when ^T : string = ParseInt64 (castToString value)
when ^T : float = (# "conv.ovf.i8" value : int64 #)
when ^T : float32 = (# "conv.ovf.i8" value : int64 #)
@@ -4615,11 +5220,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.i8.un" value : int64 #)
when ^T : unativeint = (# "conv.ovf.i8.un" value : int64 #)
when ^T : byte = (# "conv.ovf.i8.un" value : int64 #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> int64) (value))
- []
[]
let inline unativeint (value: ^T) =
- (^T : (static member op_Explicit: ^T -> unativeint) (value))
+ OpExplicitDynamic<(^T), unativeint> value
when ^T : string = ParseUIntPtr (castToString value)
when ^T : float = (# "conv.ovf.u" value : unativeint #)
when ^T : float32 = (# "conv.ovf.u" value : unativeint #)
@@ -4634,11 +5242,14 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.u.un" value : unativeint #)
when ^T : unativeint = (# "conv.ovf.u.un" value : unativeint #)
when ^T : byte = (# "conv.ovf.u.un" value : unativeint #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value))
- []
[]
let inline nativeint (value: ^T) =
- (^T : (static member op_Explicit: ^T -> nativeint) (value))
+ OpExplicitDynamic<(^T), nativeint> value
when ^T : string = ParseIntPtr (castToString value)
when ^T : float = (# "conv.ovf.i" value : nativeint #)
when ^T : float32 = (# "conv.ovf.i" value : nativeint #)
@@ -4653,6 +5264,10 @@ namespace Microsoft.FSharp.Core
when ^T : char = (# "conv.ovf.i.un" value : nativeint #)
when ^T : unativeint = (# "conv.ovf.i.un" value : nativeint #)
when ^T : byte = (# "conv.ovf.i.un" value : nativeint #)
+ // According to the somewhat subtle rules of static optimizations,
+ // this condition is used whenever ^T is resolved to a nominal type or witnesses are available
+ // That is, not in the generic implementation of '*'
+ when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value))
module OperatorIntrinsics =
@@ -5179,7 +5794,6 @@ namespace Microsoft.FSharp.Core
if len <= 0 then String.Empty
else source.Substring(start, len)
- []
let inline absImpl (x: ^T) : ^T =
(^T: (static member Abs : ^T -> ^T) (x))
when ^T : int32 = let x : int32 = retype x in System.Math.Abs(x)
@@ -5187,70 +5801,62 @@ namespace Microsoft.FSharp.Core
when ^T : float32 = let x : float32 = retype x in System.Math.Abs(x)
when ^T : int64 = let x : int64 = retype x in System.Math.Abs(x)
when ^T : nativeint =
- let x : nativeint = retype x in
- if x >= 0n then x else
- let res = -x in
- if res < 0n then raise (System.OverflowException(ErrorStrings.NoNegateMinValueString))
- res
+ (let x : nativeint = retype x
+ if x >= 0n then
+ x
+ else
+ let res = -x
+ if res < 0n then raise (System.OverflowException(ErrorStrings.NoNegateMinValueString))
+ res)
when ^T : int16 = let x : int16 = retype x in System.Math.Abs(x)
when ^T : sbyte = let x : sbyte = retype x in System.Math.Abs(x)
when ^T : decimal = System.Math.Abs(retype x : decimal)
- []
let inline acosImpl(x: ^T) : ^T =
(^T: (static member Acos : ^T -> ^T) (x))
when ^T : float = System.Math.Acos(retype x)
when ^T : float32 = System.Math.Acos(toFloat (retype x)) |> toFloat32
- []
let inline asinImpl(x: ^T) : ^T =
(^T: (static member Asin : ^T -> ^T) (x))
when ^T : float = System.Math.Asin(retype x)
when ^T : float32 = System.Math.Asin(toFloat (retype x)) |> toFloat32
- []
let inline atanImpl(x: ^T) : ^T =
(^T: (static member Atan : ^T -> ^T) (x))
when ^T : float = System.Math.Atan(retype x)
when ^T : float32 = System.Math.Atan(toFloat (retype x)) |> toFloat32
- []
let inline atan2Impl(x: ^T) (y: ^T) : 'U =
(^T: (static member Atan2 : ^T * ^T -> 'U) (x,y))
when ^T : float = System.Math.Atan2(retype x, retype y)
when ^T : float32 = System.Math.Atan2(toFloat (retype x), toFloat(retype y)) |> toFloat32
- []
let inline ceilImpl(x: ^T) : ^T =
(^T: (static member Ceiling : ^T -> ^T) (x))
when ^T : float = System.Math.Ceiling(retype x : float)
when ^T : float32 = System.Math.Ceiling(toFloat (retype x)) |> toFloat32
- []
let inline expImpl(x: ^T) : ^T =
(^T: (static member Exp : ^T -> ^T) (x))
when ^T : float = System.Math.Exp(retype x)
when ^T : float32 = System.Math.Exp(toFloat (retype x)) |> toFloat32
- []
let inline floorImpl (x: ^T) : ^T =
(^T: (static member Floor : ^T -> ^T) (x))
when ^T : float = System.Math.Floor(retype x : float)
when ^T : float32 = System.Math.Floor(toFloat (retype x)) |> toFloat32
- []
let inline truncateImpl (x: ^T) : ^T =
(^T: (static member Truncate : ^T -> ^T) (x))
when ^T : float = System.Math.Truncate(retype x : float)
when ^T : float32 = System.Math.Truncate(toFloat (retype x)) |> toFloat32
- []
let inline roundImpl (x: ^T) : ^T =
(^T: (static member Round : ^T -> ^T) (x))
when ^T : float = System.Math.Round(retype x : float)
when ^T : float32 = System.Math.Round(toFloat (retype x)) |> toFloat32
- []
let inline signImpl (x: ^T) : int =
(^T: (member Sign : int) (x))
when ^T : int32 = System.Math.Sign(retype x : int32)
@@ -5262,79 +5868,56 @@ namespace Microsoft.FSharp.Core
when ^T : float32 = System.Math.Sign(toFloat (retype x))
when ^T : decimal = System.Math.Sign(retype x : decimal)
- []
let inline logImpl(x: ^T) : ^T =
(^T: (static member Log : ^T -> ^T) (x))
when ^T : float = System.Math.Log(retype x)
when ^T : float32 = System.Math.Log(toFloat (retype x)) |> toFloat32
- []
let inline log10Impl(x: ^T) : ^T =
(^T: (static member Log10 : ^T -> ^T) (x))
when ^T : float = System.Math.Log10(retype x)
when ^T : float32 = System.Math.Log10(toFloat (retype x)) |> toFloat32
- []
let inline sqrtImpl(x: ^T) : ^U =
(^T: (static member Sqrt : ^T -> ^U) (x))
when ^T : float = System.Math.Sqrt(retype x : float)
when ^T : float32 = System.Math.Sqrt(toFloat (retype x)) |> toFloat32
- []
let inline cosImpl(x: ^T) : ^T =
(^T: (static member Cos : ^T -> ^T) (x))
when ^T : float = System.Math.Cos(retype x)
when ^T : float32 = System.Math.Cos(toFloat (retype x)) |> toFloat32
- []
let inline coshImpl(x: ^T) : ^T =
(^T: (static member Cosh : ^T -> ^T) (x))
when ^T : float = System.Math.Cosh(retype x)
when ^T : float32 = System.Math.Cosh(toFloat (retype x)) |> toFloat32
- []
let inline sinImpl(x: ^T) : ^T =
(^T: (static member Sin : ^T -> ^T) (x))
when ^T : float = System.Math.Sin(retype x)
when ^T : float32 = System.Math.Sin(toFloat (retype x)) |> toFloat32
- []
let inline sinhImpl(x: ^T) : ^T =
(^T: (static member Sinh : ^T -> ^T) (x))
when ^T : float = System.Math.Sinh(retype x)
when ^T : float32 = System.Math.Sinh(toFloat (retype x)) |> toFloat32
- []
let inline tanImpl(x: ^T) : ^T =
(^T: (static member Tan : ^T -> ^T) (x))
when ^T : float = System.Math.Tan(retype x)
when ^T : float32 = System.Math.Tan(toFloat (retype x)) |> toFloat32
- []
let inline tanhImpl(x: ^T) : ^T =
(^T: (static member Tanh : ^T -> ^T) (x))
when ^T : float = System.Math.Tanh(retype x)
when ^T : float32 = System.Math.Tanh(toFloat (retype x)) |> toFloat32
- []
let inline powImpl (x: ^T) (y: ^U) : ^T =
(^T: (static member Pow : ^T * ^U -> ^T) (x,y))
when ^T : float = System.Math.Pow((retype x : float), (retype y: float))
when ^T : float32 = System.Math.Pow(toFloat (retype x), toFloat(retype y)) |> toFloat32
- []
- let UnaryDynamicImpl nm : ('T -> 'U) =
- let aty = typeof<'T>
- let minfo = aty.GetMethod(nm, [| aty |])
- (fun x -> unboxPrim<_>(minfo.Invoke(null,[| box x|])))
-
- let BinaryDynamicImpl nm : ('T -> 'U -> 'V) =
- let aty = typeof<'T>
- let bty = typeof<'U>
- let minfo = aty.GetMethod(nm,[| aty;bty |])
- (fun x y -> unboxPrim<_>(minfo.Invoke(null,[| box x; box y|])))
-
- []
type AbsDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5349,7 +5932,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Abs"
static member Result : ('T -> 'T) = result
- []
type AcosDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5358,7 +5940,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Acos"
static member Result : ('T -> 'T) = result
- []
type AsinDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5367,7 +5948,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Asin"
static member Result : ('T -> 'T) = result
- []
type AtanDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5376,7 +5956,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Atan"
static member Result : ('T -> 'T) = result
- []
type Atan2DynamicImplTable<'T,'U>() =
static let result : ('T -> 'T -> 'U) =
let aty = typeof<'T>
@@ -5385,7 +5964,6 @@ namespace Microsoft.FSharp.Core
else BinaryDynamicImpl "Atan2"
static member Result : ('T -> 'T -> 'U) = result
- []
type CeilingDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5394,7 +5972,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Ceiling"
static member Result : ('T -> 'T) = result
- []
type ExpDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5403,7 +5980,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Exp"
static member Result : ('T -> 'T) = result
- []
type FloorDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5412,7 +5988,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Floor"
static member Result : ('T -> 'T) = result
- []
type TruncateDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5421,7 +5996,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Truncate"
static member Result : ('T -> 'T) = result
- []
type RoundDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5430,7 +6004,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Round"
static member Result : ('T -> 'T) = result
- []
type SignDynamicImplTable<'T>() =
static let result : ('T -> int) =
let aty = typeof<'T>
@@ -5445,7 +6018,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Sign"
static member Result : ('T -> int) = result
- []
type LogDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5454,7 +6026,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Log"
static member Result : ('T -> 'T) = result
- []
type Log10DynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5463,7 +6034,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Log10"
static member Result : ('T -> 'T) = result
- []
type SqrtDynamicImplTable<'T,'U>() =
static let result : ('T -> 'U) =
let aty = typeof<'T>
@@ -5472,7 +6042,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Sqrt"
static member Result : ('T -> 'U) = result
- []
type CosDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5481,7 +6050,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Cos"
static member Result : ('T -> 'T) = result
- []
type CoshDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5490,7 +6058,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Cosh"
static member Result : ('T -> 'T) = result
- []
type SinDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5499,7 +6066,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Sin"
static member Result : ('T -> 'T) = result
- []
type SinhDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5508,7 +6074,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Sinh"
static member Result : ('T -> 'T) = result
- []
type TanDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5517,7 +6082,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Tan"
static member Result : ('T -> 'T) = result
- []
type TanhDynamicImplTable<'T>() =
static let result : ('T -> 'T) =
let aty = typeof<'T>
@@ -5526,7 +6090,6 @@ namespace Microsoft.FSharp.Core
else UnaryDynamicImpl "Tanh"
static member Result : ('T -> 'T) = result
- []
type PowDynamicImplTable<'T,'U>() =
static let result : ('T -> 'U -> 'T) =
let aty = typeof<'T>
diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi
index c977af45417..85b7dc12e25 100644
--- a/src/fsharp/FSharp.Core/prim-types.fsi
+++ b/src/fsharp/FSharp.Core/prim-types.fsi
@@ -714,6 +714,8 @@ namespace Microsoft.FSharp.Core
/// NoDynamicInvocationAttribute
new : unit -> NoDynamicInvocationAttribute
+ new : isLegacy: bool -> NoDynamicInvocationAttribute
+
/// This attribute is used to indicate that references to the elements of a module, record or union
/// type require explicit qualified access.
[]
@@ -801,7 +803,7 @@ namespace Microsoft.FSharp.Core
type int64<[] 'Measure> = int64
/// Represents a managed pointer in F# code.
-#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+#if BUILDING_WITH_LKG
[]
#else
[]
@@ -812,7 +814,7 @@ namespace Microsoft.FSharp.Core
type byref<'T> = (# "!0&" #)
/// Represents the types of byrefs in F# 4.5+
-#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+#if BUILDING_WITH_LKG
[]
#else
[]
@@ -820,7 +822,7 @@ namespace Microsoft.FSharp.Core
module ByRefKinds =
/// Represents a byref that can be written
-#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+#if BUILDING_WITH_LKG
[]
#else
[]
@@ -828,7 +830,7 @@ namespace Microsoft.FSharp.Core
type Out
/// Represents a byref that can be read
-#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+#if BUILDING_WITH_LKG
[]
#else
[]
@@ -836,7 +838,7 @@ namespace Microsoft.FSharp.Core
type In
/// Represents a byref that can be both read and written
-#if BUILDING_WITH_LKG || BUILD_FROM_SOURCE
+#if BUILDING_WITH_LKG
[]
#else
[]
@@ -1063,30 +1065,106 @@ namespace Microsoft.FSharp.Core
[