From f6c1859eae72d37558baed350a48ac17c5ce75a4 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 00:20:32 +0800 Subject: [PATCH 01/78] Subtraction of two chars --- src/fsharp/FSharp.Core/prim-types.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 319481c6814..4936b6aa797 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3979,6 +3979,7 @@ namespace Microsoft.FSharp.Core when ^T : unativeint and ^U : unativeint = (# "sub" x y : unativeint #) when ^T : int16 and ^U : int16 = (# "conv.i2" (# "sub" x y : int32 #) : int16 #) when ^T : uint16 and ^U : uint16 = (# "conv.u2" (# "sub" x y : uint32 #) : uint16 #) + when ^T : char and ^U : char = (# "conv.u2" (# "sub" x y : uint32 #) : char #) 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 #) From 60171b759f1585b6f2ec6d5b5b5c1c784b593206 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 00:50:39 +0800 Subject: [PATCH 02/78] Update test.fsx --- tests/fsharp/tools/eval/test.fsx | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/fsharp/tools/eval/test.fsx b/tests/fsharp/tools/eval/test.fsx index 8956413a1bd..a1f5ae493fd 100644 --- a/tests/fsharp/tools/eval/test.fsx +++ b/tests/fsharp/tools/eval/test.fsx @@ -1236,6 +1236,7 @@ module EvaluationTests = check "vroievr097q" (LanguagePrimitives.AdditionDynamic 3.0 4.0) 7.0 check "vroievr097w" (LanguagePrimitives.AdditionDynamic 3.0f 4.0f) 7.0f check "vroievr097e" (LanguagePrimitives.AdditionDynamic 3.0M 4.0M) 7.0M + check "vroievr097n" (LanguagePrimitives.AdditionDynamic '3' '\004') '7' check "vroievr097r" (LanguagePrimitives.CheckedAdditionDynamic 3y 4y) 7y check "vroievr097t" (LanguagePrimitives.CheckedAdditionDynamic 3s 4s) 7s @@ -1250,6 +1251,38 @@ module EvaluationTests = check "vroievr097f" (LanguagePrimitives.CheckedAdditionDynamic 3.0 4.0) 7.0 check "vroievr097g" (LanguagePrimitives.CheckedAdditionDynamic 3.0f 4.0f) 7.0f check "vroievr097h" (LanguagePrimitives.CheckedAdditionDynamic 3.0M 4.0M) 7.0M + check "vroievr097u" (LanguagePrimitives.CheckedAdditionDynamic '3' '\004') '7' + + + check "vroievr0981" (LanguagePrimitives.SubtractionDynamic 3y 4y) -1y + check "vroievr0982" (LanguagePrimitives.SubtractionDynamic 3s 4s) -1s + check "vroievr0983" (LanguagePrimitives.SubtractionDynamic 3 4) -1 + check "vroievr0984" (LanguagePrimitives.SubtractionDynamic 3L 4L) -1L + check "vroievr0985" (LanguagePrimitives.SubtractionDynamic 3n 4n) -1n + check "vroievr0986" (LanguagePrimitives.SubtractionDynamic 3uy 4uy) -1uy + check "vroievr0987" (LanguagePrimitives.SubtractionDynamic 3us 4us) -1us + check "vroievr0988" (LanguagePrimitives.SubtractionDynamic 3u 4u) -1u + check "vroievr0989" (LanguagePrimitives.SubtractionDynamic 3UL 4UL) -1UL + check "vroievr0980" (LanguagePrimitives.SubtractionDynamic 3un 4un) -1un + check "vroievr098q" (LanguagePrimitives.SubtractionDynamic 3.0 4.0) -1.0 + check "vroievr098w" (LanguagePrimitives.SubtractionDynamic 3.0f 4.0f) -1.0f + check "vroievr098e" (LanguagePrimitives.SubtractionDynamic 3.0M 4.0M) -1.0M + check "vroievr098n" (LanguagePrimitives.SubtractionDynamic '3' '\004') '/' + + check "vroievr098r" (LanguagePrimitives.CheckedSubtractionDynamic 3y 4y) -1y + check "vroievr098t" (LanguagePrimitives.CheckedSubtractionDynamic 3s 4s) -1s + check "vroievr098y" (LanguagePrimitives.CheckedSubtractionDynamic 3 4) -1 + check "vroievr098u" (LanguagePrimitives.CheckedSubtractionDynamic 3L 4L) -1L + check "vroievr098i" (LanguagePrimitives.CheckedSubtractionDynamic 3n 4n) -1n + check "vroievr098o" (LanguagePrimitives.CheckedSubtractionDynamic 3uy 4uy) -1uy + check "vroievr098p" (LanguagePrimitives.CheckedSubtractionDynamic 3us 4us) -1us + check "vroievr098a" (LanguagePrimitives.CheckedSubtractionDynamic 3u 4u) -1u + check "vroievr098s" (LanguagePrimitives.CheckedSubtractionDynamic 3UL 4UL) -1UL + check "vroievr098d" (LanguagePrimitives.CheckedSubtractionDynamic 3un 4un) -1un + check "vroievr098f" (LanguagePrimitives.CheckedSubtractionDynamic 3.0 4.0) -1.0 + check "vroievr098g" (LanguagePrimitives.CheckedSubtractionDynamic 3.0f 4.0f) -1.0f + check "vroievr098h" (LanguagePrimitives.CheckedSubtractionDynamic 3.0M 4.0M) -1.0M + check "vroievr098u" (LanguagePrimitives.CheckedSubtractionDynamic '3' '\004') '/' check "vroievr0912q" (LanguagePrimitives.MultiplyDynamic 3y 4y) 12y check "vroievr0912w" (LanguagePrimitives.MultiplyDynamic 3s 4s) 12s From 460c8438b7a22e3e21a4376918ef89e76de39358 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 00:52:38 +0800 Subject: [PATCH 03/78] No extra lines --- tests/fsharp/tools/eval/test.fsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/fsharp/tools/eval/test.fsx b/tests/fsharp/tools/eval/test.fsx index a1f5ae493fd..c73850236a0 100644 --- a/tests/fsharp/tools/eval/test.fsx +++ b/tests/fsharp/tools/eval/test.fsx @@ -1253,7 +1253,6 @@ module EvaluationTests = check "vroievr097h" (LanguagePrimitives.CheckedAdditionDynamic 3.0M 4.0M) 7.0M check "vroievr097u" (LanguagePrimitives.CheckedAdditionDynamic '3' '\004') '7' - check "vroievr0981" (LanguagePrimitives.SubtractionDynamic 3y 4y) -1y check "vroievr0982" (LanguagePrimitives.SubtractionDynamic 3s 4s) -1s check "vroievr0983" (LanguagePrimitives.SubtractionDynamic 3 4) -1 @@ -1298,7 +1297,6 @@ module EvaluationTests = check "vroievr0912s" (LanguagePrimitives.MultiplyDynamic 3.0f 4.0f) 12.0f check "vroievr0912d" (LanguagePrimitives.MultiplyDynamic 3.0M 4.0M) 12.0M - check "vroievr0912f" (LanguagePrimitives.CheckedMultiplyDynamic 3y 4y) 12y check "vroievr0912g" (LanguagePrimitives.CheckedMultiplyDynamic 3s 4s) 12s check "vroievr0912h" (LanguagePrimitives.CheckedMultiplyDynamic 3 4) 12 From a81a42f927dc8664b2ca13639788f54d5caf56c2 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 00:53:55 +0800 Subject: [PATCH 04/78] Update dynamic implementation --- src/fsharp/FSharp.Core/prim-types.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 4936b6aa797..0b32ada79c8 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2620,6 +2620,7 @@ namespace Microsoft.FSharp.Core elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.u2" (# "sub" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.i1" (# "sub" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.u1" (# "sub" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) + elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.u1" (# "sub" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : char #) elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Subtraction(convPrim<_,decimal> x, convPrim<_,decimal> y)) else BinaryOpDynamicImplTable.Invoke "op_Subtraction" x y From 5d7318b139336ec61ff8a41e33ccde913c7d4845 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 00:55:26 +0800 Subject: [PATCH 05/78] Update prim-types.fs --- src/fsharp/FSharp.Core/prim-types.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 0b32ada79c8..51e4a09ae42 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2718,6 +2718,7 @@ namespace Microsoft.FSharp.Core elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "sub.ovf.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.ovf.i2" (# "sub.ovf" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "sub.ovf.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "sub.ovf.un" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : uint16 #) elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.ovf.i1" (# "sub.ovf" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.ovf.u1.un" (# "sub.ovf.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Subtraction(convPrim<_,decimal> x, convPrim<_,decimal> y)) @@ -4900,6 +4901,7 @@ namespace Microsoft.FSharp.Core when ^T : unativeint and ^U : unativeint = (# "sub.ovf.un" x y : unativeint #) when ^T : int16 and ^U : int16 = (# "conv.ovf.i2" (# "sub.ovf" x y : int32 #) : int16 #) when ^T : uint16 and ^U : uint16 = (# "conv.ovf.u2.un" (# "sub.ovf.un" x y : uint32 #) : uint16 #) + when ^T : char and ^U : char = (# "conv.ovf.u2.un" (# "sub.ovf.un" x y : uint32 #) : char #) 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 #) From caab2f01418ab3ef67427387fe946c59c9b7d4d0 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 01:07:20 +0800 Subject: [PATCH 06/78] Update test.fsx --- tests/fsharp/core/libtest/test.fsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index f708f50351b..8b31dc1dc55 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -3657,6 +3657,9 @@ module Optimiations = begin let _ = check "opt.oi20c77tb" (0x8000000000000000L >>> 63) (0xFFFFFFFFFFFFFFFFL) let _ = check "opt.oi20c77yb" (0x8000000000000000L >>> 64) (0x8000000000000000L) + let _ = check "opt.oi20c77qc" ('a' + '\025') ('z') + let _ = check "opt.oi20c77wc" ('z' - '\025') ('a') + end From 14857a4b9e7004e660b47c388fc1f5ead4235237 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 16 Jun 2021 14:14:49 +0800 Subject: [PATCH 07/78] lol --- tests/fsharp/tools/eval/test.fsx | 58 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/fsharp/tools/eval/test.fsx b/tests/fsharp/tools/eval/test.fsx index c73850236a0..44ac6157ffb 100644 --- a/tests/fsharp/tools/eval/test.fsx +++ b/tests/fsharp/tools/eval/test.fsx @@ -1253,35 +1253,35 @@ module EvaluationTests = check "vroievr097h" (LanguagePrimitives.CheckedAdditionDynamic 3.0M 4.0M) 7.0M check "vroievr097u" (LanguagePrimitives.CheckedAdditionDynamic '3' '\004') '7' - check "vroievr0981" (LanguagePrimitives.SubtractionDynamic 3y 4y) -1y - check "vroievr0982" (LanguagePrimitives.SubtractionDynamic 3s 4s) -1s - check "vroievr0983" (LanguagePrimitives.SubtractionDynamic 3 4) -1 - check "vroievr0984" (LanguagePrimitives.SubtractionDynamic 3L 4L) -1L - check "vroievr0985" (LanguagePrimitives.SubtractionDynamic 3n 4n) -1n - check "vroievr0986" (LanguagePrimitives.SubtractionDynamic 3uy 4uy) -1uy - check "vroievr0987" (LanguagePrimitives.SubtractionDynamic 3us 4us) -1us - check "vroievr0988" (LanguagePrimitives.SubtractionDynamic 3u 4u) -1u - check "vroievr0989" (LanguagePrimitives.SubtractionDynamic 3UL 4UL) -1UL - check "vroievr0980" (LanguagePrimitives.SubtractionDynamic 3un 4un) -1un - check "vroievr098q" (LanguagePrimitives.SubtractionDynamic 3.0 4.0) -1.0 - check "vroievr098w" (LanguagePrimitives.SubtractionDynamic 3.0f 4.0f) -1.0f - check "vroievr098e" (LanguagePrimitives.SubtractionDynamic 3.0M 4.0M) -1.0M - check "vroievr098n" (LanguagePrimitives.SubtractionDynamic '3' '\004') '/' - - check "vroievr098r" (LanguagePrimitives.CheckedSubtractionDynamic 3y 4y) -1y - check "vroievr098t" (LanguagePrimitives.CheckedSubtractionDynamic 3s 4s) -1s - check "vroievr098y" (LanguagePrimitives.CheckedSubtractionDynamic 3 4) -1 - check "vroievr098u" (LanguagePrimitives.CheckedSubtractionDynamic 3L 4L) -1L - check "vroievr098i" (LanguagePrimitives.CheckedSubtractionDynamic 3n 4n) -1n - check "vroievr098o" (LanguagePrimitives.CheckedSubtractionDynamic 3uy 4uy) -1uy - check "vroievr098p" (LanguagePrimitives.CheckedSubtractionDynamic 3us 4us) -1us - check "vroievr098a" (LanguagePrimitives.CheckedSubtractionDynamic 3u 4u) -1u - check "vroievr098s" (LanguagePrimitives.CheckedSubtractionDynamic 3UL 4UL) -1UL - check "vroievr098d" (LanguagePrimitives.CheckedSubtractionDynamic 3un 4un) -1un - check "vroievr098f" (LanguagePrimitives.CheckedSubtractionDynamic 3.0 4.0) -1.0 - check "vroievr098g" (LanguagePrimitives.CheckedSubtractionDynamic 3.0f 4.0f) -1.0f - check "vroievr098h" (LanguagePrimitives.CheckedSubtractionDynamic 3.0M 4.0M) -1.0M - check "vroievr098u" (LanguagePrimitives.CheckedSubtractionDynamic '3' '\004') '/' + check "vroievr0981" (LanguagePrimitives.SubtractionDynamic 7y 4y) 3y + check "vroievr0982" (LanguagePrimitives.SubtractionDynamic 7s 4s) 3s + check "vroievr0983" (LanguagePrimitives.SubtractionDynamic 7 4) 3 + check "vroievr0984" (LanguagePrimitives.SubtractionDynamic 7L 4L) 3L + check "vroievr0985" (LanguagePrimitives.SubtractionDynamic 7n 4n) 3n + check "vroievr0986" (LanguagePrimitives.SubtractionDynamic 7uy 4uy) 3uy + check "vroievr0987" (LanguagePrimitives.SubtractionDynamic 7us 4us) 3us + check "vroievr0988" (LanguagePrimitives.SubtractionDynamic 7u 4u) 3u + check "vroievr0989" (LanguagePrimitives.SubtractionDynamic 7UL 4UL) 3UL + check "vroievr0980" (LanguagePrimitives.SubtractionDynamic 7un 4un) 3un + check "vroievr098q" (LanguagePrimitives.SubtractionDynamic 7.0 4.0) 3.0 + check "vroievr098w" (LanguagePrimitives.SubtractionDynamic 7.0f 4.0f) 3.0f + check "vroievr098e" (LanguagePrimitives.SubtractionDynamic 7.0M 4.0M) 3.0M + check "vroievr098n" (LanguagePrimitives.SubtractionDynamic '7' '\004') '3' + + check "vroievr098r" (LanguagePrimitives.CheckedSubtractionDynamic 7y 4y) 3y + check "vroievr098t" (LanguagePrimitives.CheckedSubtractionDynamic 7s 4s) 3s + check "vroievr098y" (LanguagePrimitives.CheckedSubtractionDynamic 7 4) 3 + check "vroievr098u" (LanguagePrimitives.CheckedSubtractionDynamic 7L 4L) 3L + check "vroievr098i" (LanguagePrimitives.CheckedSubtractionDynamic 7n 4n) 3n + check "vroievr098o" (LanguagePrimitives.CheckedSubtractionDynamic 7uy 4uy) 3uy + check "vroievr098p" (LanguagePrimitives.CheckedSubtractionDynamic 7us 4us) 3us + check "vroievr098a" (LanguagePrimitives.CheckedSubtractionDynamic 7u 4u) 3u + check "vroievr098s" (LanguagePrimitives.CheckedSubtractionDynamic 7UL 4UL) 3UL + check "vroievr098d" (LanguagePrimitives.CheckedSubtractionDynamic 7un 4un) 3un + check "vroievr098f" (LanguagePrimitives.CheckedSubtractionDynamic 7.0 4.0) 3.0 + check "vroievr098g" (LanguagePrimitives.CheckedSubtractionDynamic 7.0f 4.0f) 3.0f + check "vroievr098h" (LanguagePrimitives.CheckedSubtractionDynamic 7.0M 4.0M) 3.0M + check "vroievr098u" (LanguagePrimitives.CheckedSubtractionDynamic '7' '\004') '3' check "vroievr0912q" (LanguagePrimitives.MultiplyDynamic 3y 4y) 12y check "vroievr0912w" (LanguagePrimitives.MultiplyDynamic 3s 4s) 12s From 5f3503381b2df4876ef510c30fecad9042c58a88 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 17 Jun 2021 12:10:57 +0800 Subject: [PATCH 08/78] char? --- src/fsharp/FSharp.Core/prim-types.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 51e4a09ae42..2b0c6e4b578 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2699,7 +2699,7 @@ namespace Microsoft.FSharp.Core elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "add.ovf.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.ovf.i2" (# "add.ovf" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "add.ovf.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) - elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "add.ovf.un" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "add.ovf.un" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : char #) elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.ovf.i1" (# "add.ovf" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.ovf.u1.un" (# "add.ovf.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) elif type3eq<'T1, 'T2, 'U, string> then convPrim<_,'U> (String.Concat(convPrim<_,string> x, convPrim<_,string> y)) @@ -2718,7 +2718,7 @@ namespace Microsoft.FSharp.Core elif type3eq<'T1, 'T2, 'U, unativeint> then convPrim<_,'U> (# "sub.ovf.un" (convPrim<_,unativeint> x) (convPrim<_,unativeint> y) : unativeint #) elif type3eq<'T1, 'T2, 'U, int16> then convPrim<_,'U> (# "conv.ovf.i2" (# "sub.ovf" (convPrim<_,int16> x) (convPrim<_,int16> y) : int32 #) : int16 #) elif type3eq<'T1, 'T2, 'U, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "sub.ovf.un" (convPrim<_,uint16> x) (convPrim<_,uint16> y) : uint32 #) : uint16 #) - elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "sub.ovf.un" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : uint16 #) + elif type3eq<'T1, 'T2, 'U, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (# "sub.ovf.un" (convPrim<_,char> x) (convPrim<_,char> y) : uint32 #) : char #) elif type3eq<'T1, 'T2, 'U, sbyte> then convPrim<_,'U> (# "conv.ovf.i1" (# "sub.ovf" (convPrim<_,sbyte> x) (convPrim<_,sbyte> y) : int32 #) : sbyte #) elif type3eq<'T1, 'T2, 'U, byte> then convPrim<_,'U> (# "conv.ovf.u1.un" (# "sub.ovf.un" (convPrim<_,byte> x) (convPrim<_,byte> y) : uint32 #) : byte #) elif type3eq<'T1, 'T2, 'U, decimal> then convPrim<_,'U> (Decimal.op_Subtraction(convPrim<_,decimal> x, convPrim<_,decimal> y)) From 5e023430fc9caf6989af96029a8040311e98b32d Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 18 Jun 2021 01:00:11 +0800 Subject: [PATCH 09/78] Update test.fsx --- tests/fsharp/core/quotes/test.fsx | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 6415c466a65..2e6daf3b083 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3396,6 +3396,7 @@ module WitnessTests = <@@ 1.0f / 4.0f @@>, true <@@ 1 % 4 @@>, true <@@ -(4.0M) @@>, true + <@@ 'z' - 'a' @@>, true <@@ 1y <<< 3 @@>, true <@@ 1uy <<< 3 @@>, true From 1af5c2f4142f780ded7004ce5f1cd91ce4ea3cbe Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 18 Jun 2021 16:38:43 +0800 Subject: [PATCH 10/78] The missing piece --- src/fsharp/ConstraintSolver.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index a3837ae5fc2..f83c53204ab 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -384,7 +384,7 @@ let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g let IsCharOrStringType g ty = isCharTy g ty || isStringTy g ty /// Checks the argument type for a built-in solution to an op_Addition, op_Subtraction or op_Modulus constraint. -let IsAddSubModType nm g ty = IsNumericOrIntegralEnumType g ty || (nm = "op_Addition" && IsCharOrStringType g ty) +let IsAddSubModType nm g ty = IsNumericOrIntegralEnumType g ty || (nm = "op_Addition" && IsCharOrStringType g ty) || (nm = "op_Subtraction" && isCharTy g ty) /// Checks the argument type for a built-in solution to a bitwise operator constraint let IsBitwiseOpType g ty = IsIntegerOrIntegerEnumTy g ty || (isEnumTy g ty) From 6d31bad32c5cd4c43974eaf9819488d2e7fab4bc Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 18 Jun 2021 23:07:04 +0800 Subject: [PATCH 11/78] Witness test refactor --- src/fsharp/FSharp.Core/Linq.fs | 142 +++---- src/fsharp/pars.fsy | 2 +- tests/fsharp/core/quotes/test.fsx | 602 +++++++++++++++++------------- 3 files changed, 425 insertions(+), 321 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 8bc7fcf5615..3aea9de8201 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -361,84 +361,84 @@ module LeafExpressionConverter = Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr | GenericEqualityQ _ - | EqualsQ _ -> transBinOp inp env false args false Expression.Equal - | NotEqQ _ -> transBinOp inp env false args false Expression.NotEqual - | GreaterQ _ -> transBinOp inp env false args false Expression.GreaterThan - | GreaterEqQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual - | LessQ _ -> transBinOp inp env false args false Expression.LessThan - | LessEqQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual + | EqualsQ _ -> transBinBoolOp inp env false args false Expression.Equal + | NotEqQ _ -> transBinBoolOp inp env false args false Expression.NotEqual + | GreaterQ _ -> transBinBoolOp inp env false args false Expression.GreaterThan + | GreaterEqQ _ -> transBinBoolOp inp env false args false Expression.GreaterThanOrEqual + | LessQ _ -> transBinBoolOp inp env false args false Expression.LessThan + | LessEqQ _ -> transBinBoolOp inp env false args false Expression.LessThanOrEqual | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ _ -> transBinOp inp env false args false Expression.Equal - | StaticNotEqQ _ -> transBinOp inp env false args false Expression.NotEqual - | StaticGreaterQ _ -> transBinOp inp env false args false Expression.GreaterThan - | StaticGreaterEqQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual - | StaticLessQ _ -> transBinOp inp env false args false Expression.LessThan - | StaticLessEqQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual - - | NullableEqualsQ _ -> transBinOp inp env false args true Expression.Equal - | NullableNotEqQ _ -> transBinOp inp env false args true Expression.NotEqual - | NullableGreaterQ _ -> transBinOp inp env false args true Expression.GreaterThan - | NullableGreaterEqQ _ -> transBinOp inp env false args true Expression.GreaterThanOrEqual - | NullableLessQ _ -> transBinOp inp env false args true Expression.LessThan - | NullableLessEqQ _ -> transBinOp inp env false args true Expression.LessThanOrEqual - - | EqualsNullableQ _ -> transBinOp inp env true args false Expression.Equal - | NotEqNullableQ _ -> transBinOp inp env true args false Expression.NotEqual - | GreaterNullableQ _ -> transBinOp inp env true args false Expression.GreaterThan - | GreaterEqNullableQ _ -> transBinOp inp env true args false Expression.GreaterThanOrEqual - | LessNullableQ _ -> transBinOp inp env true args false Expression.LessThan - | LessEqNullableQ _ -> transBinOp inp env true args false Expression.LessThanOrEqual - - | NullableEqualsNullableQ _ -> transBinOp inp env false args false Expression.Equal - | NullableNotEqNullableQ _ -> transBinOp inp env false args false Expression.NotEqual - | NullableGreaterNullableQ _ -> transBinOp inp env false args false Expression.GreaterThan - | NullableGreaterEqNullableQ _ -> transBinOp inp env false args false Expression.GreaterThanOrEqual - | NullableLessNullableQ _ -> transBinOp inp env false args false Expression.LessThan - | NullableLessEqNullableQ _ -> transBinOp inp env false args false Expression.LessThanOrEqual + | StaticEqualsQ _ -> transBinBoolOp inp env false args false Expression.Equal + | StaticNotEqQ _ -> transBinBoolOp inp env false args false Expression.NotEqual + | StaticGreaterQ _ -> transBinBoolOp inp env false args false Expression.GreaterThan + | StaticGreaterEqQ _ -> transBinBoolOp inp env false args false Expression.GreaterThanOrEqual + | StaticLessQ _ -> transBinBoolOp inp env false args false Expression.LessThan + | StaticLessEqQ _ -> transBinBoolOp inp env false args false Expression.LessThanOrEqual + + | NullableEqualsQ _ -> transBinBoolOp inp env false args true Expression.Equal + | NullableNotEqQ _ -> transBinBoolOp inp env false args true Expression.NotEqual + | NullableGreaterQ _ -> transBinBoolOp inp env false args true Expression.GreaterThan + | NullableGreaterEqQ _ -> transBinBoolOp inp env false args true Expression.GreaterThanOrEqual + | NullableLessQ _ -> transBinBoolOp inp env false args true Expression.LessThan + | NullableLessEqQ _ -> transBinBoolOp inp env false args true Expression.LessThanOrEqual + + | EqualsNullableQ _ -> transBinBoolOp inp env true args false Expression.Equal + | NotEqNullableQ _ -> transBinBoolOp inp env true args false Expression.NotEqual + | GreaterNullableQ _ -> transBinBoolOp inp env true args false Expression.GreaterThan + | GreaterEqNullableQ _ -> transBinBoolOp inp env true args false Expression.GreaterThanOrEqual + | LessNullableQ _ -> transBinBoolOp inp env true args false Expression.LessThan + | LessEqNullableQ _ -> transBinBoolOp inp env true args false Expression.LessThanOrEqual + + | NullableEqualsNullableQ _ -> transBinBoolOp inp env false args false Expression.Equal + | NullableNotEqNullableQ _ -> transBinBoolOp inp env false args false Expression.NotEqual + | NullableGreaterNullableQ _ -> transBinBoolOp inp env false args false Expression.GreaterThan + | NullableGreaterEqNullableQ _ -> transBinBoolOp inp env false args false Expression.GreaterThanOrEqual + | NullableLessNullableQ _ -> transBinBoolOp inp env false args false Expression.LessThan + | NullableLessEqNullableQ _ -> transBinBoolOp inp 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 _ -> transBinOp inp env false args false Expression.Add - | DivideQ _ -> transBinOp inp env false args false Expression.Divide - | MinusQ _ -> transBinOp inp env false args false Expression.Subtract - | MultiplyQ _ -> transBinOp inp env false args false Expression.Multiply - | ModuloQ _ -> transBinOp inp env false args false Expression.Modulo - - | ShiftLeftQ _ -> transBinOp inp env false args false Expression.LeftShift - | ShiftRightQ _ -> transBinOp inp env false args false Expression.RightShift - | BitwiseAndQ _ -> transBinOp inp env false args false Expression.And - | BitwiseOrQ _ -> transBinOp inp env false args false Expression.Or - | BitwiseXorQ _ -> transBinOp inp env false args false Expression.ExclusiveOr + | PlusQ _ -> transBinOp inp env false args false Expression.Add (methodhandleof (fun (x, y) -> x + y)) + | DivideQ _ -> transBinOp inp env false args false Expression.Divide (methodhandleof (fun (x, y) -> x / y)) + | MinusQ _ -> transBinOp inp env false args false Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) + | MultiplyQ _ -> transBinOp inp env false args false Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) + | ModuloQ _ -> transBinOp inp env false args false Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) + + | ShiftLeftQ _ -> transBinOp inp env false args false Expression.LeftShift (methodhandleof (fun (x, y) -> x <<< y)) + | ShiftRightQ _ -> transBinOp inp env false args false Expression.RightShift (methodhandleof (fun (x, y) -> x >>> y)) + | BitwiseAndQ _ -> transBinOp inp env false args false Expression.And (methodhandleof (fun (x, y) -> x &&& y)) + | BitwiseOrQ _ -> transBinOp inp env false args false Expression.Or (methodhandleof (fun (x, y) -> x ||| y)) + | BitwiseXorQ _ -> transBinOp inp env false args false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> x ^^^ y)) | BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr - | CheckedPlusQ _ -> transBinOp inp env false args false Expression.AddChecked - | CheckedMinusQ _ -> transBinOp inp env false args false Expression.SubtractChecked - | CheckedMultiplyQ _ -> transBinOp inp env false args false Expression.MultiplyChecked + | CheckedPlusQ _ -> transBinOp inp env false args false Expression.AddChecked (methodhandleof (fun (x, y) -> Checked.(+) x y)) + | CheckedMinusQ _ -> transBinOp inp env false args false Expression.SubtractChecked (methodhandleof (fun (x, y) -> Checked.(-) x y)) + | CheckedMultiplyQ _ -> transBinOp inp env false args false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> Checked.(*) x y)) - | NullablePlusQ _ -> transBinOp inp env false args true Expression.Add - | PlusNullableQ _ -> transBinOp inp env true args false Expression.Add - | NullablePlusNullableQ _ -> transBinOp inp env false args false Expression.Add + | NullablePlusQ _ -> transBinOp inp env false args true Expression.Add (methodhandleof (fun (x, y) -> x + y)) + | PlusNullableQ _ -> transBinOp inp env true args false Expression.Add (methodhandleof (fun (x, y) -> x + y)) + | NullablePlusNullableQ _ -> transBinOp inp env false args false Expression.Add (methodhandleof (fun (x, y) -> x + y)) - | NullableMinusQ _ -> transBinOp inp env false args true Expression.Subtract - | MinusNullableQ _ -> transBinOp inp env true args false Expression.Subtract - | NullableMinusNullableQ _ -> transBinOp inp env false args false Expression.Subtract + | NullableMinusQ _ -> transBinOp inp env false args true Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) + | MinusNullableQ _ -> transBinOp inp env true args false Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) + | NullableMinusNullableQ _ -> transBinOp inp env false args false Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) - | NullableMultiplyQ _ -> transBinOp inp env false args true Expression.Multiply - | MultiplyNullableQ _ -> transBinOp inp env true args false Expression.Multiply - | NullableMultiplyNullableQ _ -> transBinOp inp env false args false Expression.Multiply + | NullableMultiplyQ _ -> transBinOp inp env false args true Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) + | MultiplyNullableQ _ -> transBinOp inp env true args false Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) + | NullableMultiplyNullableQ _ -> transBinOp inp env false args false Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) - | NullableDivideQ _ -> transBinOp inp env false args true Expression.Divide - | DivideNullableQ _ -> transBinOp inp env true args false Expression.Divide - | NullableDivideNullableQ _ -> transBinOp inp env false args false Expression.Divide + | NullableDivideQ _ -> transBinOp inp env false args true Expression.Divide (methodhandleof (fun (x, y) -> x / y)) + | DivideNullableQ _ -> transBinOp inp env true args false Expression.Divide (methodhandleof (fun (x, y) -> x / y)) + | NullableDivideNullableQ _ -> transBinOp inp env false args false Expression.Divide (methodhandleof (fun (x, y) -> x / y)) - | NullableModuloQ _ -> transBinOp inp env false args true Expression.Modulo - | ModuloNullableQ _ -> transBinOp inp env true args false Expression.Modulo - | NullableModuloNullableQ _ -> transBinOp inp env false args false Expression.Modulo + | NullableModuloQ _ -> transBinOp inp env false args true Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) + | ModuloNullableQ _ -> transBinOp inp env true args false Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) + | NullableModuloNullableQ _ -> transBinOp inp env false args false Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr @@ -665,7 +665,7 @@ module LeafExpressionConverter = and failConvert inp = 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 inp env addConvertLeft args addConvertRight (exprErasedConstructor : _ * _ -> _) = + and transBinBoolOp inp env addConvertLeft args addConvertRight (exprErasedConstructor: _ * _ -> _) = match args with | [x1; x2] -> let e1 = ConvExprToLinqInContext env x1 @@ -675,6 +675,22 @@ module LeafExpressionConverter = exprErasedConstructor(e1, e2) |> asExpr | _ -> failConvert inp + and transBinOp inp env addConvertLeft args addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = + 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 + try exprErasedConstructor(e1, e2, null) with e -> + // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. + try exprErasedConstructor(e1, e2, System.Reflection.MethodInfo.GetMethodFromHandle fallback :?> _) with _ -> + // Still failing. Preserve descriptive exception stack traces. + System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e).Throw() + failwith "Unreachable" + |> asExpr + | _ -> failConvert inp + and ConvObjArg env objOpt coerceTo : Expression = match objOpt with | Some obj -> diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 06921be7304..49a20a50e74 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -1404,7 +1404,7 @@ namedModuleDefnBlock: { Choice1Of2 $1.Lid } -/* A module definition that inccludes a 'begin'...'end' (rarely used in F# with #light syntax) */ +/* A module definition that includes a 'begin'...'end' (rarely used in F# with #light syntax) */ wrappedNamedModuleDefn: | structOrBegin moduleDefnsOrExprPossiblyEmpty END { $2 } diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 6415c466a65..b67b163f02a 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -1543,7 +1543,7 @@ module MoreQuotationsTests = [Coerce (enumerator, Object)])), Dispose, []), Value ()))))""" - let t9() = <@@ try failwith "test" with Failure _ -> 0 @@> + let t9() = <@@ try failwith "test" with Failure _ -> 0 @@> checkStrings "vwewvwewe9" (sprintf "%A" (t9())) """TryWith (Call (None, FailWith, [Value ("test")]), matchValue, Let (activePatternResult1557, Call (None, FailurePattern, [matchValue]), @@ -3383,267 +3383,355 @@ module WitnessTests = test "check CallWithWitnesses all operators)" (let tests = - [ <@@ sin 1.0 @@>, true - <@@ sin 1.0f @@>, true - <@@ sign 1.0f @@>, true - <@@ sqrt 1.0f @@>, true - <@@ 2.0f ** 2.0f @@>, true - <@@ atan2 3.0 4.0 @@>, true - <@@ 1.0f + 4.0f @@>, true - <@@ 1.0f - 4.0f @@>, true - <@@ 1.0f * 4.0f @@>, true - <@@ 1.0M * 4.0M @@>, true - <@@ 1.0f / 4.0f @@>, true - <@@ 1 % 4 @@>, true - <@@ -(4.0M) @@>, true - - <@@ 1y <<< 3 @@>, true - <@@ 1uy <<< 3 @@>, true - <@@ 1s <<< 3 @@>, true - <@@ 1us <<< 3 @@>, true - <@@ 1 <<< 3 @@>, true - <@@ 1u <<< 3 @@>, true - <@@ 1L <<< 3 @@>, true - <@@ 1UL <<< 3 @@>, true - <@@ LanguagePrimitives.GenericOne <<< 3 @@>, false - <@@ LanguagePrimitives.GenericOne <<< 3 @@>, false - - <@@ 1y >>> 3 @@>, true - <@@ 1uy >>> 3 @@>, true - <@@ 1s >>> 3 @@>, true - <@@ 1us >>> 3 @@>, true - <@@ 1 >>> 3 @@>, true - <@@ 1u >>> 3 @@>, true - <@@ 1L >>> 3 @@>, true - <@@ 1UL >>> 3 @@>, true - <@@ LanguagePrimitives.GenericOne >>> 3 @@>, false - <@@ LanguagePrimitives.GenericOne >>> 3 @@>, false + [ <@@ sin 1.0 @@>, Some <@@ 0.8414709848 @@> + <@@ sin 1.0f @@>, Some <@@ 0.841470957f @@> + <@@ sign 1.0f @@>, Some <@@ 1 @@> + <@@ sqrt 1.0f @@>, Some <@@ 1f @@> + <@@ atan2 3.0 4.0 @@>, Some <@@ 0.6435011088 @@> + <@@ atan2 3.0 4.0 @@>, Some <@@ 0.6435011088 @@> - <@@ 1y &&& 3y @@>, true - <@@ 1uy &&& 3uy @@>, true - <@@ 1s &&& 3s @@>, true - <@@ 1us &&& 3us @@>, true - <@@ 1 &&& 3 @@>, true - <@@ 1u &&& 3u @@>, true - <@@ 1L &&& 3L @@>, true - <@@ 1UL &&& 3UL @@>, true - <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, false - <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, false - - <@@ 1y ||| 3y @@>, true - <@@ 1uy ||| 3uy @@>, true - <@@ 1s ||| 3s @@>, true - <@@ 1us ||| 3us @@>, true - <@@ 1 ||| 3 @@>, true - <@@ 1u ||| 3u @@>, true - <@@ 1L ||| 3L @@>, true - <@@ 1UL ||| 3UL @@>, true - <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, false - <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, false - - <@@ 1y ^^^ 3y @@>, true - <@@ 1uy ^^^ 3uy @@>, true - <@@ 1s ^^^ 3s @@>, true - <@@ 1us ^^^ 3us @@>, true - <@@ 1 ^^^ 3 @@>, true - <@@ 1u ^^^ 3u @@>, true - <@@ 1L ^^^ 3L @@>, true - <@@ 1UL ^^^ 3UL @@>, true - <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, false - <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, false - - <@@ ~~~3y @@>, true - <@@ ~~~3uy @@>, true - <@@ ~~~3s @@>, true - <@@ ~~~3us @@>, true - <@@ ~~~3 @@>, true - <@@ ~~~3u @@>, true - <@@ ~~~3L @@>, true - <@@ ~~~3UL @@>, true - <@@ ~~~LanguagePrimitives.GenericOne @@>, false - <@@ ~~~LanguagePrimitives.GenericOne @@>, false - - <@@ byte 3uy @@>, true - <@@ byte 3y @@>, true - <@@ byte 3s @@>, true - <@@ byte 3us @@>, true - <@@ byte 3 @@>, true - <@@ byte 3u @@>, true - <@@ byte 3L @@>, true - <@@ byte 3UL @@>, true - <@@ byte 3.0f @@>, true - <@@ byte 3.0 @@>, true - <@@ byte LanguagePrimitives.GenericOne @@>, false - <@@ byte LanguagePrimitives.GenericOne @@>, false - <@@ byte 3.0M @@>, true - <@@ byte "3" @@>, false - - <@@ sbyte 3uy @@>, true - <@@ sbyte 3y @@>, true - <@@ sbyte 3s @@>, true - <@@ sbyte 3us @@>, true - <@@ sbyte 3 @@>, true - <@@ sbyte 3u @@>, true - <@@ sbyte 3L @@>, true - <@@ sbyte 3UL @@>, true - <@@ sbyte 3.0f @@>, true - <@@ sbyte 3.0 @@>, true - <@@ sbyte LanguagePrimitives.GenericOne @@>, false - <@@ sbyte LanguagePrimitives.GenericOne @@>, false - <@@ sbyte 3.0M @@>, true - <@@ sbyte "3" @@>, false - - <@@ int16 3uy @@>, true - <@@ int16 3y @@>, true - <@@ int16 3s @@>, true - <@@ int16 3us @@>, true - <@@ int16 3 @@>, true - <@@ int16 3u @@>, true - <@@ int16 3L @@>, true - <@@ int16 3UL @@>, true - <@@ int16 3.0f @@>, true - <@@ int16 3.0 @@>, true - <@@ int16 LanguagePrimitives.GenericOne @@>, false - <@@ int16 LanguagePrimitives.GenericOne @@>, false - <@@ int16 3.0M @@>, true - <@@ int16 "3" @@>, false - - <@@ uint16 3uy @@>, true - <@@ uint16 3y @@>, true - <@@ uint16 3s @@>, true - <@@ uint16 3us @@>, true - <@@ uint16 3 @@>, true - <@@ uint16 3u @@>, true - <@@ uint16 3L @@>, true - <@@ uint16 3UL @@>, true - <@@ uint16 3.0f @@>, true - <@@ uint16 3.0 @@>, true - <@@ uint16 LanguagePrimitives.GenericOne @@>, false - <@@ uint16 LanguagePrimitives.GenericOne @@>, false - <@@ uint16 3.0M @@>, true - <@@ uint16 "3" @@>, false - - <@@ int32 3uy @@>, true - <@@ int32 3y @@>, true - <@@ int32 3s @@>, true - <@@ int32 3us @@>, true - <@@ int32 3 @@>, true - <@@ int32 3u @@>, true - <@@ int32 3L @@>, true - <@@ int32 3UL @@>, true - <@@ int32 3.0f @@>, true - <@@ int32 3.0 @@>, true - <@@ int32 LanguagePrimitives.GenericOne @@>, false - <@@ int32 LanguagePrimitives.GenericOne @@>, false - <@@ int32 3.0M @@>, true - <@@ int32 "3" @@>, false - - <@@ uint32 3uy @@>, true - <@@ uint32 3y @@>, true - <@@ uint32 3s @@>, true - <@@ uint32 3us @@>, true - <@@ uint32 3 @@>, true - <@@ uint32 3u @@>, true - <@@ uint32 3L @@>, true - <@@ uint32 3UL @@>, true - <@@ uint32 3.0f @@>, true - <@@ uint32 3.0 @@>, true - <@@ uint32 LanguagePrimitives.GenericOne @@>, false - <@@ uint32 LanguagePrimitives.GenericOne @@>, false - <@@ uint32 3.0M @@>, true - <@@ uint32 "3" @@>, false - - <@@ int64 3uy @@>, true - <@@ int64 3y @@>, true - <@@ int64 3s @@>, true - <@@ int64 3us @@>, true - <@@ int64 3 @@>, true - <@@ int64 3u @@>, true - <@@ int64 3L @@>, true - <@@ int64 3UL @@>, true - <@@ int64 3.0f @@>, true - <@@ int64 3.0 @@>, true - <@@ int64 LanguagePrimitives.GenericOne @@>, false - <@@ int64 LanguagePrimitives.GenericOne @@>, false - <@@ int64 3.0M @@>, true - <@@ int64 "3" @@>, false + <@@ 1y + 4y @@>, Some <@@ 5y @@> + <@@ 1uy + 4uy @@>, Some <@@ 5uy @@> + <@@ 1s + 4s @@>, Some <@@ 5s @@> + <@@ 1us + 4us @@>, Some <@@ 5us @@> + <@@ 1 + 4 @@>, Some <@@ 5 @@> + <@@ 1u + 4u @@>, Some <@@ 5u @@> + <@@ 1L + 4L @@>, Some <@@ 5L @@> + <@@ 1uL + 4uL @@>, Some <@@ 5uL @@> + <@@ 1.0f + 4.0f @@>, Some <@@ 5f @@> + <@@ 1.0 + 4.0 @@>, Some <@@ 5. @@> + <@@ 1m + 4m @@>, Some <@@ 5m @@> + <@@ '1' + '\004' @@>, Some <@@ '5' @@> + <@@ "abc" + "def" @@>, Some <@@ "abcdef" @@> + <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, None + + <@@ 4y - 1y @@>, Some <@@ 3y @@> + <@@ 4uy - 1uy @@>, Some <@@ 3uy @@> + <@@ 4s - 1s @@>, Some <@@ 3s @@> + <@@ 4us - 1us @@>, Some <@@ 3us @@> + <@@ 4 - 1 @@>, Some <@@ 3 @@> + <@@ 4u - 1u @@>, Some <@@ 3u @@> + <@@ 4L - 1L @@>, Some <@@ 3L @@> + <@@ 4uL - 1uL @@>, Some <@@ 3uL @@> + <@@ 4.0f - 1.0f @@>, Some <@@ 3f @@> + <@@ 4.0 - 1.0 @@>, Some <@@ 3. @@> + <@@ 4m - 1m @@>, Some <@@ 3m @@> + <@@ '4' - '\001' @@>, Some <@@ '3' @@> + <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, None + + <@@ 2y * 4y @@>, Some <@@ 8y @@> + <@@ 2uy * 4uy @@>, Some <@@ 8uy @@> + <@@ 2s * 4s @@>, Some <@@ 8s @@> + <@@ 2us * 4us @@>, Some <@@ 8us @@> + <@@ 2 * 4 @@>, Some <@@ 8 @@> + <@@ 2u * 4u @@>, Some <@@ 8u @@> + <@@ 2L * 4L @@>, Some <@@ 8L @@> + <@@ 2uL * 4uL @@>, Some <@@ 8uL @@> + <@@ 2.0f * 4.0f @@>, Some <@@ 8f @@> + <@@ 2.0 * 4.0 @@>, Some <@@ 8. @@> + <@@ 2m * 4m @@>, Some <@@ 8m @@> + <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, None + + <@@ 6y / 3y @@>, Some <@@ 2y @@> + <@@ 6uy / 3uy @@>, Some <@@ 2uy @@> + <@@ 6s / 3s @@>, Some <@@ 2s @@> + <@@ 6us / 3us @@>, Some <@@ 2us @@> + <@@ 6 / 3 @@>, Some <@@ 2 @@> + <@@ 6u / 3u @@>, Some <@@ 2u @@> + <@@ 6L / 3L @@>, Some <@@ 2L @@> + <@@ 6uL / 3uL @@>, Some <@@ 2uL @@> + <@@ 6.0f / 3.0f @@>, Some <@@ 2f @@> + <@@ 6.0 / 3.0 @@>, Some <@@ 2. @@> + <@@ 6m / 3m @@>, Some <@@ 2m @@> + <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, None + + <@@ 9y % 4y @@>, Some <@@ 1y @@> + <@@ 9uy % 4uy @@>, Some <@@ 1uy @@> + <@@ 9s % 4s @@>, Some <@@ 1s @@> + <@@ 9us % 4us @@>, Some <@@ 1us @@> + <@@ 9 % 4 @@>, Some <@@ 1 @@> + <@@ 9u % 4u @@>, Some <@@ 1u @@> + <@@ 9L % 4L @@>, Some <@@ 1L @@> + <@@ 9uL % 4uL @@>, Some <@@ 1uL @@> + <@@ 9.0f % 4.0f @@>, Some <@@ 1f @@> + <@@ 9.0 % 4.0 @@>, Some <@@ 1. @@> + <@@ 9m % 4m @@>, Some <@@ 1m @@> + <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, None + + <@@ -(1y) @@>, Some <@@ -1y @@> + <@@ -(1s) @@>, Some <@@ -1s @@> + <@@ -(1) @@>, Some <@@ -1 @@> + <@@ -(1L) @@>, Some <@@ -1L @@> + <@@ -(1f) @@>, Some <@@ -1f @@> + <@@ -(1.) @@>, Some <@@ -1. @@> + <@@ -(1m) @@>, Some <@@ -1m @@> + <@@ -(LanguagePrimitives.GenericOne) @@>, None + + <@@ 4f ** 3f @@>, Some <@@ 64f @@> + <@@ 4. ** 3. @@>, Some <@@ 64. @@> + <@@ 4m ** 3m @@>, Some <@@ 64m @@> + + <@@ 1y <<< 3 @@>, Some <@@ 8y @@> + <@@ 1uy <<< 3 @@>, Some <@@ 8uy @@> + <@@ 1s <<< 3 @@>, Some <@@ 8s @@> + <@@ 1us <<< 3 @@>, Some <@@ 8us @@> + <@@ 1 <<< 3 @@>, Some <@@ 8 @@> + <@@ 1u <<< 3 @@>, Some <@@ 8u @@> + <@@ 1L <<< 3 @@>, Some <@@ 8L @@> + <@@ 1UL <<< 3 @@>, Some <@@ 8UL @@> + <@@ LanguagePrimitives.GenericOne <<< 3 @@>, None + <@@ LanguagePrimitives.GenericOne <<< 3 @@>, None + + <@@ 1y >>> 3 @@>, Some <@@ 0y @@> + <@@ 1uy >>> 3 @@>, Some <@@ 0uy @@> + <@@ 1s >>> 3 @@>, Some <@@ 0s @@> + <@@ 1us >>> 3 @@>, Some <@@ 0us @@> + <@@ 1 >>> 3 @@>, Some <@@ 0 @@> + <@@ 1u >>> 3 @@>, Some <@@ 0u @@> + <@@ 1L >>> 3 @@>, Some <@@ 0L @@> + <@@ 1UL >>> 3 @@>, Some <@@ 0UL @@> + <@@ LanguagePrimitives.GenericOne >>> 3 @@>, None + <@@ LanguagePrimitives.GenericOne >>> 3 @@>, None - <@@ uint64 3uy @@>, true - <@@ uint64 3y @@>, true - <@@ uint64 3s @@>, true - <@@ uint64 3us @@>, true - <@@ uint64 3 @@>, true - <@@ uint64 3u @@>, true - <@@ uint64 3L @@>, true - <@@ uint64 3UL @@>, true - <@@ uint64 3.0f @@>, true - <@@ uint64 3.0 @@>, true - <@@ uint64 LanguagePrimitives.GenericOne @@>, false - <@@ uint64 LanguagePrimitives.GenericOne @@>, false - <@@ uint64 3.0M @@>, true - <@@ uint64 "3" @@>, false - - <@@ nativeint 3uy @@>, true - <@@ nativeint 3y @@>, true - <@@ nativeint 3s @@>, true - <@@ nativeint 3us @@>, true - <@@ nativeint 3 @@>, true - <@@ nativeint 3u @@>, true - <@@ nativeint 3L @@>, true - <@@ nativeint 3UL @@>, true - <@@ nativeint 3.0f @@>, true - <@@ nativeint 3.0 @@>, true - <@@ nativeint LanguagePrimitives.GenericOne @@>, false - <@@ nativeint LanguagePrimitives.GenericOne @@>, false - //<@@ nativeint 3.0M @@>, false - //<@@ nativeint "3" @@>, false - - <@@ unativeint 3uy @@>, true - <@@ unativeint 3y @@>, true - <@@ unativeint 3s @@>, true - <@@ unativeint 3us @@>, true - <@@ unativeint 3 @@>, true - <@@ unativeint 3u @@>, true - <@@ unativeint 3L @@>, true - <@@ unativeint 3UL @@>, true - <@@ unativeint 3.0f @@>, true - <@@ unativeint 3.0 @@>, true - <@@ unativeint LanguagePrimitives.GenericOne @@>, false - <@@ unativeint LanguagePrimitives.GenericOne @@>, false - //<@@ unativeint 3.0M @@>, true - //<@@ unativeint "3" @@>, true - - <@@ LanguagePrimitives.GenericZero @@>, true - <@@ LanguagePrimitives.GenericZero @@>, true - <@@ LanguagePrimitives.GenericZero @@>, true - <@@ LanguagePrimitives.GenericZero @@>, true - <@@ LanguagePrimitives.GenericZero @@>, true - <@@ LanguagePrimitives.GenericZero @@>, true - <@@ LanguagePrimitives.GenericOne @@>, true - <@@ LanguagePrimitives.GenericOne @@>, true - <@@ LanguagePrimitives.GenericOne @@>, true - <@@ LanguagePrimitives.GenericOne @@>, true - <@@ LanguagePrimitives.GenericOne @@>, true - <@@ LanguagePrimitives.GenericOne @@>, true - <@@ List.sum [ 1; 2 ] @@>, true - <@@ List.sum [ 1.0f; 2.0f ] @@>, true - <@@ List.sum [ 1.0; 2.0 ] @@>, true - <@@ List.sum [ 1.0M; 2.0M ] @@>, true - <@@ List.average [ 1.0; 2.0 ] @@>, true - <@@ List.average [ 1.0f; 2.0f ] @@>, true - <@@ List.average [ 1.0M; 2.0M ] @@>, true + <@@ 1y &&& 3y @@>, Some <@@ 1y @@> + <@@ 1uy &&& 3uy @@>, Some <@@ 1uy @@> + <@@ 1s &&& 3s @@>, Some <@@ 1s @@> + <@@ 1us &&& 3us @@>, Some <@@ 1us @@> + <@@ 1 &&& 3 @@>, Some <@@ 1 @@> + <@@ 1u &&& 3u @@>, Some <@@ 1u @@> + <@@ 1L &&& 3L @@>, Some <@@ 1L @@> + <@@ 1UL &&& 3UL @@>, Some <@@ 1UL @@> + <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, None + + <@@ 1y ||| 3y @@>, Some <@@ 3y @@> + <@@ 1uy ||| 3uy @@>, Some <@@ 3uy @@> + <@@ 1s ||| 3s @@>, Some <@@ 3s @@> + <@@ 1us ||| 3us @@>, Some <@@ 3us @@> + <@@ 1 ||| 3 @@>, Some <@@ 3 @@> + <@@ 1u ||| 3u @@>, Some <@@ 3u @@> + <@@ 1L ||| 3L @@>, Some <@@ 3L @@> + <@@ 1UL ||| 3UL @@>, Some <@@ 3UL @@> + <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, None + + <@@ 1y ^^^ 3y @@>, Some <@@ 2y @@> + <@@ 1uy ^^^ 3uy @@>, Some <@@ 2uy @@> + <@@ 1s ^^^ 3s @@>, Some <@@ 2s @@> + <@@ 1us ^^^ 3us @@>, Some <@@ 2us @@> + <@@ 1 ^^^ 3 @@>, Some <@@ 2 @@> + <@@ 1u ^^^ 3u @@>, Some <@@ 2u @@> + <@@ 1L ^^^ 3L @@>, Some <@@ 2L @@> + <@@ 1UL ^^^ 3UL @@>, Some <@@ 2UL @@> + <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, None + + <@@ ~~~3y @@>, Some <@@ -4y @@> + <@@ ~~~3uy @@>, Some <@@ 252uy @@> + <@@ ~~~3s @@>, Some <@@ -4s @@> + <@@ ~~~3us @@>, Some <@@ 65532us @@> + <@@ ~~~3 @@>, Some <@@ -4 @@> + <@@ ~~~3u @@>, Some <@@ 4294967292u @@> + <@@ ~~~3L @@>, Some <@@ -4L @@> + <@@ ~~~3UL @@>, Some <@@ 18446744073709551612UL @@> + <@@ ~~~LanguagePrimitives.GenericOne @@>, None + <@@ ~~~LanguagePrimitives.GenericOne @@>, None + + <@@ byte 3uy @@>, Some <@@ 3uy @@> + <@@ byte 3y @@>, Some <@@ 3uy @@> + <@@ byte 3s @@>, Some <@@ 3uy @@> + <@@ byte 3us @@>, Some <@@ 3uy @@> + <@@ byte 3 @@>, Some <@@ 3uy @@> + <@@ byte 3u @@>, Some <@@ 3uy @@> + <@@ byte 3L @@>, Some <@@ 3uy @@> + <@@ byte 3UL @@>, Some <@@ 3uy @@> + <@@ byte 3.0f @@>, Some <@@ 3uy @@> + <@@ byte 3.0 @@>, Some <@@ 3uy @@> + <@@ byte LanguagePrimitives.GenericOne @@>, None + <@@ byte LanguagePrimitives.GenericOne @@>, None + <@@ byte 3.0M @@>, Some <@@ 3uy @@> + <@@ byte "3" @@>, None + + <@@ sbyte 3uy @@>, Some <@@ 3y @@> + <@@ sbyte 3y @@>, Some <@@ 3y @@> + <@@ sbyte 3s @@>, Some <@@ 3y @@> + <@@ sbyte 3us @@>, Some <@@ 3y @@> + <@@ sbyte 3 @@>, Some <@@ 3y @@> + <@@ sbyte 3u @@>, Some <@@ 3y @@> + <@@ sbyte 3L @@>, Some <@@ 3y @@> + <@@ sbyte 3UL @@>, Some <@@ 3y @@> + <@@ sbyte 3.0f @@>, Some <@@ 3y @@> + <@@ sbyte 3.0 @@>, Some <@@ 3y @@> + <@@ sbyte LanguagePrimitives.GenericOne @@>, None + <@@ sbyte LanguagePrimitives.GenericOne @@>, None + <@@ sbyte 3.0M @@>, Some <@@ 3y @@> + <@@ sbyte "3" @@>, None + + <@@ int16 3uy @@>, Some <@@ 3s @@> + <@@ int16 3y @@>, Some <@@ 3s @@> + <@@ int16 3s @@>, Some <@@ 3s @@> + <@@ int16 3us @@>, Some <@@ 3s @@> + <@@ int16 3 @@>, Some <@@ 3s @@> + <@@ int16 3u @@>, Some <@@ 3s @@> + <@@ int16 3L @@>, Some <@@ 3s @@> + <@@ int16 3UL @@>, Some <@@ 3s @@> + <@@ int16 3.0f @@>, Some <@@ 3s @@> + <@@ int16 3.0 @@>, Some <@@ 3s @@> + <@@ int16 LanguagePrimitives.GenericOne @@>, None + <@@ int16 LanguagePrimitives.GenericOne @@>, None + <@@ int16 3.0M @@>, Some <@@ 3s @@> + <@@ int16 "3" @@>, None + + <@@ uint16 3uy @@>, Some <@@ 3us @@> + <@@ uint16 3y @@>, Some <@@ 3s @@> + <@@ uint16 3s @@>, Some <@@ 3s @@> + <@@ uint16 3us @@>, Some <@@ 3s @@> + <@@ uint16 3 @@>, Some <@@ 3s @@> + <@@ uint16 3u @@>, Some <@@ 3s @@> + <@@ uint16 3L @@>, Some <@@ 3s @@> + <@@ uint16 3UL @@>, Some <@@ 3s @@> + <@@ uint16 3.0f @@>, Some <@@ 3s @@> + <@@ uint16 3.0 @@>, Some <@@ 3s @@> + <@@ uint16 LanguagePrimitives.GenericOne @@>, None + <@@ uint16 LanguagePrimitives.GenericOne @@>, None + <@@ uint16 3.0M @@>, Some <@@ 3s @@> + <@@ uint16 "3" @@>, None + + <@@ int32 3uy @@>, Some <@@ 3 @@> + <@@ int32 3y @@>, Some <@@ 3 @@> + <@@ int32 3s @@>, Some <@@ 3 @@> + <@@ int32 3us @@>, Some <@@ 3 @@> + <@@ int32 3 @@>, Some <@@ 3 @@> + <@@ int32 3u @@>, Some <@@ 3 @@> + <@@ int32 3L @@>, Some <@@ 3 @@> + <@@ int32 3UL @@>, Some <@@ 3 @@> + <@@ int32 3.0f @@>, Some <@@ 3 @@> + <@@ int32 3.0 @@>, Some <@@ 3 @@> + <@@ int32 LanguagePrimitives.GenericOne @@>, None + <@@ int32 LanguagePrimitives.GenericOne @@>, None + <@@ int32 3.0M @@>, Some <@@ 3 @@> + <@@ int32 "3" @@>, None + + <@@ uint32 3uy @@>, Some <@@ 3u @@> + <@@ uint32 3y @@>, Some <@@ 3u @@> + <@@ uint32 3s @@>, Some <@@ 3u @@> + <@@ uint32 3us @@>, Some <@@ 3u @@> + <@@ uint32 3 @@>, Some <@@ 3u @@> + <@@ uint32 3u @@>, Some <@@ 3u @@> + <@@ uint32 3L @@>, Some <@@ 3u @@> + <@@ uint32 3UL @@>, Some <@@ 3u @@> + <@@ uint32 3.0f @@>, Some <@@ 3u @@> + <@@ uint32 3.0 @@>, Some <@@ 3u @@> + <@@ uint32 LanguagePrimitives.GenericOne @@>, None + <@@ uint32 LanguagePrimitives.GenericOne @@>, None + <@@ uint32 3.0M @@>, Some <@@ 3u @@> + <@@ uint32 "3" @@>, None + + <@@ int64 3uy @@>, Some <@@ 3L @@> + <@@ int64 3y @@>, Some <@@ 3u @@> + <@@ int64 3s @@>, Some <@@ 3u @@> + <@@ int64 3us @@>, Some <@@ 3u @@> + <@@ int64 3 @@>, Some <@@ 3u @@> + <@@ int64 3u @@>, Some <@@ 3u @@> + <@@ int64 3L @@>, Some <@@ 3u @@> + <@@ int64 3UL @@>, Some <@@ 3u @@> + <@@ int64 3.0f @@>, Some <@@ 3u @@> + <@@ int64 3.0 @@>, Some <@@ 3u @@> + <@@ int64 LanguagePrimitives.GenericOne @@>, None + <@@ int64 LanguagePrimitives.GenericOne @@>, None + <@@ int64 3.0M @@>, Some <@@ 3u @@> + <@@ int64 "3" @@>, None + + <@@ uint64 3uy @@>, Some <@@ 3UL @@> + <@@ uint64 3y @@>, Some <@@ 3UL @@> + <@@ uint64 3s @@>, Some <@@ 3UL @@> + <@@ uint64 3us @@>, Some <@@ 3UL @@> + <@@ uint64 3 @@>, Some <@@ 3UL @@> + <@@ uint64 3u @@>, Some <@@ 3UL @@> + <@@ uint64 3L @@>, Some <@@ 3UL @@> + <@@ uint64 3UL @@>, Some <@@ 3UL @@> + <@@ uint64 3.0f @@>, Some <@@ 3UL @@> + <@@ uint64 3.0 @@>, Some <@@ 3UL @@> + <@@ uint64 LanguagePrimitives.GenericOne @@>, None + <@@ uint64 LanguagePrimitives.GenericOne @@>, None + <@@ uint64 3.0M @@>, Some <@@ 3UL @@> + <@@ uint64 "3" @@>, None + + <@@ nativeint 3uy @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3y @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3s @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3us @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3 @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3u @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3L @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3UL @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3.0f @@>, Some <@@ nativeint 3 @@> + <@@ nativeint 3.0 @@>, Some <@@ nativeint 3 @@> + <@@ nativeint LanguagePrimitives.GenericOne @@>, None + <@@ nativeint LanguagePrimitives.GenericOne @@>, None + //<@@ nativeint 3.0M @@>, None + //<@@ nativeint "3" @@>, None + + <@@ unativeint 3uy @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3y @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3s @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3us @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3 @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3u @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3L @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3UL @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3.0f @@>, Some <@@ unativeint 3 @@> + <@@ unativeint 3.0 @@>, Some <@@ unativeint 3 @@> + <@@ unativeint LanguagePrimitives.GenericOne @@>, None + <@@ unativeint LanguagePrimitives.GenericOne @@>, None + //<@@ unativeint 3.0M @@>, Some <@@ unativeint 3 @@> + //<@@ unativeint "3" @@>, Some <@@ unativeint 3 @@> + + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0. @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0f @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0 @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0L @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0UL @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ nativeint 0 @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ unativeint 0 @@> + <@@ LanguagePrimitives.GenericZero @@>, Some <@@ '\000' @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1. @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1f @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1 @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1L @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1UL @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ nativeint 1 @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ unativeint 1 @@> + <@@ LanguagePrimitives.GenericOne @@>, Some <@@ '\001' @@> + <@@ List.sum [ 1; 2 ] @@>, Some <@@ 3 @@> + <@@ List.sum [ 1.0f; 2.0f ] @@>, Some <@@ 3f @@> + <@@ List.sum [ 1.0; 2.0 ] @@>, Some <@@ 3. @@> + <@@ List.sum [ 1.0M; 2.0M ] @@>, Some <@@ 3m @@> + <@@ List.average [ 1.0; 2.0 ] @@>, Some <@@ 1.5 @@> + <@@ List.average [ 1.0f; 2.0f ] @@>, Some <@@ 1.5f @@> + <@@ List.average [ 1.0M; 2.0M ] @@>, Some <@@ 1.5m @@> ] - tests |> List.forall (fun (test, canEval) -> - if canEval then + tests |> List.map (fun (test, canEval) -> + match canEval with + | Some eval -> printfn "--> checking we can evaluate %A" test - FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test |> ignore - printfn "<-- evaluated!" - else - printfn "skipping evaluation of %A because LinqExpressionConverter can't handle it" test - printfn "checking %A" test + let res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test |> ignore + let b = res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation eval + if b then printfn "<-- Success, It is %A which is equal to %A" res eval + else printfn "<-- FAIL, It is %A which is not equal to %A" res eval + b + | None -> + printfn "--><-- skipping evaluation of %A because LinqExpressionConverter can't handle it" test + true + && match test with - | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> minfo1.IsStatic && minfo2.IsStatic && minfo2.Name = minfo1.Name + "$W" && @@ -3660,7 +3748,7 @@ module WitnessTests = (match args with [ _; _ ] -> true | _ -> false) *) true - | _ -> false)) + | _ -> false)) |> List.forall // Don't short circuit on a failed test module MoreWitnessTests = From ef8a96cbc83109f272c2a961674a76105562f47a Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 19 Jun 2021 17:23:23 +0800 Subject: [PATCH 12/78] Fix types --- tests/fsharp/core/quotes/test.fsx | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index e68b766a0ca..2b2ce6007e3 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3731,24 +3731,24 @@ module WitnessTests = true && match test with - | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> - minfo1.IsStatic && - minfo2.IsStatic && - minfo2.Name = minfo1.Name + "$W" && + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + minfo1.IsStatic && + minfo2.IsStatic && + minfo2.Name = minfo1.Name + "$W" && (* - (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && - minfo2.GetParameters().Length = 3 && - (printfn "checking witnessArgs.Length..."; true) && - witnessArgs.Length = 1 && - (printfn "checking args.Length..."; true) && - args.Length = 2 && - (printfn "witnessArgs..."; true) && - (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && - (printfn "args..."; true) && - (match args with [ _; _ ] -> true | _ -> false) - *) - true - | _ -> false)) |> List.forall id // Don't short circuit on a failed test + (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length..."; true) && + witnessArgs.Length = 1 && + (printfn "checking args.Length..."; true) && + args.Length = 2 && + (printfn "witnessArgs..."; true) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && + (printfn "args..."; true) && + (match args with [ _; _ ] -> true | _ -> false) + *) + true + | _ -> false) |> List.forall id) // Don't short circuit on a failed test module MoreWitnessTests = From e22d8eb32464dfaa14ab70c4c24ebce44261ee3e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 19 Jun 2021 17:25:09 +0800 Subject: [PATCH 13/78] Decimals can't pow --- tests/fsharp/core/quotes/test.fsx | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 2b2ce6007e3..e44b79d4780 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3474,7 +3474,6 @@ module WitnessTests = <@@ 4f ** 3f @@>, Some <@@ 64f @@> <@@ 4. ** 3. @@>, Some <@@ 64. @@> - <@@ 4m ** 3m @@>, Some <@@ 64m @@> <@@ 1y <<< 3 @@>, Some <@@ 8y @@> <@@ 1uy <<< 3 @@>, Some <@@ 8uy @@> From 1f0d8f9b9a598b36fbb528643e85347f601b8164 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 19 Jun 2021 18:26:11 +0800 Subject: [PATCH 14/78] You sneaky --- tests/fsharp/core/quotes/test.fsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index e44b79d4780..7533fde59ce 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3720,7 +3720,7 @@ module WitnessTests = match canEval with | Some eval -> printfn "--> checking we can evaluate %A" test - let res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test |> ignore + let res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test let b = res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation eval if b then printfn "<-- Success, It is %A which is equal to %A" res eval else printfn "<-- FAIL, It is %A which is not equal to %A" res eval From bcf1bae003ca774112709cdcbb837d65d2300223 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 19 Jun 2021 21:49:50 +0800 Subject: [PATCH 15/78] Fix precisions --- tests/fsharp/core/quotes/test.fsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 7533fde59ce..8b77d53ccb1 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3383,12 +3383,12 @@ module WitnessTests = test "check CallWithWitnesses all operators)" (let tests = - [ <@@ sin 1.0 @@>, Some <@@ 0.8414709848 @@> - <@@ sin 1.0f @@>, Some <@@ 0.841470957f @@> + [ <@@ sin 1.0 @@>, Some <@@ 0x3FEAED548F090CEELF @@> // Around 0.841470984807897 + <@@ sin 1.0f @@>, Some <@@ 0x3F576AA4lf @@> // = 0.841471f <@@ sign 1.0f @@>, Some <@@ 1 @@> <@@ sqrt 1.0f @@>, Some <@@ 1f @@> - <@@ atan2 3.0 4.0 @@>, Some <@@ 0.6435011088 @@> - <@@ atan2 3.0 4.0 @@>, Some <@@ 0.6435011088 @@> + <@@ atan2 3.0 4.0 @@>, Some <@@ 0x3FE4978FA3269EE1LF @@> // Around 0.643501108793284 + <@@ atan2 3.0 4.0 @@>, Some <@@ 0x3FE4978FA3269EE1LF @@> // Around 0.643501108793284 <@@ 1y + 4y @@>, Some <@@ 5y @@> <@@ 1uy + 4uy @@>, Some <@@ 5uy @@> From 6bc762584e3f6feaf4c082cf4c2c9f0251a4d5ad Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 20 Jun 2021 00:37:20 +0800 Subject: [PATCH 16/78] Let me look at that exception --- src/fsharp/FSharp.Core/Linq.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 3aea9de8201..7e1d52637b0 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -684,9 +684,9 @@ module LeafExpressionConverter = let e2 = if addConvertRight then Expression.Convert(e2, typedefof>.MakeGenericType [| e2.Type |]) |> asExpr else e2 try exprErasedConstructor(e1, e2, null) with e -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - try exprErasedConstructor(e1, e2, System.Reflection.MethodInfo.GetMethodFromHandle fallback :?> _) with _ -> + try exprErasedConstructor(e1, e2, System.Reflection.MethodInfo.GetMethodFromHandle fallback :?> _) with e' -> // Still failing. Preserve descriptive exception stack traces. - System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e).Throw() + System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e').Throw() failwith "Unreachable" |> asExpr | _ -> failConvert inp From 534e136759c8d88d0b64c6448c18b7c3e9cd26ec Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 20 Jun 2021 14:09:32 +0800 Subject: [PATCH 17/78] Fix it --- src/fsharp/FSharp.Core/Linq.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 7e1d52637b0..12b5d59c01e 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -682,12 +682,12 @@ module LeafExpressionConverter = 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 - try exprErasedConstructor(e1, e2, null) with e -> + try exprErasedConstructor(e1, e2, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - try exprErasedConstructor(e1, e2, System.Reflection.MethodInfo.GetMethodFromHandle fallback :?> _) with e' -> - // Still failing. Preserve descriptive exception stack traces. - System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e').Throw() - failwith "Unreachable" + let nullableUnderlyingType (exp: Expression) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + System.Reflection.MethodInfo.GetMethodFromHandle fallback + :?> System.Reflection.MethodInfo + |> fun method -> exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType e1; nullableUnderlyingType e2 |]) |> asExpr | _ -> failConvert inp From 28d16d2d951e831b698b62346a11e75d3951dda2 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 20 Jun 2021 14:23:33 +0800 Subject: [PATCH 18/78] More tests --- tests/fsharp/core/quotes/test.fsx | 97 +++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 8b77d53ccb1..82da1fcf2c9 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3258,6 +3258,7 @@ module TestMatchBang = #if LANGVERSION_PREVIEW module WitnessTests = open FSharp.Data.UnitSystems.SI.UnitSymbols + open FSharp.Linq test "check CallWithWitness" (<@ 1 + 1 @> @@ -3714,6 +3715,102 @@ module WitnessTests = <@@ List.average [ 1.0; 2.0 ] @@>, Some <@@ 1.5 @@> <@@ List.average [ 1.0f; 2.0f ] @@>, Some <@@ 1.5f @@> <@@ List.average [ 1.0M; 2.0M ] @@>, Some <@@ 1.5m @@> + + <@@ Nullable<_> 1y ?+ 4y @@>, Some <@@ Nullable<_> 5y @@> + <@@ Nullable<_> 1uy ?+ 4uy @@>, Some <@@ Nullable<_> 5uy @@> + <@@ Nullable<_> 1s ?+ 4s @@>, Some <@@ Nullable<_> 5s @@> + <@@ Nullable<_> 1us ?+ 4us @@>, Some <@@ Nullable<_> 5us @@> + <@@ Nullable<_> 1 ?+ 4 @@>, Some <@@ Nullable<_> 5 @@> + <@@ Nullable<_> 1u ?+ 4u @@>, Some <@@ Nullable<_> 5u @@> + <@@ Nullable<_> 1L ?+ 4L @@>, Some <@@ Nullable<_> 5L @@> + <@@ Nullable<_> 1uL ?+ 4uL @@>, Some <@@ Nullable<_> 5uL @@> + <@@ Nullable<_> 1.0f ?+ 4.0f @@>, Some <@@ Nullable<_> 5f @@> + <@@ Nullable<_> 1.0 ?+ 4.0 @@>, Some <@@ Nullable<_> 5. @@> + <@@ Nullable<_> 1m ?+ 4m @@>, Some <@@ Nullable<_> 5m @@> + <@@ Nullable<_> '1' ?+ '\004' @@>, Some <@@ Nullable<_> '5' @@> + <@@ Nullable<_> "abc" ?+ "def" @@>, Some <@@ Nullable<_> "abcdef" @@> + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, None + + <@@ 1y +? Nullable<_> 4y @@>, Some <@@ Nullable<_> 5y @@> + <@@ 1uy +? Nullable<_> 4uy @@>, Some <@@ Nullable<_> 5uy @@> + <@@ 1s +? Nullable<_> 4s @@>, Some <@@ Nullable<_> 5s @@> + <@@ 1us +? Nullable<_> 4us @@>, Some <@@ Nullable<_> 5us @@> + <@@ 1 +? Nullable<_> 4 @@>, Some <@@ Nullable<_> 5 @@> + <@@ 1u +? Nullable<_> 4u @@>, Some <@@ Nullable<_> 5u @@> + <@@ 1L +? Nullable<_> 4L @@>, Some <@@ Nullable<_> 5L @@> + <@@ 1uL +? Nullable<_> 4uL @@>, Some <@@ Nullable<_> 5uL @@> + <@@ 1.0f +? Nullable<_> 4.0f @@>, Some <@@ Nullable<_> 5f @@> + <@@ 1.0 +? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> + <@@ 1m +? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> + <@@ '1' +? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> + <@@ "abc" +? Nullable<_> "def" @@>, Some <@@ Nullable<_> "abcdef" @@> + <@@ LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None + + <@@ Nullable<_> 1y ?+? Nullable<_> 4y @@>, Some <@@ Nullable<_> 5y @@> + <@@ Nullable<_> 1uy ?+? Nullable<_> 4uy @@>, Some <@@ Nullable<_> 5uy @@> + <@@ Nullable<_> 1s ?+? Nullable<_> 4s @@>, Some <@@ Nullable<_> 5s @@> + <@@ Nullable<_> 1us ?+? Nullable<_> 4us @@>, Some <@@ Nullable<_> 5us @@> + <@@ Nullable<_> 1 ?+? Nullable<_> 4 @@>, Some <@@ Nullable<_> 5 @@> + <@@ Nullable<_> 1u ?+? Nullable<_> 4u @@>, Some <@@ Nullable<_> 5u @@> + <@@ Nullable<_> 1L ?+? Nullable<_> 4L @@>, Some <@@ Nullable<_> 5L @@> + <@@ Nullable<_> 1uL ?+? Nullable<_> 4uL @@>, Some <@@ Nullable<_> 5uL @@> + <@@ Nullable<_> 1.0f ?+? Nullable<_> 4.0f @@>, Some <@@ Nullable<_> 5f @@> + <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> + <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> + <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> + <@@ Nullable<_> "abc" ?+? Nullable<_> "def" @@>, Some <@@ Nullable<_> "abcdef" @@> + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None + + <@@ Nullable<_> 1y ?= 1y @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1uy ?= 1uy @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1s ?= 1s @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1us ?= 1us @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1 ?= 1 @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1u ?= 1u @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1L ?= 1L @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1uL ?= 1uL @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1.0f ?= 1.0f @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1.0 ?= 1.0 @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1m ?= 1m @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> '1' ?= '1' @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> "abc" ?= "abc" @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, None + + <@@ 1y =? Nullable<_> 1y @@>, Some <@@ Nullable<_> true @@> + <@@ 1uy =? Nullable<_> 1uy @@>, Some <@@ Nullable<_> true @@> + <@@ 1s =? Nullable<_> 1s @@>, Some <@@ Nullable<_> true @@> + <@@ 1us =? Nullable<_> 1us @@>, Some <@@ Nullable<_> true @@> + <@@ 1 =? Nullable<_> 1 @@>, Some <@@ Nullable<_> true @@> + <@@ 1u =? Nullable<_> 1u @@>, Some <@@ Nullable<_> true @@> + <@@ 1L =? Nullable<_> 1L @@>, Some <@@ Nullable<_> true @@> + <@@ 1uL =? Nullable<_> 1uL @@>, Some <@@ Nullable<_> true @@> + <@@ 1.0f =? Nullable<_> 1.0f @@>, Some <@@ Nullable<_> true @@> + <@@ 1.0 =? Nullable<_> 1.0 @@>, Some <@@ Nullable<_> true @@> + <@@ 1m =? Nullable<_> 1m @@>, Some <@@ Nullable<_> true @@> + <@@ '1' =? Nullable<_> '1' @@>, Some <@@ Nullable<_> true @@> + <@@ "abc" =? Nullable<_> "abc" @@>, Some <@@ Nullable<_> true @@> + <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, None + + <@@ Nullable<_> 1y ?=? Nullable<_> 1y @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1uy ?=? Nullable<_> 1uy @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1s ?=? Nullable<_> 1s @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1us ?=? Nullable<_> 1us @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1 ?=? Nullable<_> 1 @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1u ?=? Nullable<_> 1u @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1L ?=? Nullable<_> 1L @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1uL ?=? Nullable<_> 1uL @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1.0f ?=? Nullable<_> 1.0f @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> "abc" ?=? Nullable<_> "abc" @@>, Some <@@ Nullable<_> true @@> + <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, None ] tests |> List.map (fun (test, canEval) -> From 9fcafbf453ea50cd4ea27235acd44110944cff29 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 20 Jun 2021 14:58:21 +0800 Subject: [PATCH 19/78] Fix twice --- tests/fsharp/core/quotes/test.fsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 82da1fcf2c9..74f23dec8a1 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3258,7 +3258,7 @@ module TestMatchBang = #if LANGVERSION_PREVIEW module WitnessTests = open FSharp.Data.UnitSystems.SI.UnitSymbols - open FSharp.Linq + open FSharp.Linq.NullableOperators test "check CallWithWitness" (<@ 1 + 1 @> From 5dde7fc230fbafa23ea2d5d7ac4065045a6ad946 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 20 Jun 2021 16:48:36 +0800 Subject: [PATCH 20/78] Nullables are only for structs --- tests/fsharp/core/quotes/test.fsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 74f23dec8a1..074dae8a484 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3728,7 +3728,6 @@ module WitnessTests = <@@ Nullable<_> 1.0 ?+ 4.0 @@>, Some <@@ Nullable<_> 5. @@> <@@ Nullable<_> 1m ?+ 4m @@>, Some <@@ Nullable<_> 5m @@> <@@ Nullable<_> '1' ?+ '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ Nullable<_> "abc" ?+ "def" @@>, Some <@@ Nullable<_> "abcdef" @@> <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, None <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, None @@ -3744,7 +3743,6 @@ module WitnessTests = <@@ 1.0 +? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> <@@ 1m +? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> <@@ '1' +? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ "abc" +? Nullable<_> "def" @@>, Some <@@ Nullable<_> "abcdef" @@> <@@ LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None <@@ LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None @@ -3760,7 +3758,6 @@ module WitnessTests = <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ Nullable<_> "abc" ?+? Nullable<_> "def" @@>, Some <@@ Nullable<_> "abcdef" @@> <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None @@ -3776,7 +3773,6 @@ module WitnessTests = <@@ Nullable<_> 1.0 ?= 1.0 @@>, Some <@@ Nullable<_> true @@> <@@ Nullable<_> 1m ?= 1m @@>, Some <@@ Nullable<_> true @@> <@@ Nullable<_> '1' ?= '1' @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> "abc" ?= "abc" @@>, Some <@@ Nullable<_> true @@> <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, None <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, None @@ -3792,7 +3788,6 @@ module WitnessTests = <@@ 1.0 =? Nullable<_> 1.0 @@>, Some <@@ Nullable<_> true @@> <@@ 1m =? Nullable<_> 1m @@>, Some <@@ Nullable<_> true @@> <@@ '1' =? Nullable<_> '1' @@>, Some <@@ Nullable<_> true @@> - <@@ "abc" =? Nullable<_> "abc" @@>, Some <@@ Nullable<_> true @@> <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, None <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, None @@ -3808,7 +3803,6 @@ module WitnessTests = <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, Some <@@ Nullable<_> true @@> <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, Some <@@ Nullable<_> true @@> <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> "abc" ?=? Nullable<_> "abc" @@>, Some <@@ Nullable<_> true @@> <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, None <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, None ] From a87154964e2e205ce8cd87ac66e4edcc31ad4a76 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 20 Jun 2021 22:13:56 +0800 Subject: [PATCH 21/78] Fix wrong operator --- tests/fsharp/core/quotes/test.fsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 074dae8a484..1084a6783d4 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3743,8 +3743,8 @@ module WitnessTests = <@@ 1.0 +? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> <@@ 1m +? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> <@@ '1' +? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, None <@@ Nullable<_> 1y ?+? Nullable<_> 4y @@>, Some <@@ Nullable<_> 5y @@> <@@ Nullable<_> 1uy ?+? Nullable<_> 4uy @@>, Some <@@ Nullable<_> 5uy @@> From 0a020afc6eca91698ddbc2f39440367427bbd709 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 21 Jun 2021 02:32:31 +0800 Subject: [PATCH 22/78] 3rd generic type parameter? --- src/fsharp/FSharp.Core/Linq.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 12b5d59c01e..dc5b3837995 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -687,7 +687,7 @@ module LeafExpressionConverter = let nullableUnderlyingType (exp: Expression) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t System.Reflection.MethodInfo.GetMethodFromHandle fallback :?> System.Reflection.MethodInfo - |> fun method -> exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType e1; nullableUnderlyingType e2 |]) + |> fun method -> exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType e1; nullableUnderlyingType e2; nullableUnderlyingType e1 |]) |> asExpr | _ -> failConvert inp From 110c6041c3d70c96dd67c4871182d178a83362b5 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 21 Jun 2021 14:57:03 +0800 Subject: [PATCH 23/78] Conciseness --- src/fsharp/FSharp.Core/Linq.fs | 163 ++++++++++++++---------------- tests/fsharp/core/quotes/test.fsx | 50 +++++++++ 2 files changed, 126 insertions(+), 87 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index dc5b3837995..5aafccdf3c1 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -360,85 +360,85 @@ module LeafExpressionConverter = | PlusQ (_, [ty1; ty2; ty3], [x1; x2]) when (ty1 = typeof) && (ty2 = typeof) && (ty3 = typeof) -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr - | GenericEqualityQ _ - | EqualsQ _ -> transBinBoolOp inp env false args false Expression.Equal - | NotEqQ _ -> transBinBoolOp inp env false args false Expression.NotEqual - | GreaterQ _ -> transBinBoolOp inp env false args false Expression.GreaterThan - | GreaterEqQ _ -> transBinBoolOp inp env false args false Expression.GreaterThanOrEqual - | LessQ _ -> transBinBoolOp inp env false args false Expression.LessThan - | LessEqQ _ -> transBinBoolOp inp env false args false Expression.LessThanOrEqual + | GenericEqualityQ (_, _, [x1; x2]) + | EqualsQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Equal + | NotEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.NotEqual + | GreaterQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan + | GreaterEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual + | LessQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan + | LessEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ _ -> transBinBoolOp inp env false args false Expression.Equal - | StaticNotEqQ _ -> transBinBoolOp inp env false args false Expression.NotEqual - | StaticGreaterQ _ -> transBinBoolOp inp env false args false Expression.GreaterThan - | StaticGreaterEqQ _ -> transBinBoolOp inp env false args false Expression.GreaterThanOrEqual - | StaticLessQ _ -> transBinBoolOp inp env false args false Expression.LessThan - | StaticLessEqQ _ -> transBinBoolOp inp env false args false Expression.LessThanOrEqual - - | NullableEqualsQ _ -> transBinBoolOp inp env false args true Expression.Equal - | NullableNotEqQ _ -> transBinBoolOp inp env false args true Expression.NotEqual - | NullableGreaterQ _ -> transBinBoolOp inp env false args true Expression.GreaterThan - | NullableGreaterEqQ _ -> transBinBoolOp inp env false args true Expression.GreaterThanOrEqual - | NullableLessQ _ -> transBinBoolOp inp env false args true Expression.LessThan - | NullableLessEqQ _ -> transBinBoolOp inp env false args true Expression.LessThanOrEqual - - | EqualsNullableQ _ -> transBinBoolOp inp env true args false Expression.Equal - | NotEqNullableQ _ -> transBinBoolOp inp env true args false Expression.NotEqual - | GreaterNullableQ _ -> transBinBoolOp inp env true args false Expression.GreaterThan - | GreaterEqNullableQ _ -> transBinBoolOp inp env true args false Expression.GreaterThanOrEqual - | LessNullableQ _ -> transBinBoolOp inp env true args false Expression.LessThan - | LessEqNullableQ _ -> transBinBoolOp inp env true args false Expression.LessThanOrEqual - - | NullableEqualsNullableQ _ -> transBinBoolOp inp env false args false Expression.Equal - | NullableNotEqNullableQ _ -> transBinBoolOp inp env false args false Expression.NotEqual - | NullableGreaterNullableQ _ -> transBinBoolOp inp env false args false Expression.GreaterThan - | NullableGreaterEqNullableQ _ -> transBinBoolOp inp env false args false Expression.GreaterThanOrEqual - | NullableLessNullableQ _ -> transBinBoolOp inp env false args false Expression.LessThan - | NullableLessEqNullableQ _ -> transBinBoolOp inp env false args false Expression.LessThanOrEqual + | StaticEqualsQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Equal + | StaticNotEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.NotEqual + | StaticGreaterQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual + | StaticLessQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan + | StaticLessEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual + + | NullableEqualsQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Equal + | NullableNotEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.NotEqual + | NullableGreaterQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.GreaterThan + | NullableGreaterEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.GreaterThanOrEqual + | NullableLessQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.LessThan + | NullableLessEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.LessThanOrEqual + + | EqualsNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Equal + | NotEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.NotEqual + | GreaterNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.GreaterThan + | GreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.GreaterThanOrEqual + | LessNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.LessThan + | LessEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.LessThanOrEqual + + | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Equal + | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.NotEqual + | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan + | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual + | NullableLessNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan + | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 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 _ -> transBinOp inp env false args false Expression.Add (methodhandleof (fun (x, y) -> x + y)) - | DivideQ _ -> transBinOp inp env false args false Expression.Divide (methodhandleof (fun (x, y) -> x / y)) - | MinusQ _ -> transBinOp inp env false args false Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) - | MultiplyQ _ -> transBinOp inp env false args false Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) - | ModuloQ _ -> transBinOp inp env false args false Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) - - | ShiftLeftQ _ -> transBinOp inp env false args false Expression.LeftShift (methodhandleof (fun (x, y) -> x <<< y)) - | ShiftRightQ _ -> transBinOp inp env false args false Expression.RightShift (methodhandleof (fun (x, y) -> x >>> y)) - | BitwiseAndQ _ -> transBinOp inp env false args false Expression.And (methodhandleof (fun (x, y) -> x &&& y)) - | BitwiseOrQ _ -> transBinOp inp env false args false Expression.Or (methodhandleof (fun (x, y) -> x ||| y)) - | BitwiseXorQ _ -> transBinOp inp env false args false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> x ^^^ y)) + | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add LanguagePrimitives.AdditionDynamic + | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract LanguagePrimitives.SubtractionDynamic + | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply LanguagePrimitives.MultiplyDynamic + | DivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide LanguagePrimitives.DivisionDynamic + | ModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo LanguagePrimitives.ModulusDynamic + + | ShiftLeftQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LeftShift LanguagePrimitives.LeftShiftDynamic + | ShiftRightQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.RightShift LanguagePrimitives.RightShiftDynamic + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And LanguagePrimitives.BitwiseAndDynamic + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or LanguagePrimitives.BitwiseOrDynamic + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr LanguagePrimitives.ExclusiveOrDynamic | BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr - | CheckedPlusQ _ -> transBinOp inp env false args false Expression.AddChecked (methodhandleof (fun (x, y) -> Checked.(+) x y)) - | CheckedMinusQ _ -> transBinOp inp env false args false Expression.SubtractChecked (methodhandleof (fun (x, y) -> Checked.(-) x y)) - | CheckedMultiplyQ _ -> transBinOp inp env false args false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> Checked.(*) x y)) + | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked LanguagePrimitives.CheckedAdditionDynamic + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked LanguagePrimitives.CheckedSubtractionDynamic + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked LanguagePrimitives.CheckedMultiplyDynamic - | NullablePlusQ _ -> transBinOp inp env false args true Expression.Add (methodhandleof (fun (x, y) -> x + y)) - | PlusNullableQ _ -> transBinOp inp env true args false Expression.Add (methodhandleof (fun (x, y) -> x + y)) - | NullablePlusNullableQ _ -> transBinOp inp env false args false Expression.Add (methodhandleof (fun (x, y) -> x + y)) + | NullablePlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Add LanguagePrimitives.AdditionDynamic + | PlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Add LanguagePrimitives.AdditionDynamic + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add LanguagePrimitives.AdditionDynamic - | NullableMinusQ _ -> transBinOp inp env false args true Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) - | MinusNullableQ _ -> transBinOp inp env true args false Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) - | NullableMinusNullableQ _ -> transBinOp inp env false args false Expression.Subtract (methodhandleof (fun (x, y) -> x - y)) + | NullableMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Subtract LanguagePrimitives.SubtractionDynamic + | MinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Subtract LanguagePrimitives.SubtractionDynamic + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract LanguagePrimitives.SubtractionDynamic - | NullableMultiplyQ _ -> transBinOp inp env false args true Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) - | MultiplyNullableQ _ -> transBinOp inp env true args false Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) - | NullableMultiplyNullableQ _ -> transBinOp inp env false args false Expression.Multiply (methodhandleof (fun (x, y) -> x * y)) + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Multiply LanguagePrimitives.MultiplyDynamic + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Multiply LanguagePrimitives.MultiplyDynamic + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply LanguagePrimitives.MultiplyDynamic - | NullableDivideQ _ -> transBinOp inp env false args true Expression.Divide (methodhandleof (fun (x, y) -> x / y)) - | DivideNullableQ _ -> transBinOp inp env true args false Expression.Divide (methodhandleof (fun (x, y) -> x / y)) - | NullableDivideNullableQ _ -> transBinOp inp env false args false Expression.Divide (methodhandleof (fun (x, y) -> x / y)) + | NullableDivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Divide LanguagePrimitives.DivisionDynamic + | DivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Divide LanguagePrimitives.DivisionDynamic + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide LanguagePrimitives.DivisionDynamic - | NullableModuloQ _ -> transBinOp inp env false args true Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) - | ModuloNullableQ _ -> transBinOp inp env true args false Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) - | NullableModuloNullableQ _ -> transBinOp inp env false args false Expression.Modulo (methodhandleof (fun (x, y) -> x % y)) + | NullableModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Modulo LanguagePrimitives.ModulusDynamic + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo LanguagePrimitives.ModulusDynamic + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo LanguagePrimitives.ModulusDynamic | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr @@ -665,31 +665,20 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) - and transBinBoolOp inp 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 - | _ -> failConvert inp - - and transBinOp inp env addConvertLeft args addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = - 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 + and transBinOp _inp 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 transBinOpFallback inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = + transBinOp inp env addConvertLeft x1 x2 addConvertRight (fun (e1, e2) -> try exprErasedConstructor(e1, e2, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expression) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t - System.Reflection.MethodInfo.GetMethodFromHandle fallback - :?> System.Reflection.MethodInfo - |> fun method -> exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType e1; nullableUnderlyingType e2; nullableUnderlyingType e1 |]) - |> asExpr - | _ -> failConvert inp + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + exprErasedConstructor(e1, e2, (Func<_, _, _>(fallback)).Method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) + ) and ConvObjArg env objOpt coerceTo : Expression = match objOpt with diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 1084a6783d4..824376d1287 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3406,6 +3406,21 @@ module WitnessTests = <@@ "abc" + "def" @@>, Some <@@ "abcdef" @@> <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, None <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, None + <@@ Checked.(+) 1y 4y @@>, Some <@@ 5y @@> + <@@ Checked.(+) 1uy 4uy @@>, Some <@@ 5uy @@> + <@@ Checked.(+) 1s 4s @@>, Some <@@ 5s @@> + <@@ Checked.(+) 1us 4us @@>, Some <@@ 5us @@> + <@@ Checked.(+) 1 4 @@>, Some <@@ 5 @@> + <@@ Checked.(+) 1u 4u @@>, Some <@@ 5u @@> + <@@ Checked.(+) 1L 4L @@>, Some <@@ 5L @@> + <@@ Checked.(+) 1uL 4uL @@>, Some <@@ 5uL @@> + <@@ Checked.(+) 1.0f 4.0f @@>, Some <@@ 5f @@> + <@@ Checked.(+) 1.0 4.0 @@>, Some <@@ 5. @@> + <@@ Checked.(+) 1m 4m @@>, Some <@@ 5m @@> + <@@ Checked.(+) '1' '\004' @@>, Some <@@ '5' @@> + <@@ Checked.(+) "abc" "def" @@>, Some <@@ "abcdef" @@> + <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None + <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None <@@ 4y - 1y @@>, Some <@@ 3y @@> <@@ 4uy - 1uy @@>, Some <@@ 3uy @@> @@ -3421,6 +3436,20 @@ module WitnessTests = <@@ '4' - '\001' @@>, Some <@@ '3' @@> <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, None <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, None + <@@ Checked.(-) 4y 1y @@>, Some <@@ 3y @@> + <@@ Checked.(-) 4uy 1uy @@>, Some <@@ 3uy @@> + <@@ Checked.(-) 4s 1s @@>, Some <@@ 3s @@> + <@@ Checked.(-) 4us 1us @@>, Some <@@ 3us @@> + <@@ Checked.(-) 4 1 @@>, Some <@@ 3 @@> + <@@ Checked.(-) 4u 1u @@>, Some <@@ 3u @@> + <@@ Checked.(-) 4L 1L @@>, Some <@@ 3L @@> + <@@ Checked.(-) 4uL 1uL @@>, Some <@@ 3uL @@> + <@@ Checked.(-) 4.0f 1.0f @@>, Some <@@ 3f @@> + <@@ Checked.(-) 4.0 1.0 @@>, Some <@@ 3. @@> + <@@ Checked.(-) 4m 1m @@>, Some <@@ 3m @@> + <@@ Checked.(-) '4' '\001' @@>, Some <@@ '3' @@> + <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None + <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None <@@ 2y * 4y @@>, Some <@@ 8y @@> <@@ 2uy * 4uy @@>, Some <@@ 8uy @@> @@ -3435,6 +3464,19 @@ module WitnessTests = <@@ 2m * 4m @@>, Some <@@ 8m @@> <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, None <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, None + <@@ Checked.(*) 2y 4y @@>, Some <@@ 8y @@> + <@@ Checked.(*) 2uy 4uy @@>, Some <@@ 8uy @@> + <@@ Checked.(*) 2s 4s @@>, Some <@@ 8s @@> + <@@ Checked.(*) 2us 4us @@>, Some <@@ 8us @@> + <@@ Checked.(*) 2 4 @@>, Some <@@ 8 @@> + <@@ Checked.(*) 2u 4u @@>, Some <@@ 8u @@> + <@@ Checked.(*) 2L 4L @@>, Some <@@ 8L @@> + <@@ Checked.(*) 2uL 4uL @@>, Some <@@ 8uL @@> + <@@ Checked.(*) 2.0f 4.0f @@>, Some <@@ 8f @@> + <@@ Checked.(*) 2.0 4.0 @@>, Some <@@ 8. @@> + <@@ Checked.(*) 2m 4m @@>, Some <@@ 8m @@> + <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None + <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None <@@ 6y / 3y @@>, Some <@@ 2y @@> <@@ 6uy / 3uy @@>, Some <@@ 2uy @@> @@ -3472,6 +3514,14 @@ module WitnessTests = <@@ -(1.) @@>, Some <@@ -1. @@> <@@ -(1m) @@>, Some <@@ -1m @@> <@@ -(LanguagePrimitives.GenericOne) @@>, None + <@@ Checked.(~-) (1y) @@>, Some <@@ -1y @@> + <@@ Checked.(~-) (1s) @@>, Some <@@ -1s @@> + <@@ Checked.(~-) (1) @@>, Some <@@ -1 @@> + <@@ Checked.(~-) (1L) @@>, Some <@@ -1L @@> + <@@ Checked.(~-) (1f) @@>, Some <@@ -1f @@> + <@@ Checked.(~-) (1.) @@>, Some <@@ -1. @@> + <@@ Checked.(~-) (1m) @@>, Some <@@ -1m @@> + <@@ Checked.(~-) (LanguagePrimitives.GenericOne) @@>, None <@@ 4f ** 3f @@>, Some <@@ 64f @@> <@@ 4. ** 3. @@>, Some <@@ 64. @@> From 9457bf36eeadb54b91e346900873f8eb9e006411 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 21 Jun 2021 15:31:20 +0800 Subject: [PATCH 24/78] ??? --- tests/fsharp/core/quotes/test.fsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 824376d1287..fed94dc7804 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3683,18 +3683,18 @@ module WitnessTests = <@@ uint32 "3" @@>, None <@@ int64 3uy @@>, Some <@@ 3L @@> - <@@ int64 3y @@>, Some <@@ 3u @@> - <@@ int64 3s @@>, Some <@@ 3u @@> - <@@ int64 3us @@>, Some <@@ 3u @@> - <@@ int64 3 @@>, Some <@@ 3u @@> - <@@ int64 3u @@>, Some <@@ 3u @@> - <@@ int64 3L @@>, Some <@@ 3u @@> - <@@ int64 3UL @@>, Some <@@ 3u @@> - <@@ int64 3.0f @@>, Some <@@ 3u @@> - <@@ int64 3.0 @@>, Some <@@ 3u @@> + <@@ int64 3y @@>, Some <@@ 3L @@> + <@@ int64 3s @@>, Some <@@ 3L @@> + <@@ int64 3us @@>, Some <@@ 3L @@> + <@@ int64 3 @@>, Some <@@ 3L @@> + <@@ int64 3u @@>, Some <@@ 3L @@> + <@@ int64 3L @@>, Some <@@ 3L @@> + <@@ int64 3UL @@>, Some <@@ 3L @@> + <@@ int64 3.0f @@>, Some <@@ 3L @@> + <@@ int64 3.0 @@>, Some <@@ 3L @@> <@@ int64 LanguagePrimitives.GenericOne @@>, None <@@ int64 LanguagePrimitives.GenericOne @@>, None - <@@ int64 3.0M @@>, Some <@@ 3u @@> + <@@ int64 3.0M @@>, Some <@@ 3L @@> <@@ int64 "3" @@>, None <@@ uint64 3uy @@>, Some <@@ 3UL @@> From 7fb220721bdbda76168743877ed1dadfbbfebd6c Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 21 Jun 2021 18:07:43 +0800 Subject: [PATCH 25/78] Back to method handles --- src/fsharp/FSharp.Core/Linq.fs | 61 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 5aafccdf3c1..cbc44f1b69b 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -402,43 +402,43 @@ module LeafExpressionConverter = Expression.Constant (new System.Decimal(lo, med, hi, isNegative, scale)) |> asExpr | NegQ (_, _, [x1]) -> Expression.Negate(ConvExprToLinqInContext env x1) |> asExpr - | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add LanguagePrimitives.AdditionDynamic - | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract LanguagePrimitives.SubtractionDynamic - | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply LanguagePrimitives.MultiplyDynamic - | DivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide LanguagePrimitives.DivisionDynamic - | ModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo LanguagePrimitives.ModulusDynamic - - | ShiftLeftQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LeftShift LanguagePrimitives.LeftShiftDynamic - | ShiftRightQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.RightShift LanguagePrimitives.RightShiftDynamic - | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And LanguagePrimitives.BitwiseAndDynamic - | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or LanguagePrimitives.BitwiseOrDynamic - | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr LanguagePrimitives.ExclusiveOrDynamic + | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic + | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic + | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic + | DivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic + | ModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic + + | ShiftLeftQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LeftShift <| methodhandleof LanguagePrimitives.LeftShiftDynamic + | ShiftRightQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.RightShift <| methodhandleof LanguagePrimitives.RightShiftDynamic + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And <| methodhandleof LanguagePrimitives.BitwiseAndDynamic + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or <| methodhandleof LanguagePrimitives.BitwiseOrDynamic + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof LanguagePrimitives.ExclusiveOrDynamic | BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr - | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked LanguagePrimitives.CheckedAdditionDynamic - | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked LanguagePrimitives.CheckedSubtractionDynamic - | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked LanguagePrimitives.CheckedMultiplyDynamic + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked <| methodhandleof LanguagePrimitives.CheckedAdditionDynamic + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof LanguagePrimitives.CheckedSubtractionDynamic + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof LanguagePrimitives.CheckedMultiplyDynamic - | NullablePlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Add LanguagePrimitives.AdditionDynamic - | PlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Add LanguagePrimitives.AdditionDynamic - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add LanguagePrimitives.AdditionDynamic + | NullablePlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic + | PlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic - | NullableMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Subtract LanguagePrimitives.SubtractionDynamic - | MinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Subtract LanguagePrimitives.SubtractionDynamic - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract LanguagePrimitives.SubtractionDynamic + | NullableMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic + | MinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Multiply LanguagePrimitives.MultiplyDynamic - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Multiply LanguagePrimitives.MultiplyDynamic - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply LanguagePrimitives.MultiplyDynamic + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic - | NullableDivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Divide LanguagePrimitives.DivisionDynamic - | DivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Divide LanguagePrimitives.DivisionDynamic - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide LanguagePrimitives.DivisionDynamic + | NullableDivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic + | DivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic - | NullableModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Modulo LanguagePrimitives.ModulusDynamic - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo LanguagePrimitives.ModulusDynamic - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo LanguagePrimitives.ModulusDynamic + | NullableModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr @@ -677,7 +677,8 @@ module LeafExpressionConverter = try exprErasedConstructor(e1, e2, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t - exprErasedConstructor(e1, e2, (Func<_, _, _>(fallback)).Method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) ) and ConvObjArg env objOpt coerceTo : Expression = From c53999c47a01081483b7d8af81dbce13a53fa5b5 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 21 Jun 2021 20:50:20 +0800 Subject: [PATCH 26/78] :/ --- src/fsharp/FSharp.Core/Linq.fs | 58 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index cbc44f1b69b..54ee4bd681d 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -402,43 +402,43 @@ module LeafExpressionConverter = Expression.Constant (new System.Decimal(lo, med, hi, isNegative, scale)) |> asExpr | NegQ (_, _, [x1]) -> Expression.Negate(ConvExprToLinqInContext env x1) |> asExpr - | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic - | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic - | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic - | DivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic - | ModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic - - | ShiftLeftQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LeftShift <| methodhandleof LanguagePrimitives.LeftShiftDynamic - | ShiftRightQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.RightShift <| methodhandleof LanguagePrimitives.RightShiftDynamic - | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And <| methodhandleof LanguagePrimitives.BitwiseAndDynamic - | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or <| methodhandleof LanguagePrimitives.BitwiseOrDynamic - | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof LanguagePrimitives.ExclusiveOrDynamic + | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | DivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | ModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + + | ShiftLeftQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LeftShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y) + | ShiftRightQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.RightShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y) + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y) + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y) + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y) | BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr - | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked <| methodhandleof LanguagePrimitives.CheckedAdditionDynamic - | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof LanguagePrimitives.CheckedSubtractionDynamic - | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof LanguagePrimitives.CheckedMultiplyDynamic + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y) + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y) + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y) - | NullablePlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic - | PlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof LanguagePrimitives.AdditionDynamic + | NullablePlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | PlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | NullableMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic - | MinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof LanguagePrimitives.SubtractionDynamic + | NullableMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | MinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof LanguagePrimitives.MultiplyDynamic + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | NullableDivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic - | DivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof LanguagePrimitives.DivisionDynamic + | NullableDivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | DivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | NullableModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof LanguagePrimitives.ModulusDynamic + | NullableModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) | ConvNullableCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr | ConvNullableDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr From 134902daab197219ca74c74ff4fcdce0c848229b Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 21 Jun 2021 23:29:37 +0800 Subject: [PATCH 27/78] Get tests passing? --- src/fsharp/FSharp.Core/Linq.fs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 54ee4bd681d..22b621d3be1 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -355,7 +355,6 @@ module LeafExpressionConverter = 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) -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr @@ -401,7 +400,7 @@ module LeafExpressionConverter = | 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 + | NegQ (_, _, [x]) -> transUnaryOpFallback inp env x Expression.Negate <| methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x) | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) @@ -413,9 +412,9 @@ module LeafExpressionConverter = | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y) | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y) | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y) - | BitwiseNotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr + | BitwiseNotQ (_, _, [x]) -> transUnaryOpFallback inp env x Expression.Not <| methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x) - | CheckedNeg (_, _, [x1]) -> Expression.NegateChecked(ConvExprToLinqInContext env x1) |> asExpr + | CheckedNeg (_, _, [x]) -> transUnaryOpFallback inp env x Expression.NegateChecked <| methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x) | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y) | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y) | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y) @@ -665,6 +664,15 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) + and transUnaryOpFallback inp env x (exprErasedConstructor: _ * _ -> _) fallback = + let e = ConvExprToLinqInContext env x + try exprErasedConstructor(e, null) with _ -> + // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) + |> asExpr + and transBinOp _inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ -> _) = let e1 = ConvExprToLinqInContext env x1 let e2 = ConvExprToLinqInContext env x2 From 0298c65a1293c06cb85f370196aaa70e05617e88 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Tue, 22 Jun 2021 01:23:15 +0800 Subject: [PATCH 28/78] =?UTF-8?q?=F0=9F=A4=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/fsharp/core/quotes/test.fsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index fed94dc7804..c91bd6b9382 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3638,18 +3638,18 @@ module WitnessTests = <@@ int16 "3" @@>, None <@@ uint16 3uy @@>, Some <@@ 3us @@> - <@@ uint16 3y @@>, Some <@@ 3s @@> - <@@ uint16 3s @@>, Some <@@ 3s @@> - <@@ uint16 3us @@>, Some <@@ 3s @@> - <@@ uint16 3 @@>, Some <@@ 3s @@> - <@@ uint16 3u @@>, Some <@@ 3s @@> - <@@ uint16 3L @@>, Some <@@ 3s @@> - <@@ uint16 3UL @@>, Some <@@ 3s @@> - <@@ uint16 3.0f @@>, Some <@@ 3s @@> - <@@ uint16 3.0 @@>, Some <@@ 3s @@> + <@@ uint16 3y @@>, Some <@@ 3us @@> + <@@ uint16 3s @@>, Some <@@ 3us @@> + <@@ uint16 3us @@>, Some <@@ 3us @@> + <@@ uint16 3 @@>, Some <@@ 3us @@> + <@@ uint16 3u @@>, Some <@@ 3us @@> + <@@ uint16 3L @@>, Some <@@ 3us @@> + <@@ uint16 3UL @@>, Some <@@ 3us @@> + <@@ uint16 3.0f @@>, Some <@@ 3us @@> + <@@ uint16 3.0 @@>, Some <@@ 3us @@> <@@ uint16 LanguagePrimitives.GenericOne @@>, None <@@ uint16 LanguagePrimitives.GenericOne @@>, None - <@@ uint16 3.0M @@>, Some <@@ 3s @@> + <@@ uint16 3.0M @@>, Some <@@ 3us @@> <@@ uint16 "3" @@>, None <@@ int32 3uy @@>, Some <@@ 3 @@> From 6947e615b47d15de8004af871ca9e632796ddbb0 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Tue, 22 Jun 2021 17:41:46 +0800 Subject: [PATCH 29/78] Going ambitious --- src/fsharp/FSharp.Core/Linq.fs | 91 +-- tests/fsharp/core/quotes/test.fsx | 993 ++++++++++++++++-------------- 2 files changed, 553 insertions(+), 531 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 22b621d3be1..1da5a2ac5d0 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -99,7 +99,7 @@ module LeafExpressionConverter = 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 (|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)) @@ -185,6 +185,8 @@ module LeafExpressionConverter = 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 (|ConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.nativeint x)) + let (|ConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.unativeint 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")) @@ -208,10 +210,8 @@ module LeafExpressionConverter = 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)) - + let (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.nativeint x)) + let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.unativeint x)) let (|UnboxGeneric|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.UnboxGeneric x)) let (|TypeTestGeneric|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric x)) @@ -226,6 +226,8 @@ module LeafExpressionConverter = let (|CheckedConvUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint16 x)) let (|CheckedConvUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint32 x)) let (|CheckedConvUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint64 x)) + let (|CheckedConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.nativeint x)) + let (|CheckedConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.unativeint x)) let (|ImplicitExpressionConversionHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> ImplicitExpressionConversionHelper x)) let (|MemberInitializationHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> MemberInitializationHelper x)) let (|NewAnonymousObjectHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> NewAnonymousObjectHelper x)) @@ -439,56 +441,23 @@ module LeafExpressionConverter = | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - | 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 - | ConvNullableFloat32Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableSingleQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableSByteQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableInt8Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableInt16Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableInt32Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableIntQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableInt64Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableByteQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableUInt8Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableUInt16Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableUInt32Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - | ConvNullableUInt64Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - // LINQ expressions can't do native integer operations, so we don't convert these - //| ConvNullableIntPtrQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - //| ConvNullableUIntPtrQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof>) |> asExpr - - | ConvCharQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvDecimalQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvFloatQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvDoubleQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvFloat32Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvSingleQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvSByteQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvInt8Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvInt16Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvInt32Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvIntQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvInt64Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvByteQ (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvUInt8Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvUInt16Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvUInt32Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - | ConvUInt64Q (_, _, [x1]) -> Expression.Convert(ConvExprToLinqInContext env x1, typeof) |> asExpr - - | CheckedConvCharQ (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvSByteQ (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvInt8Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvInt16Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvInt32Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvInt64Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvByteQ (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvUInt8Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvUInt16Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvUInt32Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr - | CheckedConvUInt64Q (_, _, [x1]) -> Expression.ConvertChecked(ConvExprToLinqInContext env x1, typeof) |> asExpr + | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) + | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) + | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) + | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) + | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) + + | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) + | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) + | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) + | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) + | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x + + | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) + | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) + | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) + | CheckedConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env true x + | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> Expression.ArrayIndex(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr @@ -672,14 +641,12 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) |> asExpr - and transBinOp _inp 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 transBinOpFallback inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = transBinOp inp env addConvertLeft x1 x2 addConvertRight (fun (e1, e2) -> try exprErasedConstructor(e1, e2, null) with _ -> @@ -688,6 +655,16 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) ) + and transConvFallback (inp: Expr) env isChecked x = + let e = ConvExprToLinqInContext env x + let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert + try exprErasedConstructor(e, inp.Type, null) with _ -> + // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + // The dynamic implementations of checked conversion operators refer to LanguagePrimitives.ExplicitDynamic which is unchecked! This is a bug and should definitely be fixed. + let method = Reflection.MethodInfo.GetMethodFromHandle (methodhandleof (fun x -> LanguagePrimitives.ExplicitDynamic x)) :?> Reflection.MethodInfo + exprErasedConstructor(e, inp.Type, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) + |> asExpr and ConvObjArg env objOpt coerceTo : Expression = match objOpt with diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index c91bd6b9382..c7691dd4b39 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3384,491 +3384,533 @@ module WitnessTests = test "check CallWithWitnesses all operators)" (let tests = - [ <@@ sin 1.0 @@>, Some <@@ 0x3FEAED548F090CEELF @@> // Around 0.841470984807897 - <@@ sin 1.0f @@>, Some <@@ 0x3F576AA4lf @@> // = 0.841471f - <@@ sign 1.0f @@>, Some <@@ 1 @@> - <@@ sqrt 1.0f @@>, Some <@@ 1f @@> - <@@ atan2 3.0 4.0 @@>, Some <@@ 0x3FE4978FA3269EE1LF @@> // Around 0.643501108793284 - <@@ atan2 3.0 4.0 @@>, Some <@@ 0x3FE4978FA3269EE1LF @@> // Around 0.643501108793284 + [ <@@ sin 1.0 @@>, box 0x3FEAED548F090CEELF // Around 0.841470984807897 + <@@ sin 1.0f @@>, box 0x3F576AA4lf // = 0.841471f + <@@ sign 1.0f @@>, box 1 + <@@ sqrt 1.0f @@>, box 1f + <@@ atan2 3.0 4.0 @@>, box 0x3FE4978FA3269EE1LF // Around 0.643501108793284 + <@@ atan2 3.0 4.0 @@>, box 0x3FE4978FA3269EE1LF // Around 0.643501108793284 - <@@ 1y + 4y @@>, Some <@@ 5y @@> - <@@ 1uy + 4uy @@>, Some <@@ 5uy @@> - <@@ 1s + 4s @@>, Some <@@ 5s @@> - <@@ 1us + 4us @@>, Some <@@ 5us @@> - <@@ 1 + 4 @@>, Some <@@ 5 @@> - <@@ 1u + 4u @@>, Some <@@ 5u @@> - <@@ 1L + 4L @@>, Some <@@ 5L @@> - <@@ 1uL + 4uL @@>, Some <@@ 5uL @@> - <@@ 1.0f + 4.0f @@>, Some <@@ 5f @@> - <@@ 1.0 + 4.0 @@>, Some <@@ 5. @@> - <@@ 1m + 4m @@>, Some <@@ 5m @@> - <@@ '1' + '\004' @@>, Some <@@ '5' @@> - <@@ "abc" + "def" @@>, Some <@@ "abcdef" @@> - <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, None - <@@ Checked.(+) 1y 4y @@>, Some <@@ 5y @@> - <@@ Checked.(+) 1uy 4uy @@>, Some <@@ 5uy @@> - <@@ Checked.(+) 1s 4s @@>, Some <@@ 5s @@> - <@@ Checked.(+) 1us 4us @@>, Some <@@ 5us @@> - <@@ Checked.(+) 1 4 @@>, Some <@@ 5 @@> - <@@ Checked.(+) 1u 4u @@>, Some <@@ 5u @@> - <@@ Checked.(+) 1L 4L @@>, Some <@@ 5L @@> - <@@ Checked.(+) 1uL 4uL @@>, Some <@@ 5uL @@> - <@@ Checked.(+) 1.0f 4.0f @@>, Some <@@ 5f @@> - <@@ Checked.(+) 1.0 4.0 @@>, Some <@@ 5. @@> - <@@ Checked.(+) 1m 4m @@>, Some <@@ 5m @@> - <@@ Checked.(+) '1' '\004' @@>, Some <@@ '5' @@> - <@@ Checked.(+) "abc" "def" @@>, Some <@@ "abcdef" @@> - <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None - <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None - - <@@ 4y - 1y @@>, Some <@@ 3y @@> - <@@ 4uy - 1uy @@>, Some <@@ 3uy @@> - <@@ 4s - 1s @@>, Some <@@ 3s @@> - <@@ 4us - 1us @@>, Some <@@ 3us @@> - <@@ 4 - 1 @@>, Some <@@ 3 @@> - <@@ 4u - 1u @@>, Some <@@ 3u @@> - <@@ 4L - 1L @@>, Some <@@ 3L @@> - <@@ 4uL - 1uL @@>, Some <@@ 3uL @@> - <@@ 4.0f - 1.0f @@>, Some <@@ 3f @@> - <@@ 4.0 - 1.0 @@>, Some <@@ 3. @@> - <@@ 4m - 1m @@>, Some <@@ 3m @@> - <@@ '4' - '\001' @@>, Some <@@ '3' @@> - <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, None - <@@ Checked.(-) 4y 1y @@>, Some <@@ 3y @@> - <@@ Checked.(-) 4uy 1uy @@>, Some <@@ 3uy @@> - <@@ Checked.(-) 4s 1s @@>, Some <@@ 3s @@> - <@@ Checked.(-) 4us 1us @@>, Some <@@ 3us @@> - <@@ Checked.(-) 4 1 @@>, Some <@@ 3 @@> - <@@ Checked.(-) 4u 1u @@>, Some <@@ 3u @@> - <@@ Checked.(-) 4L 1L @@>, Some <@@ 3L @@> - <@@ Checked.(-) 4uL 1uL @@>, Some <@@ 3uL @@> - <@@ Checked.(-) 4.0f 1.0f @@>, Some <@@ 3f @@> - <@@ Checked.(-) 4.0 1.0 @@>, Some <@@ 3. @@> - <@@ Checked.(-) 4m 1m @@>, Some <@@ 3m @@> - <@@ Checked.(-) '4' '\001' @@>, Some <@@ '3' @@> - <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None - <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None - - <@@ 2y * 4y @@>, Some <@@ 8y @@> - <@@ 2uy * 4uy @@>, Some <@@ 8uy @@> - <@@ 2s * 4s @@>, Some <@@ 8s @@> - <@@ 2us * 4us @@>, Some <@@ 8us @@> - <@@ 2 * 4 @@>, Some <@@ 8 @@> - <@@ 2u * 4u @@>, Some <@@ 8u @@> - <@@ 2L * 4L @@>, Some <@@ 8L @@> - <@@ 2uL * 4uL @@>, Some <@@ 8uL @@> - <@@ 2.0f * 4.0f @@>, Some <@@ 8f @@> - <@@ 2.0 * 4.0 @@>, Some <@@ 8. @@> - <@@ 2m * 4m @@>, Some <@@ 8m @@> - <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, None - <@@ Checked.(*) 2y 4y @@>, Some <@@ 8y @@> - <@@ Checked.(*) 2uy 4uy @@>, Some <@@ 8uy @@> - <@@ Checked.(*) 2s 4s @@>, Some <@@ 8s @@> - <@@ Checked.(*) 2us 4us @@>, Some <@@ 8us @@> - <@@ Checked.(*) 2 4 @@>, Some <@@ 8 @@> - <@@ Checked.(*) 2u 4u @@>, Some <@@ 8u @@> - <@@ Checked.(*) 2L 4L @@>, Some <@@ 8L @@> - <@@ Checked.(*) 2uL 4uL @@>, Some <@@ 8uL @@> - <@@ Checked.(*) 2.0f 4.0f @@>, Some <@@ 8f @@> - <@@ Checked.(*) 2.0 4.0 @@>, Some <@@ 8. @@> - <@@ Checked.(*) 2m 4m @@>, Some <@@ 8m @@> - <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None - <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, None - - <@@ 6y / 3y @@>, Some <@@ 2y @@> - <@@ 6uy / 3uy @@>, Some <@@ 2uy @@> - <@@ 6s / 3s @@>, Some <@@ 2s @@> - <@@ 6us / 3us @@>, Some <@@ 2us @@> - <@@ 6 / 3 @@>, Some <@@ 2 @@> - <@@ 6u / 3u @@>, Some <@@ 2u @@> - <@@ 6L / 3L @@>, Some <@@ 2L @@> - <@@ 6uL / 3uL @@>, Some <@@ 2uL @@> - <@@ 6.0f / 3.0f @@>, Some <@@ 2f @@> - <@@ 6.0 / 3.0 @@>, Some <@@ 2. @@> - <@@ 6m / 3m @@>, Some <@@ 2m @@> - <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, None - - <@@ 9y % 4y @@>, Some <@@ 1y @@> - <@@ 9uy % 4uy @@>, Some <@@ 1uy @@> - <@@ 9s % 4s @@>, Some <@@ 1s @@> - <@@ 9us % 4us @@>, Some <@@ 1us @@> - <@@ 9 % 4 @@>, Some <@@ 1 @@> - <@@ 9u % 4u @@>, Some <@@ 1u @@> - <@@ 9L % 4L @@>, Some <@@ 1L @@> - <@@ 9uL % 4uL @@>, Some <@@ 1uL @@> - <@@ 9.0f % 4.0f @@>, Some <@@ 1f @@> - <@@ 9.0 % 4.0 @@>, Some <@@ 1. @@> - <@@ 9m % 4m @@>, Some <@@ 1m @@> - <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, None - - <@@ -(1y) @@>, Some <@@ -1y @@> - <@@ -(1s) @@>, Some <@@ -1s @@> - <@@ -(1) @@>, Some <@@ -1 @@> - <@@ -(1L) @@>, Some <@@ -1L @@> - <@@ -(1f) @@>, Some <@@ -1f @@> - <@@ -(1.) @@>, Some <@@ -1. @@> - <@@ -(1m) @@>, Some <@@ -1m @@> - <@@ -(LanguagePrimitives.GenericOne) @@>, None - <@@ Checked.(~-) (1y) @@>, Some <@@ -1y @@> - <@@ Checked.(~-) (1s) @@>, Some <@@ -1s @@> - <@@ Checked.(~-) (1) @@>, Some <@@ -1 @@> - <@@ Checked.(~-) (1L) @@>, Some <@@ -1L @@> - <@@ Checked.(~-) (1f) @@>, Some <@@ -1f @@> - <@@ Checked.(~-) (1.) @@>, Some <@@ -1. @@> - <@@ Checked.(~-) (1m) @@>, Some <@@ -1m @@> - <@@ Checked.(~-) (LanguagePrimitives.GenericOne) @@>, None - - <@@ 4f ** 3f @@>, Some <@@ 64f @@> - <@@ 4. ** 3. @@>, Some <@@ 64. @@> - - <@@ 1y <<< 3 @@>, Some <@@ 8y @@> - <@@ 1uy <<< 3 @@>, Some <@@ 8uy @@> - <@@ 1s <<< 3 @@>, Some <@@ 8s @@> - <@@ 1us <<< 3 @@>, Some <@@ 8us @@> - <@@ 1 <<< 3 @@>, Some <@@ 8 @@> - <@@ 1u <<< 3 @@>, Some <@@ 8u @@> - <@@ 1L <<< 3 @@>, Some <@@ 8L @@> - <@@ 1UL <<< 3 @@>, Some <@@ 8UL @@> - <@@ LanguagePrimitives.GenericOne <<< 3 @@>, None - <@@ LanguagePrimitives.GenericOne <<< 3 @@>, None - - <@@ 1y >>> 3 @@>, Some <@@ 0y @@> - <@@ 1uy >>> 3 @@>, Some <@@ 0uy @@> - <@@ 1s >>> 3 @@>, Some <@@ 0s @@> - <@@ 1us >>> 3 @@>, Some <@@ 0us @@> - <@@ 1 >>> 3 @@>, Some <@@ 0 @@> - <@@ 1u >>> 3 @@>, Some <@@ 0u @@> - <@@ 1L >>> 3 @@>, Some <@@ 0L @@> - <@@ 1UL >>> 3 @@>, Some <@@ 0UL @@> - <@@ LanguagePrimitives.GenericOne >>> 3 @@>, None - <@@ LanguagePrimitives.GenericOne >>> 3 @@>, None + <@@ 1y + 4y @@>, box 5y + <@@ 1uy + 4uy @@>, box 5uy + <@@ 1s + 4s @@>, box 5s + <@@ 1us + 4us @@>, box 5us + <@@ 1 + 4 @@>, box 5 + <@@ 1u + 4u @@>, box 5u + <@@ 1L + 4L @@>, box 5L + <@@ 1uL + 4uL @@>, box 5uL + <@@ 1.0f + 4.0f @@>, box 5f + <@@ 1.0 + 4.0 @@>, box 5. + <@@ 1m + 4m @@>, box 5m + <@@ '1' + '\004' @@>, box '5' + <@@ "abc" + "def" @@>, box "abcdef" + <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, box 2n + <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, box 2un + <@@ Checked.(+) 1y 4y @@>, box 5y + <@@ Checked.(+) 1uy 4uy @@>, box 5uy + <@@ Checked.(+) 1s 4s @@>, box 5s + <@@ Checked.(+) 1us 4us @@>, box 5us + <@@ Checked.(+) 1 4 @@>, box 5 + <@@ Checked.(+) 1u 4u @@>, box 5u + <@@ Checked.(+) 1L 4L @@>, box 5L + <@@ Checked.(+) 1uL 4uL @@>, box 5uL + <@@ Checked.(+) 1.0f 4.0f @@>, box 5f + <@@ Checked.(+) 1.0 4.0 @@>, box 5. + <@@ Checked.(+) 1m 4m @@>, box 5m + <@@ Checked.(+) '1' '\004' @@>, box '5' + <@@ Checked.(+) "abc" "def" @@>, box "abcdef" + <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 2n + <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 2un + + <@@ 4y - 1y @@>, box 3y + <@@ 4uy - 1uy @@>, box 3uy + <@@ 4s - 1s @@>, box 3s + <@@ 4us - 1us @@>, box 3us + <@@ 4 - 1 @@>, box 3 + <@@ 4u - 1u @@>, box 3u + <@@ 4L - 1L @@>, box 3L + <@@ 4uL - 1uL @@>, box 3uL + <@@ 4.0f - 1.0f @@>, box 3f + <@@ 4.0 - 1.0 @@>, box 3. + <@@ 4m - 1m @@>, box 3m + <@@ '4' - '\001' @@>, box '3' + <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, box 0n + <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, box 0un + <@@ Checked.(-) 4y 1y @@>, box 3y + <@@ Checked.(-) 4uy 1uy @@>, box 3uy + <@@ Checked.(-) 4s 1s @@>, box 3s + <@@ Checked.(-) 4us 1us @@>, box 3us + <@@ Checked.(-) 4 1 @@>, box 3 + <@@ Checked.(-) 4u 1u @@>, box 3u + <@@ Checked.(-) 4L 1L @@>, box 3L + <@@ Checked.(-) 4uL 1uL @@>, box 3uL + <@@ Checked.(-) 4.0f 1.0f @@>, box 3f + <@@ Checked.(-) 4.0 1.0 @@>, box 3. + <@@ Checked.(-) 4m 1m @@>, box 3m + <@@ Checked.(-) '4' '\001' @@>, box '3' + <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 0n + <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 0un + + <@@ 2y * 4y @@>, box 8y + <@@ 2uy * 4uy @@>, box 8uy + <@@ 2s * 4s @@>, box 8s + <@@ 2us * 4us @@>, box 8us + <@@ 2 * 4 @@>, box 8 + <@@ 2u * 4u @@>, box 8u + <@@ 2L * 4L @@>, box 8L + <@@ 2uL * 4uL @@>, box 8uL + <@@ 2.0f * 4.0f @@>, box 8f + <@@ 2.0 * 4.0 @@>, box 8. + <@@ 2m * 4m @@>, box 8m + <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, box 1un + <@@ Checked.(*) 2y 4y @@>, box 8y + <@@ Checked.(*) 2uy 4uy @@>, box 8uy + <@@ Checked.(*) 2s 4s @@>, box 8s + <@@ Checked.(*) 2us 4us @@>, box 8us + <@@ Checked.(*) 2 4 @@>, box 8 + <@@ Checked.(*) 2u 4u @@>, box 8u + <@@ Checked.(*) 2L 4L @@>, box 8L + <@@ Checked.(*) 2uL 4uL @@>, box 8uL + <@@ Checked.(*) 2.0f 4.0f @@>, box 8f + <@@ Checked.(*) 2.0 4.0 @@>, box 8. + <@@ Checked.(*) 2m 4m @@>, box 8m + <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 1n + <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 1un + + <@@ 6y / 3y @@>, box 2y + <@@ 6uy / 3uy @@>, box 2uy + <@@ 6s / 3s @@>, box 2s + <@@ 6us / 3us @@>, box 2us + <@@ 6 / 3 @@>, box 2 + <@@ 6u / 3u @@>, box 2u + <@@ 6L / 3L @@>, box 2L + <@@ 6uL / 3uL @@>, box 2uL + <@@ 6.0f / 3.0f @@>, box 2f + <@@ 6.0 / 3.0 @@>, box 2. + <@@ 6m / 3m @@>, box 2m + <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, box 1un + + <@@ 9y % 4y @@>, box 1y + <@@ 9uy % 4uy @@>, box 1uy + <@@ 9s % 4s @@>, box 1s + <@@ 9us % 4us @@>, box 1us + <@@ 9 % 4 @@>, box 1 + <@@ 9u % 4u @@>, box 1u + <@@ 9L % 4L @@>, box 1L + <@@ 9uL % 4uL @@>, box 1uL + <@@ 9.0f % 4.0f @@>, box 1f + <@@ 9.0 % 4.0 @@>, box 1. + <@@ 9m % 4m @@>, box 1m + <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, box 0n + <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, box 0un + + <@@ -(1y) @@>, box -1y + <@@ -(1s) @@>, box -1s + <@@ -(1) @@>, box -1 + <@@ -(1L) @@>, box -1L + <@@ -(1f) @@>, box -1f + <@@ -(1.) @@>, box -1. + <@@ -(1m) @@>, box -1m + <@@ -(LanguagePrimitives.GenericOne) @@>, box -1n + <@@ Checked.(~-) (1y) @@>, box -1y + <@@ Checked.(~-) (1s) @@>, box -1s + <@@ Checked.(~-) (1) @@>, box -1 + <@@ Checked.(~-) (1L) @@>, box -1L + <@@ Checked.(~-) (1f) @@>, box -1f + <@@ Checked.(~-) (1.) @@>, box -1. + <@@ Checked.(~-) (1m) @@>, box -1m + <@@ Checked.(~-) (LanguagePrimitives.GenericOne) @@>, box -1n + + <@@ 4f ** 3f @@>, box 64f + <@@ 4. ** 3. @@>, box 64. + + <@@ 1y <<< 3 @@>, box 8y + <@@ 1uy <<< 3 @@>, box 8uy + <@@ 1s <<< 3 @@>, box 8s + <@@ 1us <<< 3 @@>, box 8us + <@@ 1 <<< 3 @@>, box 8 + <@@ 1u <<< 3 @@>, box 8u + <@@ 1L <<< 3 @@>, box 8L + <@@ 1UL <<< 3 @@>, box 8UL + <@@ LanguagePrimitives.GenericOne <<< 3 @@>, box 8n + <@@ LanguagePrimitives.GenericOne <<< 3 @@>, box 8un + + <@@ 1y >>> 3 @@>, box 0y + <@@ 1uy >>> 3 @@>, box 0uy + <@@ 1s >>> 3 @@>, box 0s + <@@ 1us >>> 3 @@>, box 0us + <@@ 1 >>> 3 @@>, box 0 + <@@ 1u >>> 3 @@>, box 0u + <@@ 1L >>> 3 @@>, box 0L + <@@ 1UL >>> 3 @@>, box 0UL + <@@ LanguagePrimitives.GenericOne >>> 3 @@>, box 0n + <@@ LanguagePrimitives.GenericOne >>> 3 @@>, box 0un - <@@ 1y &&& 3y @@>, Some <@@ 1y @@> - <@@ 1uy &&& 3uy @@>, Some <@@ 1uy @@> - <@@ 1s &&& 3s @@>, Some <@@ 1s @@> - <@@ 1us &&& 3us @@>, Some <@@ 1us @@> - <@@ 1 &&& 3 @@>, Some <@@ 1 @@> - <@@ 1u &&& 3u @@>, Some <@@ 1u @@> - <@@ 1L &&& 3L @@>, Some <@@ 1L @@> - <@@ 1UL &&& 3UL @@>, Some <@@ 1UL @@> - <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, None - - <@@ 1y ||| 3y @@>, Some <@@ 3y @@> - <@@ 1uy ||| 3uy @@>, Some <@@ 3uy @@> - <@@ 1s ||| 3s @@>, Some <@@ 3s @@> - <@@ 1us ||| 3us @@>, Some <@@ 3us @@> - <@@ 1 ||| 3 @@>, Some <@@ 3 @@> - <@@ 1u ||| 3u @@>, Some <@@ 3u @@> - <@@ 1L ||| 3L @@>, Some <@@ 3L @@> - <@@ 1UL ||| 3UL @@>, Some <@@ 3UL @@> - <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, None - - <@@ 1y ^^^ 3y @@>, Some <@@ 2y @@> - <@@ 1uy ^^^ 3uy @@>, Some <@@ 2uy @@> - <@@ 1s ^^^ 3s @@>, Some <@@ 2s @@> - <@@ 1us ^^^ 3us @@>, Some <@@ 2us @@> - <@@ 1 ^^^ 3 @@>, Some <@@ 2 @@> - <@@ 1u ^^^ 3u @@>, Some <@@ 2u @@> - <@@ 1L ^^^ 3L @@>, Some <@@ 2L @@> - <@@ 1UL ^^^ 3UL @@>, Some <@@ 2UL @@> - <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, None - - <@@ ~~~3y @@>, Some <@@ -4y @@> - <@@ ~~~3uy @@>, Some <@@ 252uy @@> - <@@ ~~~3s @@>, Some <@@ -4s @@> - <@@ ~~~3us @@>, Some <@@ 65532us @@> - <@@ ~~~3 @@>, Some <@@ -4 @@> - <@@ ~~~3u @@>, Some <@@ 4294967292u @@> - <@@ ~~~3L @@>, Some <@@ -4L @@> - <@@ ~~~3UL @@>, Some <@@ 18446744073709551612UL @@> - <@@ ~~~LanguagePrimitives.GenericOne @@>, None - <@@ ~~~LanguagePrimitives.GenericOne @@>, None - - <@@ byte 3uy @@>, Some <@@ 3uy @@> - <@@ byte 3y @@>, Some <@@ 3uy @@> - <@@ byte 3s @@>, Some <@@ 3uy @@> - <@@ byte 3us @@>, Some <@@ 3uy @@> - <@@ byte 3 @@>, Some <@@ 3uy @@> - <@@ byte 3u @@>, Some <@@ 3uy @@> - <@@ byte 3L @@>, Some <@@ 3uy @@> - <@@ byte 3UL @@>, Some <@@ 3uy @@> - <@@ byte 3.0f @@>, Some <@@ 3uy @@> - <@@ byte 3.0 @@>, Some <@@ 3uy @@> - <@@ byte LanguagePrimitives.GenericOne @@>, None - <@@ byte LanguagePrimitives.GenericOne @@>, None - <@@ byte 3.0M @@>, Some <@@ 3uy @@> - <@@ byte "3" @@>, None - - <@@ sbyte 3uy @@>, Some <@@ 3y @@> - <@@ sbyte 3y @@>, Some <@@ 3y @@> - <@@ sbyte 3s @@>, Some <@@ 3y @@> - <@@ sbyte 3us @@>, Some <@@ 3y @@> - <@@ sbyte 3 @@>, Some <@@ 3y @@> - <@@ sbyte 3u @@>, Some <@@ 3y @@> - <@@ sbyte 3L @@>, Some <@@ 3y @@> - <@@ sbyte 3UL @@>, Some <@@ 3y @@> - <@@ sbyte 3.0f @@>, Some <@@ 3y @@> - <@@ sbyte 3.0 @@>, Some <@@ 3y @@> - <@@ sbyte LanguagePrimitives.GenericOne @@>, None - <@@ sbyte LanguagePrimitives.GenericOne @@>, None - <@@ sbyte 3.0M @@>, Some <@@ 3y @@> - <@@ sbyte "3" @@>, None - - <@@ int16 3uy @@>, Some <@@ 3s @@> - <@@ int16 3y @@>, Some <@@ 3s @@> - <@@ int16 3s @@>, Some <@@ 3s @@> - <@@ int16 3us @@>, Some <@@ 3s @@> - <@@ int16 3 @@>, Some <@@ 3s @@> - <@@ int16 3u @@>, Some <@@ 3s @@> - <@@ int16 3L @@>, Some <@@ 3s @@> - <@@ int16 3UL @@>, Some <@@ 3s @@> - <@@ int16 3.0f @@>, Some <@@ 3s @@> - <@@ int16 3.0 @@>, Some <@@ 3s @@> - <@@ int16 LanguagePrimitives.GenericOne @@>, None - <@@ int16 LanguagePrimitives.GenericOne @@>, None - <@@ int16 3.0M @@>, Some <@@ 3s @@> - <@@ int16 "3" @@>, None - - <@@ uint16 3uy @@>, Some <@@ 3us @@> - <@@ uint16 3y @@>, Some <@@ 3us @@> - <@@ uint16 3s @@>, Some <@@ 3us @@> - <@@ uint16 3us @@>, Some <@@ 3us @@> - <@@ uint16 3 @@>, Some <@@ 3us @@> - <@@ uint16 3u @@>, Some <@@ 3us @@> - <@@ uint16 3L @@>, Some <@@ 3us @@> - <@@ uint16 3UL @@>, Some <@@ 3us @@> - <@@ uint16 3.0f @@>, Some <@@ 3us @@> - <@@ uint16 3.0 @@>, Some <@@ 3us @@> - <@@ uint16 LanguagePrimitives.GenericOne @@>, None - <@@ uint16 LanguagePrimitives.GenericOne @@>, None - <@@ uint16 3.0M @@>, Some <@@ 3us @@> - <@@ uint16 "3" @@>, None - - <@@ int32 3uy @@>, Some <@@ 3 @@> - <@@ int32 3y @@>, Some <@@ 3 @@> - <@@ int32 3s @@>, Some <@@ 3 @@> - <@@ int32 3us @@>, Some <@@ 3 @@> - <@@ int32 3 @@>, Some <@@ 3 @@> - <@@ int32 3u @@>, Some <@@ 3 @@> - <@@ int32 3L @@>, Some <@@ 3 @@> - <@@ int32 3UL @@>, Some <@@ 3 @@> - <@@ int32 3.0f @@>, Some <@@ 3 @@> - <@@ int32 3.0 @@>, Some <@@ 3 @@> - <@@ int32 LanguagePrimitives.GenericOne @@>, None - <@@ int32 LanguagePrimitives.GenericOne @@>, None - <@@ int32 3.0M @@>, Some <@@ 3 @@> - <@@ int32 "3" @@>, None - - <@@ uint32 3uy @@>, Some <@@ 3u @@> - <@@ uint32 3y @@>, Some <@@ 3u @@> - <@@ uint32 3s @@>, Some <@@ 3u @@> - <@@ uint32 3us @@>, Some <@@ 3u @@> - <@@ uint32 3 @@>, Some <@@ 3u @@> - <@@ uint32 3u @@>, Some <@@ 3u @@> - <@@ uint32 3L @@>, Some <@@ 3u @@> - <@@ uint32 3UL @@>, Some <@@ 3u @@> - <@@ uint32 3.0f @@>, Some <@@ 3u @@> - <@@ uint32 3.0 @@>, Some <@@ 3u @@> - <@@ uint32 LanguagePrimitives.GenericOne @@>, None - <@@ uint32 LanguagePrimitives.GenericOne @@>, None - <@@ uint32 3.0M @@>, Some <@@ 3u @@> - <@@ uint32 "3" @@>, None - - <@@ int64 3uy @@>, Some <@@ 3L @@> - <@@ int64 3y @@>, Some <@@ 3L @@> - <@@ int64 3s @@>, Some <@@ 3L @@> - <@@ int64 3us @@>, Some <@@ 3L @@> - <@@ int64 3 @@>, Some <@@ 3L @@> - <@@ int64 3u @@>, Some <@@ 3L @@> - <@@ int64 3L @@>, Some <@@ 3L @@> - <@@ int64 3UL @@>, Some <@@ 3L @@> - <@@ int64 3.0f @@>, Some <@@ 3L @@> - <@@ int64 3.0 @@>, Some <@@ 3L @@> - <@@ int64 LanguagePrimitives.GenericOne @@>, None - <@@ int64 LanguagePrimitives.GenericOne @@>, None - <@@ int64 3.0M @@>, Some <@@ 3L @@> - <@@ int64 "3" @@>, None + <@@ 1y &&& 3y @@>, box 1y + <@@ 1uy &&& 3uy @@>, box 1uy + <@@ 1s &&& 3s @@>, box 1s + <@@ 1us &&& 3us @@>, box 1us + <@@ 1 &&& 3 @@>, box 1 + <@@ 1u &&& 3u @@>, box 1u + <@@ 1L &&& 3L @@>, box 1L + <@@ 1UL &&& 3UL @@>, box 1UL + <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, box 1un + + <@@ 1y ||| 3y @@>, box 3y + <@@ 1uy ||| 3uy @@>, box 3uy + <@@ 1s ||| 3s @@>, box 3s + <@@ 1us ||| 3us @@>, box 3us + <@@ 1 ||| 3 @@>, box 3 + <@@ 1u ||| 3u @@>, box 3u + <@@ 1L ||| 3L @@>, box 3L + <@@ 1UL ||| 3UL @@>, box 3UL + <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, box 1un + + <@@ 1y ^^^ 3y @@>, box 2y + <@@ 1uy ^^^ 3uy @@>, box 2uy + <@@ 1s ^^^ 3s @@>, box 2s + <@@ 1us ^^^ 3us @@>, box 2us + <@@ 1 ^^^ 3 @@>, box 2 + <@@ 1u ^^^ 3u @@>, box 2u + <@@ 1L ^^^ 3L @@>, box 2L + <@@ 1UL ^^^ 3UL @@>, box 2UL + <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, box 0n + <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, box 0un + + <@@ ~~~3y @@>, box -4y + <@@ ~~~3uy @@>, box 252uy + <@@ ~~~3s @@>, box -4s + <@@ ~~~3us @@>, box 65532us + <@@ ~~~3 @@>, box -4 + <@@ ~~~3u @@>, box 4294967292u + <@@ ~~~3L @@>, box -4L + <@@ ~~~3UL @@>, box 18446744073709551612UL + <@@ ~~~LanguagePrimitives.GenericOne @@>, box ~~~1n + <@@ ~~~LanguagePrimitives.GenericOne @@>, box ~~~1un + + <@@ byte 3uy @@>, box 3uy + <@@ byte 3y @@>, box 3uy + <@@ byte 3s @@>, box 3uy + <@@ byte 3us @@>, box 3uy + <@@ byte 3 @@>, box 3uy + <@@ byte 3u @@>, box 3uy + <@@ byte 3L @@>, box 3uy + <@@ byte 3UL @@>, box 3uy + <@@ byte 3.0f @@>, box 3uy + <@@ byte 3.0 @@>, box 3uy + <@@ byte LanguagePrimitives.GenericOne @@>, box 3uy + <@@ byte LanguagePrimitives.GenericOne @@>, box 3uy + <@@ byte 3.0M @@>, box 3uy + <@@ byte "3" @@>, box 3uy + + <@@ sbyte 3uy @@>, box 3y + <@@ sbyte 3y @@>, box 3y + <@@ sbyte 3s @@>, box 3y + <@@ sbyte 3us @@>, box 3y + <@@ sbyte 3 @@>, box 3y + <@@ sbyte 3u @@>, box 3y + <@@ sbyte 3L @@>, box 3y + <@@ sbyte 3UL @@>, box 3y + <@@ sbyte 3.0f @@>, box 3y + <@@ sbyte 3.0 @@>, box 3y + <@@ sbyte LanguagePrimitives.GenericOne @@>, box 3y + <@@ sbyte LanguagePrimitives.GenericOne @@>, box 3y + <@@ sbyte 3.0M @@>, box 3y + <@@ sbyte "3" @@>, box 3y + + <@@ int16 3uy @@>, box 3s + <@@ int16 3y @@>, box 3s + <@@ int16 3s @@>, box 3s + <@@ int16 3us @@>, box 3s + <@@ int16 3 @@>, box 3s + <@@ int16 3u @@>, box 3s + <@@ int16 3L @@>, box 3s + <@@ int16 3UL @@>, box 3s + <@@ int16 3.0f @@>, box 3s + <@@ int16 3.0 @@>, box 3s + <@@ int16 LanguagePrimitives.GenericOne @@>, box 3s + <@@ int16 LanguagePrimitives.GenericOne @@>, box 3s + <@@ int16 3.0M @@>, box 3s + <@@ int16 "3" @@>, box 3s + + <@@ uint16 3uy @@>, box 3us + <@@ uint16 3y @@>, box 3us + <@@ uint16 3s @@>, box 3us + <@@ uint16 3us @@>, box 3us + <@@ uint16 3 @@>, box 3us + <@@ uint16 3u @@>, box 3us + <@@ uint16 3L @@>, box 3us + <@@ uint16 3UL @@>, box 3us + <@@ uint16 3.0f @@>, box 3us + <@@ uint16 3.0 @@>, box 3us + <@@ uint16 LanguagePrimitives.GenericOne @@>, box 3us + <@@ uint16 LanguagePrimitives.GenericOne @@>, box 3us + <@@ uint16 3.0M @@>, box 3us + <@@ uint16 "3" @@>, box 3us + + <@@ int32 3uy @@>, box 3 + <@@ int32 3y @@>, box 3 + <@@ int32 3s @@>, box 3 + <@@ int32 3us @@>, box 3 + <@@ int32 3 @@>, box 3 + <@@ int32 3u @@>, box 3 + <@@ int32 3L @@>, box 3 + <@@ int32 3UL @@>, box 3 + <@@ int32 3.0f @@>, box 3 + <@@ int32 3.0 @@>, box 3 + <@@ int32 LanguagePrimitives.GenericOne @@>, box 3 + <@@ int32 LanguagePrimitives.GenericOne @@>, box 3 + <@@ int32 3.0M @@>, box 3 + <@@ int32 "3" @@>, box 3 + + <@@ uint32 3uy @@>, box 3u + <@@ uint32 3y @@>, box 3u + <@@ uint32 3s @@>, box 3u + <@@ uint32 3us @@>, box 3u + <@@ uint32 3 @@>, box 3u + <@@ uint32 3u @@>, box 3u + <@@ uint32 3L @@>, box 3u + <@@ uint32 3UL @@>, box 3u + <@@ uint32 3.0f @@>, box 3u + <@@ uint32 3.0 @@>, box 3u + <@@ uint32 LanguagePrimitives.GenericOne @@>, box 3u + <@@ uint32 LanguagePrimitives.GenericOne @@>, box 3u + <@@ uint32 3.0M @@>, box 3u + <@@ uint32 "3" @@>, box 3u + + <@@ int64 3uy @@>, box 3L + <@@ int64 3y @@>, box 3L + <@@ int64 3s @@>, box 3L + <@@ int64 3us @@>, box 3L + <@@ int64 3 @@>, box 3L + <@@ int64 3u @@>, box 3L + <@@ int64 3L @@>, box 3L + <@@ int64 3UL @@>, box 3L + <@@ int64 3.0f @@>, box 3L + <@@ int64 3.0 @@>, box 3L + <@@ int64 LanguagePrimitives.GenericOne @@>, box 3L + <@@ int64 LanguagePrimitives.GenericOne @@>, box 3L + <@@ int64 3.0M @@>, box 3L + <@@ int64 "3" @@>, box 3L - <@@ uint64 3uy @@>, Some <@@ 3UL @@> - <@@ uint64 3y @@>, Some <@@ 3UL @@> - <@@ uint64 3s @@>, Some <@@ 3UL @@> - <@@ uint64 3us @@>, Some <@@ 3UL @@> - <@@ uint64 3 @@>, Some <@@ 3UL @@> - <@@ uint64 3u @@>, Some <@@ 3UL @@> - <@@ uint64 3L @@>, Some <@@ 3UL @@> - <@@ uint64 3UL @@>, Some <@@ 3UL @@> - <@@ uint64 3.0f @@>, Some <@@ 3UL @@> - <@@ uint64 3.0 @@>, Some <@@ 3UL @@> - <@@ uint64 LanguagePrimitives.GenericOne @@>, None - <@@ uint64 LanguagePrimitives.GenericOne @@>, None - <@@ uint64 3.0M @@>, Some <@@ 3UL @@> - <@@ uint64 "3" @@>, None - - <@@ nativeint 3uy @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3y @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3s @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3us @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3 @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3u @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3L @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3UL @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3.0f @@>, Some <@@ nativeint 3 @@> - <@@ nativeint 3.0 @@>, Some <@@ nativeint 3 @@> - <@@ nativeint LanguagePrimitives.GenericOne @@>, None - <@@ nativeint LanguagePrimitives.GenericOne @@>, None - //<@@ nativeint 3.0M @@>, None - //<@@ nativeint "3" @@>, None - - <@@ unativeint 3uy @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3y @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3s @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3us @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3 @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3u @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3L @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3UL @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3.0f @@>, Some <@@ unativeint 3 @@> - <@@ unativeint 3.0 @@>, Some <@@ unativeint 3 @@> - <@@ unativeint LanguagePrimitives.GenericOne @@>, None - <@@ unativeint LanguagePrimitives.GenericOne @@>, None - //<@@ unativeint 3.0M @@>, Some <@@ unativeint 3 @@> - //<@@ unativeint "3" @@>, Some <@@ unativeint 3 @@> - - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0. @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0f @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0 @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0L @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ 0UL @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ nativeint 0 @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ unativeint 0 @@> - <@@ LanguagePrimitives.GenericZero @@>, Some <@@ '\000' @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1. @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1f @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1 @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1L @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ 1UL @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ nativeint 1 @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ unativeint 1 @@> - <@@ LanguagePrimitives.GenericOne @@>, Some <@@ '\001' @@> - <@@ List.sum [ 1; 2 ] @@>, Some <@@ 3 @@> - <@@ List.sum [ 1.0f; 2.0f ] @@>, Some <@@ 3f @@> - <@@ List.sum [ 1.0; 2.0 ] @@>, Some <@@ 3. @@> - <@@ List.sum [ 1.0M; 2.0M ] @@>, Some <@@ 3m @@> - <@@ List.average [ 1.0; 2.0 ] @@>, Some <@@ 1.5 @@> - <@@ List.average [ 1.0f; 2.0f ] @@>, Some <@@ 1.5f @@> - <@@ List.average [ 1.0M; 2.0M ] @@>, Some <@@ 1.5m @@> + <@@ uint64 3uy @@>, box 3UL + <@@ uint64 3y @@>, box 3UL + <@@ uint64 3s @@>, box 3UL + <@@ uint64 3us @@>, box 3UL + <@@ uint64 3 @@>, box 3UL + <@@ uint64 3u @@>, box 3UL + <@@ uint64 3L @@>, box 3UL + <@@ uint64 3UL @@>, box 3UL + <@@ uint64 3.0f @@>, box 3UL + <@@ uint64 3.0 @@>, box 3UL + <@@ uint64 LanguagePrimitives.GenericOne @@>, box 3UL + <@@ uint64 LanguagePrimitives.GenericOne @@>, box 3UL + <@@ uint64 3.0M @@>, box 3UL + <@@ uint64 "3" @@>, box 3UL + + <@@ nativeint 3uy @@>, box 3n + <@@ nativeint 3y @@>, box 3n + <@@ nativeint 3s @@>, box 3n + <@@ nativeint 3us @@>, box 3n + <@@ nativeint 3 @@>, box 3n + <@@ nativeint 3u @@>, box 3n + <@@ nativeint 3L @@>, box 3n + <@@ nativeint 3UL @@>, box 3n + <@@ nativeint 3.0f @@>, box 3n + <@@ nativeint 3.0 @@>, box 3n + <@@ nativeint LanguagePrimitives.GenericOne @@>, box 3n + <@@ nativeint LanguagePrimitives.GenericOne @@>, box 3n + <@@ nativeint 3.0M @@>, box 3n + <@@ nativeint "3" @@>, box 3n + + <@@ unativeint 3uy @@>, box 3un + <@@ unativeint 3y @@>, box 3un + <@@ unativeint 3s @@>, box 3un + <@@ unativeint 3us @@>, box 3un + <@@ unativeint 3 @@>, box 3un + <@@ unativeint 3u @@>, box 3un + <@@ unativeint 3L @@>, box 3un + <@@ unativeint 3UL @@>, box 3un + <@@ unativeint 3.0f @@>, box 3un + <@@ unativeint 3.0 @@>, box 3un + <@@ unativeint LanguagePrimitives.GenericOne @@>, box 3un + <@@ unativeint LanguagePrimitives.GenericOne @@>, box 3un + <@@ unativeint 3.0M @@>, box 3un + <@@ unativeint "3" @@>, box 3un + + <@@ float32 3uy @@>, box 3f + <@@ float32 3y @@>, box 3f + <@@ float32 3s @@>, box 3f + <@@ float32 3us @@>, box 3f + <@@ float32 3 @@>, box 3f + <@@ float32 3u @@>, box 3f + <@@ float32 3L @@>, box 3f + <@@ float32 3UL @@>, box 3f + <@@ float32 3.0f @@>, box 3f + <@@ float32 3.0 @@>, box 3f + <@@ float32 LanguagePrimitives.GenericOne @@>, box 3f + <@@ float32 LanguagePrimitives.GenericOne @@>, box 3f + <@@ float32 3.0M @@>, box 3f + <@@ float32 "3" @@>, box 3f + + <@@ float 3uy @@>, box 3. + <@@ float 3y @@>, box 3. + <@@ float 3s @@>, box 3. + <@@ float 3us @@>, box 3. + <@@ float 3 @@>, box 3. + <@@ float 3u @@>, box 3. + <@@ float 3L @@>, box 3. + <@@ float 3UL @@>, box 3. + <@@ float 3.0f @@>, box 3. + <@@ float 3.0 @@>, box 3. + <@@ float LanguagePrimitives.GenericOne @@>, box 3. + <@@ float LanguagePrimitives.GenericOne @@>, box 3. + <@@ float 3.0M @@>, box 3. + <@@ float "3" @@>, box 3. + + <@@ decimal 3uy @@>, box 3m + <@@ decimal 3y @@>, box 3m + <@@ decimal 3s @@>, box 3m + <@@ decimal 3us @@>, box 3m + <@@ decimal 3 @@>, box 3m + <@@ decimal 3u @@>, box 3m + <@@ decimal 3L @@>, box 3m + <@@ decimal 3UL @@>, box 3m + <@@ decimal 3.0f @@>, box 3m + <@@ decimal 3.0 @@>, box 3m + <@@ decimal LanguagePrimitives.GenericOne @@>, box 3m + <@@ decimal LanguagePrimitives.GenericOne @@>, box 3m + <@@ decimal 3.0M @@>, box 3m + <@@ decimal "3" @@>, box 3m + + <@@ LanguagePrimitives.GenericZero @@>, box 0. + <@@ LanguagePrimitives.GenericZero @@>, box 0f + <@@ LanguagePrimitives.GenericZero @@>, box 0 + <@@ LanguagePrimitives.GenericZero @@>, box 0L + <@@ LanguagePrimitives.GenericZero @@>, box 0UL + <@@ LanguagePrimitives.GenericZero @@>, box 0n + <@@ LanguagePrimitives.GenericZero @@>, box 0un + <@@ LanguagePrimitives.GenericZero @@>, box '\000' + <@@ LanguagePrimitives.GenericOne @@>, box 1. + <@@ LanguagePrimitives.GenericOne @@>, box 1f + <@@ LanguagePrimitives.GenericOne @@>, box 1 + <@@ LanguagePrimitives.GenericOne @@>, box 1L + <@@ LanguagePrimitives.GenericOne @@>, box 1UL + <@@ LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne @@>, box 1un + <@@ LanguagePrimitives.GenericOne @@>, box '\001' + <@@ List.sum [ 1; 2 ] @@>, box 3 + <@@ List.sum [ 1.0f; 2.0f ] @@>, box 3f + <@@ List.sum [ 1.0; 2.0 ] @@>, box 3. + <@@ List.sum [ 1.0M; 2.0M ] @@>, box 3m + <@@ List.average [ 1.0; 2.0 ] @@>, box 1.5 + <@@ List.average [ 1.0f; 2.0f ] @@>, box 1.5f + <@@ List.average [ 1.0M; 2.0M ] @@>, box 1.5m - <@@ Nullable<_> 1y ?+ 4y @@>, Some <@@ Nullable<_> 5y @@> - <@@ Nullable<_> 1uy ?+ 4uy @@>, Some <@@ Nullable<_> 5uy @@> - <@@ Nullable<_> 1s ?+ 4s @@>, Some <@@ Nullable<_> 5s @@> - <@@ Nullable<_> 1us ?+ 4us @@>, Some <@@ Nullable<_> 5us @@> - <@@ Nullable<_> 1 ?+ 4 @@>, Some <@@ Nullable<_> 5 @@> - <@@ Nullable<_> 1u ?+ 4u @@>, Some <@@ Nullable<_> 5u @@> - <@@ Nullable<_> 1L ?+ 4L @@>, Some <@@ Nullable<_> 5L @@> - <@@ Nullable<_> 1uL ?+ 4uL @@>, Some <@@ Nullable<_> 5uL @@> - <@@ Nullable<_> 1.0f ?+ 4.0f @@>, Some <@@ Nullable<_> 5f @@> - <@@ Nullable<_> 1.0 ?+ 4.0 @@>, Some <@@ Nullable<_> 5. @@> - <@@ Nullable<_> 1m ?+ 4m @@>, Some <@@ Nullable<_> 5m @@> - <@@ Nullable<_> '1' ?+ '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, None - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> 1y ?+ 4y @@>, box <| Nullable<_> 5y + <@@ Nullable<_> 1uy ?+ 4uy @@>, box <| Nullable<_> 5uy + <@@ Nullable<_> 1s ?+ 4s @@>, box <| Nullable<_> 5s + <@@ Nullable<_> 1us ?+ 4us @@>, box <| Nullable<_> 5us + <@@ Nullable<_> 1 ?+ 4 @@>, box <| Nullable<_> 5 + <@@ Nullable<_> 1u ?+ 4u @@>, box <| Nullable<_> 5u + <@@ Nullable<_> 1L ?+ 4L @@>, box <| Nullable<_> 5L + <@@ Nullable<_> 1uL ?+ 4uL @@>, box <| Nullable<_> 5uL + <@@ Nullable<_> 1.0f ?+ 4.0f @@>, box <| Nullable<_> 5f + <@@ Nullable<_> 1.0 ?+ 4.0 @@>, box <| Nullable<_> 5. + <@@ Nullable<_> 1m ?+ 4m @@>, box <| Nullable<_> 5m + <@@ Nullable<_> '1' ?+ '\004' @@>, box <| Nullable<_> '5' + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2un - <@@ 1y +? Nullable<_> 4y @@>, Some <@@ Nullable<_> 5y @@> - <@@ 1uy +? Nullable<_> 4uy @@>, Some <@@ Nullable<_> 5uy @@> - <@@ 1s +? Nullable<_> 4s @@>, Some <@@ Nullable<_> 5s @@> - <@@ 1us +? Nullable<_> 4us @@>, Some <@@ Nullable<_> 5us @@> - <@@ 1 +? Nullable<_> 4 @@>, Some <@@ Nullable<_> 5 @@> - <@@ 1u +? Nullable<_> 4u @@>, Some <@@ Nullable<_> 5u @@> - <@@ 1L +? Nullable<_> 4L @@>, Some <@@ Nullable<_> 5L @@> - <@@ 1uL +? Nullable<_> 4uL @@>, Some <@@ Nullable<_> 5uL @@> - <@@ 1.0f +? Nullable<_> 4.0f @@>, Some <@@ Nullable<_> 5f @@> - <@@ 1.0 +? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> - <@@ 1m +? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> - <@@ '1' +? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ 1y +? Nullable<_> 4y @@>, box <| Nullable<_> 5y + <@@ 1uy +? Nullable<_> 4uy @@>, box <| Nullable<_> 5uy + <@@ 1s +? Nullable<_> 4s @@>, box <| Nullable<_> 5s + <@@ 1us +? Nullable<_> 4us @@>, box <| Nullable<_> 5us + <@@ 1 +? Nullable<_> 4 @@>, box <| Nullable<_> 5 + <@@ 1u +? Nullable<_> 4u @@>, box <| Nullable<_> 5u + <@@ 1L +? Nullable<_> 4L @@>, box <| Nullable<_> 5L + <@@ 1uL +? Nullable<_> 4uL @@>, box <| Nullable<_> 5uL + <@@ 1.0f +? Nullable<_> 4.0f @@>, box <| Nullable<_> 5f + <@@ 1.0 +? Nullable<_> 4.0 @@>, box <| Nullable<_> 5. + <@@ 1m +? Nullable<_> 4m @@>, box <| Nullable<_> 5m + <@@ '1' +? Nullable<_> '\004' @@>, box <| Nullable<_> '5' + <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2n + <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2un - <@@ Nullable<_> 1y ?+? Nullable<_> 4y @@>, Some <@@ Nullable<_> 5y @@> - <@@ Nullable<_> 1uy ?+? Nullable<_> 4uy @@>, Some <@@ Nullable<_> 5uy @@> - <@@ Nullable<_> 1s ?+? Nullable<_> 4s @@>, Some <@@ Nullable<_> 5s @@> - <@@ Nullable<_> 1us ?+? Nullable<_> 4us @@>, Some <@@ Nullable<_> 5us @@> - <@@ Nullable<_> 1 ?+? Nullable<_> 4 @@>, Some <@@ Nullable<_> 5 @@> - <@@ Nullable<_> 1u ?+? Nullable<_> 4u @@>, Some <@@ Nullable<_> 5u @@> - <@@ Nullable<_> 1L ?+? Nullable<_> 4L @@>, Some <@@ Nullable<_> 5L @@> - <@@ Nullable<_> 1uL ?+? Nullable<_> 4uL @@>, Some <@@ Nullable<_> 5uL @@> - <@@ Nullable<_> 1.0f ?+? Nullable<_> 4.0f @@>, Some <@@ Nullable<_> 5f @@> - <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, Some <@@ Nullable<_> 5. @@> - <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, Some <@@ Nullable<_> 5m @@> - <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, Some <@@ Nullable<_> '5' @@> - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> 1y ?+? Nullable<_> 4y @@>, box <| Nullable<_> 5y + <@@ Nullable<_> 1uy ?+? Nullable<_> 4uy @@>, box <| Nullable<_> 5uy + <@@ Nullable<_> 1s ?+? Nullable<_> 4s @@>, box <| Nullable<_> 5s + <@@ Nullable<_> 1us ?+? Nullable<_> 4us @@>, box <| Nullable<_> 5us + <@@ Nullable<_> 1 ?+? Nullable<_> 4 @@>, box <| Nullable<_> 5 + <@@ Nullable<_> 1u ?+? Nullable<_> 4u @@>, box <| Nullable<_> 5u + <@@ Nullable<_> 1L ?+? Nullable<_> 4L @@>, box <| Nullable<_> 5L + <@@ Nullable<_> 1uL ?+? Nullable<_> 4uL @@>, box <| Nullable<_> 5uL + <@@ Nullable<_> 1.0f ?+? Nullable<_> 4.0f @@>, box <| Nullable<_> 5f + <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, box <| Nullable<_> 5. + <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, box <| Nullable<_> 5m + <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, box <| Nullable<_> '5' + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2un - <@@ Nullable<_> 1y ?= 1y @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1uy ?= 1uy @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1s ?= 1s @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1us ?= 1us @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1 ?= 1 @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1u ?= 1u @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1L ?= 1L @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1uL ?= 1uL @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1.0f ?= 1.0f @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1.0 ?= 1.0 @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1m ?= 1m @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> '1' ?= '1' @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, None - <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> 1y ?= 1y @@>, box <| Nullable<_> true + <@@ Nullable<_> 1uy ?= 1uy @@>, box <| Nullable<_> true + <@@ Nullable<_> 1s ?= 1s @@>, box <| Nullable<_> true + <@@ Nullable<_> 1us ?= 1us @@>, box <| Nullable<_> true + <@@ Nullable<_> 1 ?= 1 @@>, box <| Nullable<_> true + <@@ Nullable<_> 1u ?= 1u @@>, box <| Nullable<_> true + <@@ Nullable<_> 1L ?= 1L @@>, box <| Nullable<_> true + <@@ Nullable<_> 1uL ?= 1uL @@>, box <| Nullable<_> true + <@@ Nullable<_> 1.0f ?= 1.0f @@>, box <| Nullable<_> true + <@@ Nullable<_> 1.0 ?= 1.0 @@>, box <| Nullable<_> true + <@@ Nullable<_> 1m ?= 1m @@>, box <| Nullable<_> true + <@@ Nullable<_> '1' ?= '1' @@>, box <| Nullable<_> true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true - <@@ 1y =? Nullable<_> 1y @@>, Some <@@ Nullable<_> true @@> - <@@ 1uy =? Nullable<_> 1uy @@>, Some <@@ Nullable<_> true @@> - <@@ 1s =? Nullable<_> 1s @@>, Some <@@ Nullable<_> true @@> - <@@ 1us =? Nullable<_> 1us @@>, Some <@@ Nullable<_> true @@> - <@@ 1 =? Nullable<_> 1 @@>, Some <@@ Nullable<_> true @@> - <@@ 1u =? Nullable<_> 1u @@>, Some <@@ Nullable<_> true @@> - <@@ 1L =? Nullable<_> 1L @@>, Some <@@ Nullable<_> true @@> - <@@ 1uL =? Nullable<_> 1uL @@>, Some <@@ Nullable<_> true @@> - <@@ 1.0f =? Nullable<_> 1.0f @@>, Some <@@ Nullable<_> true @@> - <@@ 1.0 =? Nullable<_> 1.0 @@>, Some <@@ Nullable<_> true @@> - <@@ 1m =? Nullable<_> 1m @@>, Some <@@ Nullable<_> true @@> - <@@ '1' =? Nullable<_> '1' @@>, Some <@@ Nullable<_> true @@> - <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, None - <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ 1y =? Nullable<_> 1y @@>, box <| Nullable<_> true + <@@ 1uy =? Nullable<_> 1uy @@>, box <| Nullable<_> true + <@@ 1s =? Nullable<_> 1s @@>, box <| Nullable<_> true + <@@ 1us =? Nullable<_> 1us @@>, box <| Nullable<_> true + <@@ 1 =? Nullable<_> 1 @@>, box <| Nullable<_> true + <@@ 1u =? Nullable<_> 1u @@>, box <| Nullable<_> true + <@@ 1L =? Nullable<_> 1L @@>, box <| Nullable<_> true + <@@ 1uL =? Nullable<_> 1uL @@>, box <| Nullable<_> true + <@@ 1.0f =? Nullable<_> 1.0f @@>, box <| Nullable<_> true + <@@ 1.0 =? Nullable<_> 1.0 @@>, box <| Nullable<_> true + <@@ 1m =? Nullable<_> 1m @@>, box <| Nullable<_> true + <@@ '1' =? Nullable<_> '1' @@>, box <| Nullable<_> true + <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true + <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true - <@@ Nullable<_> 1y ?=? Nullable<_> 1y @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1uy ?=? Nullable<_> 1uy @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1s ?=? Nullable<_> 1s @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1us ?=? Nullable<_> 1us @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1 ?=? Nullable<_> 1 @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1u ?=? Nullable<_> 1u @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1L ?=? Nullable<_> 1L @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1uL ?=? Nullable<_> 1uL @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1.0f ?=? Nullable<_> 1.0f @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, Some <@@ Nullable<_> true @@> - <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, None - <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, None + <@@ Nullable<_> 1y ?=? Nullable<_> 1y @@>, box <| Nullable<_> true + <@@ Nullable<_> 1uy ?=? Nullable<_> 1uy @@>, box <| Nullable<_> true + <@@ Nullable<_> 1s ?=? Nullable<_> 1s @@>, box <| Nullable<_> true + <@@ Nullable<_> 1us ?=? Nullable<_> 1us @@>, box <| Nullable<_> true + <@@ Nullable<_> 1 ?=? Nullable<_> 1 @@>, box <| Nullable<_> true + <@@ Nullable<_> 1u ?=? Nullable<_> 1u @@>, box <| Nullable<_> true + <@@ Nullable<_> 1L ?=? Nullable<_> 1L @@>, box <| Nullable<_> true + <@@ Nullable<_> 1uL ?=? Nullable<_> 1uL @@>, box <| Nullable<_> true + <@@ Nullable<_> 1.0f ?=? Nullable<_> 1.0f @@>, box <| Nullable<_> true + <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, box <| Nullable<_> true + <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, box <| Nullable<_> true + <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, box <| Nullable<_> true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true ] - tests |> List.map (fun (test, canEval) -> - match canEval with - | Some eval -> - printfn "--> checking we can evaluate %A" test + tests |> List.map (fun (test, eval) -> + begin + printfn "--> Checking we can evaluate %A" test let res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test - let b = res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation eval - if b then printfn "<-- Success, It is %A which is equal to %A" res eval - else printfn "<-- FAIL, It is %A which is not equal to %A" res eval + let b = res = eval + if b then printfn "--- Success, it is %A which is equal to %A" res eval + else printfn "!!! FAILURE, it is %A which is not equal to %A" res eval b - | None -> - printfn "--><-- skipping evaluation of %A because LinqExpressionConverter can't handle it" test - true + end && match test with | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> @@ -3887,8 +3929,11 @@ module WitnessTests = (printfn "args..."; true) && (match args with [ _; _ ] -> true | _ -> false) *) - true - | _ -> false) |> List.forall id) // Don't short circuit on a failed test + (printfn "<-- Successfully checked with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) + || (printfn "<-- FAILURE, failed after matching with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) + | _ -> + printfn " List.forall id) // Don't short circuit on a failed test module MoreWitnessTests = From 63fa1a72cf101543ef55a268e05245c6c0df56e9 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Tue, 22 Jun 2021 19:25:09 +0800 Subject: [PATCH 30/78] How did tabs get in here? --- src/fsharp/FSharp.Core/Linq.fs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 1da5a2ac5d0..7b2d9cf0fab 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -448,16 +448,16 @@ module LeafExpressionConverter = | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) - | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) - | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) - | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) - | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x + | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) + | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) + | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) + | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) - | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) - | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) - | CheckedConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env true x - + | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) + | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) + | CheckedConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env true x + | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> Expression.ArrayIndex(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr From 9d819c0899782d31befb135e91910359110f93c7 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Tue, 22 Jun 2021 21:50:38 +0800 Subject: [PATCH 31/78] Who doesn't like more testing? --- src/fsharp/FSharp.Core/Linq.fs | 2 +- tests/fsharp/core/quotes/test.fsx | 850 +++++++++++++++++++++++++----- 2 files changed, 730 insertions(+), 122 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 7b2d9cf0fab..b8f72a4fc6e 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -396,7 +396,7 @@ module LeafExpressionConverter = | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual | NullableLessNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan - | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual + | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) // Detect the F# quotation encoding of decimal literals | MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) -> diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index c7691dd4b39..f36f2c4bf01 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3258,10 +3258,11 @@ module TestMatchBang = #if LANGVERSION_PREVIEW module WitnessTests = open FSharp.Data.UnitSystems.SI.UnitSymbols + open FSharp.Linq open FSharp.Linq.NullableOperators test "check CallWithWitness" - (<@ 1 + 1 @> + (<@ 1 + 1 @> |> function | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> minfo1.Name = "op_Addition" && @@ -3382,7 +3383,7 @@ module WitnessTests = false | _ -> false) - test "check CallWithWitnesses all operators)" + test "check CallWithWitnesses all operators" (let tests = [ <@@ sin 1.0 @@>, box 0x3FEAED548F090CEELF // Around 0.841470984807897 <@@ sin 1.0f @@>, box 0x3F576AA4lf // = 0.841471f @@ -3506,6 +3507,20 @@ module WitnessTests = <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, box 0n <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, box 0un + <@@ +(1y) @@>, box 1y + <@@ +(1uy) @@>, box 1uy + <@@ +(1s) @@>, box 1s + <@@ +(1us) @@>, box 1us + <@@ +(1) @@>, box 1 + <@@ +(1u) @@>, box 1u + <@@ +(1L) @@>, box 1L + <@@ +(1uL) @@>, box 1uL + <@@ +(1f) @@>, box 1f + <@@ +(1.) @@>, box 1. + <@@ +(1m) @@>, box 1m + <@@ +(LanguagePrimitives.GenericOne) @@>, box 1n + <@@ +(LanguagePrimitives.GenericOne) @@>, box 1un + <@@ -(1y) @@>, box -1y <@@ -(1s) @@>, box -1s <@@ -(1) @@>, box -1 @@ -3600,12 +3615,58 @@ module WitnessTests = <@@ byte 3u @@>, box 3uy <@@ byte 3L @@>, box 3uy <@@ byte 3UL @@>, box 3uy + <@@ byte '\003' @@>, box 3uy <@@ byte 3.0f @@>, box 3uy <@@ byte 3.0 @@>, box 3uy - <@@ byte LanguagePrimitives.GenericOne @@>, box 3uy - <@@ byte LanguagePrimitives.GenericOne @@>, box 3uy + <@@ byte LanguagePrimitives.GenericOne @@>, box 1uy + <@@ byte LanguagePrimitives.GenericOne @@>, box 1uy <@@ byte 3.0M @@>, box 3uy <@@ byte "3" @@>, box 3uy + <@@ uint8 3uy @@>, box 3uy + <@@ uint8 3y @@>, box 3uy + <@@ uint8 3s @@>, box 3uy + <@@ uint8 3us @@>, box 3uy + <@@ uint8 3 @@>, box 3uy + <@@ uint8 3u @@>, box 3uy + <@@ uint8 3L @@>, box 3uy + <@@ uint8 3UL @@>, box 3uy + <@@ uint8 '\003' @@>, box 3uy + <@@ uint8 3.0f @@>, box 3uy + <@@ uint8 3.0 @@>, box 3uy + <@@ uint8 LanguagePrimitives.GenericOne @@>, box 1uy + <@@ uint8 LanguagePrimitives.GenericOne @@>, box 1uy + <@@ uint8 3.0M @@>, box 3uy + <@@ uint8 "3" @@>, box 3uy + <@@ Checked.byte 3uy @@>, box 3uy + <@@ Checked.byte 3y @@>, box 3uy + <@@ Checked.byte 3s @@>, box 3uy + <@@ Checked.byte 3us @@>, box 3uy + <@@ Checked.byte 3 @@>, box 3uy + <@@ Checked.byte 3u @@>, box 3uy + <@@ Checked.byte 3L @@>, box 3uy + <@@ Checked.byte 3UL @@>, box 3uy + <@@ Checked.byte '\003' @@>, box 3uy + <@@ Checked.byte 3.0f @@>, box 3uy + <@@ Checked.byte 3.0 @@>, box 3uy + <@@ Checked.byte LanguagePrimitives.GenericOne @@>, box 1uy + <@@ Checked.byte LanguagePrimitives.GenericOne @@>, box 1uy + <@@ Checked.byte 3.0M @@>, box 3uy + <@@ Checked.byte "3" @@>, box 3uy + <@@ Checked.uint8 3uy @@>, box 3uy + <@@ Checked.uint8 3y @@>, box 3uy + <@@ Checked.uint8 3s @@>, box 3uy + <@@ Checked.uint8 3us @@>, box 3uy + <@@ Checked.uint8 3 @@>, box 3uy + <@@ Checked.uint8 3u @@>, box 3uy + <@@ Checked.uint8 3L @@>, box 3uy + <@@ Checked.uint8 3UL @@>, box 3uy + <@@ Checked.uint8 '\003' @@>, box 3uy + <@@ Checked.uint8 3.0f @@>, box 3uy + <@@ Checked.uint8 3.0 @@>, box 3uy + <@@ Checked.uint8 LanguagePrimitives.GenericOne @@>, box 1uy + <@@ Checked.uint8 LanguagePrimitives.GenericOne @@>, box 1uy + <@@ Checked.uint8 3.0M @@>, box 3uy + <@@ Checked.uint8 "3" @@>, box 3uy <@@ sbyte 3uy @@>, box 3y <@@ sbyte 3y @@>, box 3y @@ -3615,12 +3676,58 @@ module WitnessTests = <@@ sbyte 3u @@>, box 3y <@@ sbyte 3L @@>, box 3y <@@ sbyte 3UL @@>, box 3y + <@@ sbyte '\003' @@>, box 3y <@@ sbyte 3.0f @@>, box 3y <@@ sbyte 3.0 @@>, box 3y - <@@ sbyte LanguagePrimitives.GenericOne @@>, box 3y - <@@ sbyte LanguagePrimitives.GenericOne @@>, box 3y + <@@ sbyte LanguagePrimitives.GenericOne @@>, box 1y + <@@ sbyte LanguagePrimitives.GenericOne @@>, box 1y <@@ sbyte 3.0M @@>, box 3y <@@ sbyte "3" @@>, box 3y + <@@ int8 3uy @@>, box 3y + <@@ int8 3y @@>, box 3y + <@@ int8 3s @@>, box 3y + <@@ int8 3us @@>, box 3y + <@@ int8 3 @@>, box 3y + <@@ int8 3u @@>, box 3y + <@@ int8 3L @@>, box 3y + <@@ int8 3UL @@>, box 3y + <@@ int8 '\003' @@>, box 3y + <@@ int8 3.0f @@>, box 3y + <@@ int8 3.0 @@>, box 3y + <@@ int8 LanguagePrimitives.GenericOne @@>, box 1y + <@@ int8 LanguagePrimitives.GenericOne @@>, box 1y + <@@ int8 3.0M @@>, box 3y + <@@ int8 "3" @@>, box 3y + <@@ Checked.sbyte 3uy @@>, box 3y + <@@ Checked.sbyte 3y @@>, box 3y + <@@ Checked.sbyte 3s @@>, box 3y + <@@ Checked.sbyte 3us @@>, box 3y + <@@ Checked.sbyte 3 @@>, box 3y + <@@ Checked.sbyte 3u @@>, box 3y + <@@ Checked.sbyte 3L @@>, box 3y + <@@ Checked.sbyte 3UL @@>, box 3y + <@@ Checked.sbyte '\003' @@>, box 3y + <@@ Checked.sbyte 3.0f @@>, box 3y + <@@ Checked.sbyte 3.0 @@>, box 3y + <@@ Checked.sbyte LanguagePrimitives.GenericOne @@>, box 1y + <@@ Checked.sbyte LanguagePrimitives.GenericOne @@>, box 1y + <@@ Checked.sbyte 3.0M @@>, box 3y + <@@ Checked.sbyte "3" @@>, box 3y + <@@ Checked.int8 3uy @@>, box 3y + <@@ Checked.int8 3y @@>, box 3y + <@@ Checked.int8 3s @@>, box 3y + <@@ Checked.int8 3us @@>, box 3y + <@@ Checked.int8 3 @@>, box 3y + <@@ Checked.int8 3u @@>, box 3y + <@@ Checked.int8 3L @@>, box 3y + <@@ Checked.int8 3UL @@>, box 3y + <@@ Checked.int8 '\003' @@>, box 3y + <@@ Checked.int8 3.0f @@>, box 3y + <@@ Checked.int8 3.0 @@>, box 3y + <@@ Checked.int8 LanguagePrimitives.GenericOne @@>, box 1y + <@@ Checked.int8 LanguagePrimitives.GenericOne @@>, box 1y + <@@ Checked.int8 3.0M @@>, box 3y + <@@ Checked.int8 "3" @@>, box 3y <@@ int16 3uy @@>, box 3s <@@ int16 3y @@>, box 3s @@ -3630,12 +3737,28 @@ module WitnessTests = <@@ int16 3u @@>, box 3s <@@ int16 3L @@>, box 3s <@@ int16 3UL @@>, box 3s + <@@ int16 '\003' @@>, box 3s <@@ int16 3.0f @@>, box 3s <@@ int16 3.0 @@>, box 3s - <@@ int16 LanguagePrimitives.GenericOne @@>, box 3s - <@@ int16 LanguagePrimitives.GenericOne @@>, box 3s + <@@ int16 LanguagePrimitives.GenericOne @@>, box 1s + <@@ int16 LanguagePrimitives.GenericOne @@>, box 1s <@@ int16 3.0M @@>, box 3s <@@ int16 "3" @@>, box 3s + <@@ Checked.int16 3uy @@>, box 3s + <@@ Checked.int16 3y @@>, box 3s + <@@ Checked.int16 3s @@>, box 3s + <@@ Checked.int16 3us @@>, box 3s + <@@ Checked.int16 3 @@>, box 3s + <@@ Checked.int16 3u @@>, box 3s + <@@ Checked.int16 3L @@>, box 3s + <@@ Checked.int16 3UL @@>, box 3s + <@@ Checked.int16 '\003' @@>, box 3s + <@@ Checked.int16 3.0f @@>, box 3s + <@@ Checked.int16 3.0 @@>, box 3s + <@@ Checked.int16 LanguagePrimitives.GenericOne @@>, box 1s + <@@ Checked.int16 LanguagePrimitives.GenericOne @@>, box 1s + <@@ Checked.int16 3.0M @@>, box 3s + <@@ Checked.int16 "3" @@>, box 3s <@@ uint16 3uy @@>, box 3us <@@ uint16 3y @@>, box 3us @@ -3645,13 +3768,44 @@ module WitnessTests = <@@ uint16 3u @@>, box 3us <@@ uint16 3L @@>, box 3us <@@ uint16 3UL @@>, box 3us + <@@ uint16 '\003' @@>, box 3us <@@ uint16 3.0f @@>, box 3us <@@ uint16 3.0 @@>, box 3us - <@@ uint16 LanguagePrimitives.GenericOne @@>, box 3us - <@@ uint16 LanguagePrimitives.GenericOne @@>, box 3us + <@@ uint16 LanguagePrimitives.GenericOne @@>, box 1us + <@@ uint16 LanguagePrimitives.GenericOne @@>, box 1us <@@ uint16 3.0M @@>, box 3us <@@ uint16 "3" @@>, box 3us - + <@@ Checked.uint16 3uy @@>, box 3us + <@@ Checked.uint16 3y @@>, box 3us + <@@ Checked.uint16 3s @@>, box 3us + <@@ Checked.uint16 3us @@>, box 3us + <@@ Checked.uint16 3 @@>, box 3us + <@@ Checked.uint16 3u @@>, box 3us + <@@ Checked.uint16 3L @@>, box 3us + <@@ Checked.uint16 3UL @@>, box 3us + <@@ Checked.uint16 '\003' @@>, box 3us + <@@ Checked.uint16 3.0f @@>, box 3us + <@@ Checked.uint16 3.0 @@>, box 3us + <@@ Checked.uint16 LanguagePrimitives.GenericOne @@>, box 1us + <@@ Checked.uint16 LanguagePrimitives.GenericOne @@>, box 1us + <@@ Checked.uint16 3.0M @@>, box 3us + <@@ Checked.uint16 "3" @@>, box 3us + + <@@ int 3uy @@>, box 3 + <@@ int 3y @@>, box 3 + <@@ int 3s @@>, box 3 + <@@ int 3us @@>, box 3 + <@@ int 3 @@>, box 3 + <@@ int 3u @@>, box 3 + <@@ int 3L @@>, box 3 + <@@ int 3UL @@>, box 3 + <@@ int '\003' @@>, box 3 + <@@ int 3.0f @@>, box 3 + <@@ int 3.0 @@>, box 3 + <@@ int LanguagePrimitives.GenericOne @@>, box 1 + <@@ int LanguagePrimitives.GenericOne @@>, box 1 + <@@ int 3.0M @@>, box 3 + <@@ int "3" @@>, box 3 <@@ int32 3uy @@>, box 3 <@@ int32 3y @@>, box 3 <@@ int32 3s @@>, box 3 @@ -3660,13 +3814,59 @@ module WitnessTests = <@@ int32 3u @@>, box 3 <@@ int32 3L @@>, box 3 <@@ int32 3UL @@>, box 3 + <@@ int32 '\003' @@>, box 3 <@@ int32 3.0f @@>, box 3 <@@ int32 3.0 @@>, box 3 - <@@ int32 LanguagePrimitives.GenericOne @@>, box 3 - <@@ int32 LanguagePrimitives.GenericOne @@>, box 3 + <@@ int32 LanguagePrimitives.GenericOne @@>, box 1 + <@@ int32 LanguagePrimitives.GenericOne @@>, box 1 <@@ int32 3.0M @@>, box 3 <@@ int32 "3" @@>, box 3 - + <@@ Checked.int 3uy @@>, box 3 + <@@ Checked.int 3y @@>, box 3 + <@@ Checked.int 3s @@>, box 3 + <@@ Checked.int 3us @@>, box 3 + <@@ Checked.int 3 @@>, box 3 + <@@ Checked.int 3u @@>, box 3 + <@@ Checked.int 3L @@>, box 3 + <@@ Checked.int 3UL @@>, box 3 + <@@ Checked.int '\003' @@>, box 3 + <@@ Checked.int 3.0f @@>, box 3 + <@@ Checked.int 3.0 @@>, box 3 + <@@ Checked.int LanguagePrimitives.GenericOne @@>, box 1 + <@@ Checked.int LanguagePrimitives.GenericOne @@>, box 1 + <@@ Checked.int 3.0M @@>, box 3 + <@@ Checked.int "3" @@>, box 3 + <@@ Checked.int32 3uy @@>, box 3 + <@@ Checked.int32 3y @@>, box 3 + <@@ Checked.int32 3s @@>, box 3 + <@@ Checked.int32 3us @@>, box 3 + <@@ Checked.int32 3 @@>, box 3 + <@@ Checked.int32 3u @@>, box 3 + <@@ Checked.int32 3L @@>, box 3 + <@@ Checked.int32 3UL @@>, box 3 + <@@ Checked.int32 '\003' @@>, box 3 + <@@ Checked.int32 3.0f @@>, box 3 + <@@ Checked.int32 3.0 @@>, box 3 + <@@ Checked.int32 LanguagePrimitives.GenericOne @@>, box 1 + <@@ Checked.int32 LanguagePrimitives.GenericOne @@>, box 1 + <@@ Checked.int32 3.0M @@>, box 3 + <@@ Checked.int32 "3" @@>, box 3 + + <@@ uint 3uy @@>, box 3u + <@@ uint 3y @@>, box 3u + <@@ uint 3s @@>, box 3u + <@@ uint 3us @@>, box 3u + <@@ uint 3 @@>, box 3u + <@@ uint 3u @@>, box 3u + <@@ uint 3L @@>, box 3u + <@@ uint 3UL @@>, box 3u + <@@ uint '\003' @@>, box 3u + <@@ uint 3.0f @@>, box 3u + <@@ uint 3.0 @@>, box 3u + <@@ uint LanguagePrimitives.GenericOne @@>, box 1u + <@@ uint LanguagePrimitives.GenericOne @@>, box 1u + <@@ uint 3.0M @@>, box 3u + <@@ uint "3" @@>, box 3u <@@ uint32 3uy @@>, box 3u <@@ uint32 3y @@>, box 3u <@@ uint32 3s @@>, box 3u @@ -3675,12 +3875,28 @@ module WitnessTests = <@@ uint32 3u @@>, box 3u <@@ uint32 3L @@>, box 3u <@@ uint32 3UL @@>, box 3u + <@@ uint32 '\003' @@>, box 3u <@@ uint32 3.0f @@>, box 3u <@@ uint32 3.0 @@>, box 3u - <@@ uint32 LanguagePrimitives.GenericOne @@>, box 3u - <@@ uint32 LanguagePrimitives.GenericOne @@>, box 3u + <@@ uint32 LanguagePrimitives.GenericOne @@>, box 1u + <@@ uint32 LanguagePrimitives.GenericOne @@>, box 1u <@@ uint32 3.0M @@>, box 3u <@@ uint32 "3" @@>, box 3u + <@@ Checked.uint32 3uy @@>, box 3u + <@@ Checked.uint32 3y @@>, box 3u + <@@ Checked.uint32 3s @@>, box 3u + <@@ Checked.uint32 3us @@>, box 3u + <@@ Checked.uint32 3 @@>, box 3u + <@@ Checked.uint32 3u @@>, box 3u + <@@ Checked.uint32 3L @@>, box 3u + <@@ Checked.uint32 3UL @@>, box 3u + <@@ Checked.uint32 '\003' @@>, box 3u + <@@ Checked.uint32 3.0f @@>, box 3u + <@@ Checked.uint32 3.0 @@>, box 3u + <@@ Checked.uint32 LanguagePrimitives.GenericOne @@>, box 1u + <@@ Checked.uint32 LanguagePrimitives.GenericOne @@>, box 1u + <@@ Checked.uint32 3.0M @@>, box 3u + <@@ Checked.uint32 "3" @@>, box 3u <@@ int64 3uy @@>, box 3L <@@ int64 3y @@>, box 3L @@ -3690,12 +3906,28 @@ module WitnessTests = <@@ int64 3u @@>, box 3L <@@ int64 3L @@>, box 3L <@@ int64 3UL @@>, box 3L + <@@ int64 '\003' @@>, box 3L <@@ int64 3.0f @@>, box 3L <@@ int64 3.0 @@>, box 3L - <@@ int64 LanguagePrimitives.GenericOne @@>, box 3L - <@@ int64 LanguagePrimitives.GenericOne @@>, box 3L + <@@ int64 LanguagePrimitives.GenericOne @@>, box 1L + <@@ int64 LanguagePrimitives.GenericOne @@>, box 1L <@@ int64 3.0M @@>, box 3L <@@ int64 "3" @@>, box 3L + <@@ Checked.int64 3uy @@>, box 3L + <@@ Checked.int64 3y @@>, box 3L + <@@ Checked.int64 3s @@>, box 3L + <@@ Checked.int64 3us @@>, box 3L + <@@ Checked.int64 3 @@>, box 3L + <@@ Checked.int64 3u @@>, box 3L + <@@ Checked.int64 3L @@>, box 3L + <@@ Checked.int64 3UL @@>, box 3L + <@@ Checked.int64 '\003' @@>, box 3L + <@@ Checked.int64 3.0f @@>, box 3L + <@@ Checked.int64 3.0 @@>, box 3L + <@@ Checked.int64 LanguagePrimitives.GenericOne @@>, box 1L + <@@ Checked.int64 LanguagePrimitives.GenericOne @@>, box 1L + <@@ Checked.int64 3.0M @@>, box 3L + <@@ Checked.int64 "3" @@>, box 3L <@@ uint64 3uy @@>, box 3UL <@@ uint64 3y @@>, box 3UL @@ -3705,12 +3937,59 @@ module WitnessTests = <@@ uint64 3u @@>, box 3UL <@@ uint64 3L @@>, box 3UL <@@ uint64 3UL @@>, box 3UL + <@@ uint64 '\003' @@>, box 3UL <@@ uint64 3.0f @@>, box 3UL <@@ uint64 3.0 @@>, box 3UL - <@@ uint64 LanguagePrimitives.GenericOne @@>, box 3UL - <@@ uint64 LanguagePrimitives.GenericOne @@>, box 3UL + <@@ uint64 LanguagePrimitives.GenericOne @@>, box 1UL + <@@ uint64 LanguagePrimitives.GenericOne @@>, box 1UL <@@ uint64 3.0M @@>, box 3UL <@@ uint64 "3" @@>, box 3UL + <@@ Checked.uint64 3uy @@>, box 3UL + <@@ Checked.uint64 3y @@>, box 3UL + <@@ Checked.uint64 3s @@>, box 3UL + <@@ Checked.uint64 3us @@>, box 3UL + <@@ Checked.uint64 3 @@>, box 3UL + <@@ Checked.uint64 3u @@>, box 3UL + <@@ Checked.uint64 3L @@>, box 3UL + <@@ Checked.uint64 3UL @@>, box 3UL + <@@ Checked.uint64 '\003' @@>, box 3UL + <@@ Checked.uint64 3.0f @@>, box 3UL + <@@ Checked.uint64 3.0 @@>, box 3UL + <@@ Checked.uint64 LanguagePrimitives.GenericOne @@>, box 1UL + <@@ Checked.uint64 LanguagePrimitives.GenericOne @@>, box 1UL + <@@ Checked.uint64 3.0M @@>, box 3UL + <@@ Checked.uint64 "3" @@>, box 3UL + + <@@ char 51uy @@>, box '3' + <@@ char 51y @@>, box '3' + <@@ char 51s @@>, box '3' + <@@ char 51us @@>, box '3' + <@@ char 51 @@>, box '3' + <@@ char 51u @@>, box '3' + <@@ char 51L @@>, box '3' + <@@ char 51UL @@>, box '3' + <@@ char '3' @@>, box '3' + <@@ char 51.0f @@>, box '3' + <@@ char 51.0 @@>, box '3' + <@@ char LanguagePrimitives.GenericOne @@>, box '\001' + <@@ char LanguagePrimitives.GenericOne @@>, box '\001' + <@@ char 51.0M @@>, box '3' + <@@ char "3" @@>, box '3' + <@@ Checked.char 51uy @@>, box '3' + <@@ Checked.char 51y @@>, box '3' + <@@ Checked.char 51s @@>, box '3' + <@@ Checked.char 51us @@>, box '3' + <@@ Checked.char 51 @@>, box '3' + <@@ Checked.char 51u @@>, box '3' + <@@ Checked.char 51L @@>, box '3' + <@@ Checked.char 51UL @@>, box '3' + <@@ Checked.char '3' @@>, box '3' + <@@ Checked.char 51.0f @@>, box '3' + <@@ Checked.char 51.0 @@>, box '3' + <@@ Checked.char LanguagePrimitives.GenericOne @@>, box '\001' + <@@ Checked.char LanguagePrimitives.GenericOne @@>, box '\001' + <@@ Checked.char 51.0M @@>, box '3' + <@@ Checked.char "3" @@>, box '3' <@@ nativeint 3uy @@>, box 3n <@@ nativeint 3y @@>, box 3n @@ -3720,12 +3999,28 @@ module WitnessTests = <@@ nativeint 3u @@>, box 3n <@@ nativeint 3L @@>, box 3n <@@ nativeint 3UL @@>, box 3n + <@@ nativeint '\003' @@>, box 3n <@@ nativeint 3.0f @@>, box 3n <@@ nativeint 3.0 @@>, box 3n - <@@ nativeint LanguagePrimitives.GenericOne @@>, box 3n - <@@ nativeint LanguagePrimitives.GenericOne @@>, box 3n + <@@ nativeint LanguagePrimitives.GenericOne @@>, box 1n + <@@ nativeint LanguagePrimitives.GenericOne @@>, box 1n <@@ nativeint 3.0M @@>, box 3n <@@ nativeint "3" @@>, box 3n + <@@ Checked.nativeint 3uy @@>, box 3n + <@@ Checked.nativeint 3y @@>, box 3n + <@@ Checked.nativeint 3s @@>, box 3n + <@@ Checked.nativeint 3us @@>, box 3n + <@@ Checked.nativeint 3 @@>, box 3n + <@@ Checked.nativeint 3u @@>, box 3n + <@@ Checked.nativeint 3L @@>, box 3n + <@@ Checked.nativeint 3UL @@>, box 3n + <@@ Checked.nativeint '\003' @@>, box 3n + <@@ Checked.nativeint 3.0f @@>, box 3n + <@@ Checked.nativeint 3.0 @@>, box 3n + <@@ Checked.nativeint LanguagePrimitives.GenericOne @@>, box 1n + <@@ Checked.nativeint LanguagePrimitives.GenericOne @@>, box 1n + <@@ Checked.nativeint 3.0M @@>, box 3n + <@@ Checked.nativeint "3" @@>, box 3n <@@ unativeint 3uy @@>, box 3un <@@ unativeint 3y @@>, box 3un @@ -3735,13 +4030,44 @@ module WitnessTests = <@@ unativeint 3u @@>, box 3un <@@ unativeint 3L @@>, box 3un <@@ unativeint 3UL @@>, box 3un + <@@ unativeint '\003' @@>, box 3un <@@ unativeint 3.0f @@>, box 3un <@@ unativeint 3.0 @@>, box 3un - <@@ unativeint LanguagePrimitives.GenericOne @@>, box 3un - <@@ unativeint LanguagePrimitives.GenericOne @@>, box 3un + <@@ unativeint LanguagePrimitives.GenericOne @@>, box 1un + <@@ unativeint LanguagePrimitives.GenericOne @@>, box 1un <@@ unativeint 3.0M @@>, box 3un <@@ unativeint "3" @@>, box 3un - + <@@ Checked.unativeint 3uy @@>, box 3un + <@@ Checked.unativeint 3y @@>, box 3un + <@@ Checked.unativeint 3s @@>, box 3un + <@@ Checked.unativeint 3us @@>, box 3un + <@@ Checked.unativeint 3 @@>, box 3un + <@@ Checked.unativeint 3u @@>, box 3un + <@@ Checked.unativeint 3L @@>, box 3un + <@@ Checked.unativeint 3UL @@>, box 3un + <@@ Checked.unativeint '\003' @@>, box 3un + <@@ Checked.unativeint 3.0f @@>, box 3un + <@@ Checked.unativeint 3.0 @@>, box 3un + <@@ Checked.unativeint LanguagePrimitives.GenericOne @@>, box 1un + <@@ Checked.unativeint LanguagePrimitives.GenericOne @@>, box 1un + <@@ Checked.unativeint 3.0M @@>, box 3un + <@@ Checked.unativeint "3" @@>, box 3un + + <@@ single 3uy @@>, box 3f + <@@ single 3y @@>, box 3f + <@@ single 3s @@>, box 3f + <@@ single 3us @@>, box 3f + <@@ single 3 @@>, box 3f + <@@ single 3u @@>, box 3f + <@@ single 3L @@>, box 3f + <@@ single 3UL @@>, box 3f + <@@ single '\003' @@>, box 3f + <@@ single 3.0f @@>, box 3f + <@@ single 3.0 @@>, box 3f + <@@ single LanguagePrimitives.GenericOne @@>, box 1f + <@@ single LanguagePrimitives.GenericOne @@>, box 1f + <@@ single 3.0M @@>, box 3f + <@@ single "3" @@>, box 3f <@@ float32 3uy @@>, box 3f <@@ float32 3y @@>, box 3f <@@ float32 3s @@>, box 3f @@ -3750,13 +4076,29 @@ module WitnessTests = <@@ float32 3u @@>, box 3f <@@ float32 3L @@>, box 3f <@@ float32 3UL @@>, box 3f + <@@ float32 '\003' @@>, box 3f <@@ float32 3.0f @@>, box 3f <@@ float32 3.0 @@>, box 3f - <@@ float32 LanguagePrimitives.GenericOne @@>, box 3f - <@@ float32 LanguagePrimitives.GenericOne @@>, box 3f + <@@ float32 LanguagePrimitives.GenericOne @@>, box 1f + <@@ float32 LanguagePrimitives.GenericOne @@>, box 1f <@@ float32 3.0M @@>, box 3f <@@ float32 "3" @@>, box 3f + <@@ double 3uy @@>, box 3. + <@@ double 3y @@>, box 3. + <@@ double 3s @@>, box 3. + <@@ double 3us @@>, box 3. + <@@ double 3 @@>, box 3. + <@@ double 3u @@>, box 3. + <@@ double 3L @@>, box 3. + <@@ double 3UL @@>, box 3. + <@@ double '\003' @@>, box 3. + <@@ double 3.0f @@>, box 3. + <@@ double 3.0 @@>, box 3. + <@@ double LanguagePrimitives.GenericOne @@>, box 1. + <@@ double LanguagePrimitives.GenericOne @@>, box 1. + <@@ double 3.0M @@>, box 3. + <@@ double "3" @@>, box 3. <@@ float 3uy @@>, box 3. <@@ float 3y @@>, box 3. <@@ float 3s @@>, box 3. @@ -3765,10 +4107,11 @@ module WitnessTests = <@@ float 3u @@>, box 3. <@@ float 3L @@>, box 3. <@@ float 3UL @@>, box 3. + <@@ float '\003' @@>, box 3. <@@ float 3.0f @@>, box 3. <@@ float 3.0 @@>, box 3. - <@@ float LanguagePrimitives.GenericOne @@>, box 3. - <@@ float LanguagePrimitives.GenericOne @@>, box 3. + <@@ float LanguagePrimitives.GenericOne @@>, box 1. + <@@ float LanguagePrimitives.GenericOne @@>, box 1. <@@ float 3.0M @@>, box 3. <@@ float "3" @@>, box 3. @@ -3780,29 +4123,30 @@ module WitnessTests = <@@ decimal 3u @@>, box 3m <@@ decimal 3L @@>, box 3m <@@ decimal 3UL @@>, box 3m + <@@ decimal '\003' @@>, box 3m <@@ decimal 3.0f @@>, box 3m <@@ decimal 3.0 @@>, box 3m - <@@ decimal LanguagePrimitives.GenericOne @@>, box 3m - <@@ decimal LanguagePrimitives.GenericOne @@>, box 3m + <@@ decimal LanguagePrimitives.GenericOne @@>, box 1m + <@@ decimal LanguagePrimitives.GenericOne @@>, box 1m <@@ decimal 3.0M @@>, box 3m <@@ decimal "3" @@>, box 3m - <@@ LanguagePrimitives.GenericZero @@>, box 0. - <@@ LanguagePrimitives.GenericZero @@>, box 0f <@@ LanguagePrimitives.GenericZero @@>, box 0 <@@ LanguagePrimitives.GenericZero @@>, box 0L <@@ LanguagePrimitives.GenericZero @@>, box 0UL + <@@ LanguagePrimitives.GenericZero @@>, box '\000' <@@ LanguagePrimitives.GenericZero @@>, box 0n <@@ LanguagePrimitives.GenericZero @@>, box 0un - <@@ LanguagePrimitives.GenericZero @@>, box '\000' - <@@ LanguagePrimitives.GenericOne @@>, box 1. - <@@ LanguagePrimitives.GenericOne @@>, box 1f + <@@ LanguagePrimitives.GenericZero @@>, box 0f + <@@ LanguagePrimitives.GenericZero @@>, box 0. <@@ LanguagePrimitives.GenericOne @@>, box 1 <@@ LanguagePrimitives.GenericOne @@>, box 1L <@@ LanguagePrimitives.GenericOne @@>, box 1UL + <@@ LanguagePrimitives.GenericOne @@>, box '\001' <@@ LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne @@>, box 1un - <@@ LanguagePrimitives.GenericOne @@>, box '\001' + <@@ LanguagePrimitives.GenericOne @@>, box 1f + <@@ LanguagePrimitives.GenericOne @@>, box 1. <@@ List.sum [ 1; 2 ] @@>, box 3 <@@ List.sum [ 1.0f; 2.0f ] @@>, box 3f <@@ List.sum [ 1.0; 2.0 ] @@>, box 3. @@ -3811,95 +4155,359 @@ module WitnessTests = <@@ List.average [ 1.0f; 2.0f ] @@>, box 1.5f <@@ List.average [ 1.0M; 2.0M ] @@>, box 1.5m - <@@ Nullable<_> 1y ?+ 4y @@>, box <| Nullable<_> 5y - <@@ Nullable<_> 1uy ?+ 4uy @@>, box <| Nullable<_> 5uy - <@@ Nullable<_> 1s ?+ 4s @@>, box <| Nullable<_> 5s - <@@ Nullable<_> 1us ?+ 4us @@>, box <| Nullable<_> 5us - <@@ Nullable<_> 1 ?+ 4 @@>, box <| Nullable<_> 5 - <@@ Nullable<_> 1u ?+ 4u @@>, box <| Nullable<_> 5u - <@@ Nullable<_> 1L ?+ 4L @@>, box <| Nullable<_> 5L - <@@ Nullable<_> 1uL ?+ 4uL @@>, box <| Nullable<_> 5uL - <@@ Nullable<_> 1.0f ?+ 4.0f @@>, box <| Nullable<_> 5f - <@@ Nullable<_> 1.0 ?+ 4.0 @@>, box <| Nullable<_> 5. - <@@ Nullable<_> 1m ?+ 4m @@>, box <| Nullable<_> 5m - <@@ Nullable<_> '1' ?+ '\004' @@>, box <| Nullable<_> '5' - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2n - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2un + <@@ Nullable.byte (Nullable<_> 3uy) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3y) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3s) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3us) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3u) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3L) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3UL) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> '\003') @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3.0f) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3.0) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy + <@@ Nullable.byte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy + <@@ Nullable.byte (Nullable<_> 3.0M) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3uy) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3y) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3s) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3us) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3u) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3L) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3UL) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> '\003') @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3.0f) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3.0) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy + <@@ Nullable.uint8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy + <@@ Nullable.uint8 (Nullable<_> 3.0M) @@>, box 3uy + + <@@ Nullable.sbyte (Nullable<_> 3uy) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3y) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3s) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3us) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3u) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3L) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3UL) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> '\003') @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3.0f) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3.0) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y + <@@ Nullable.sbyte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y + <@@ Nullable.sbyte (Nullable<_> 3.0M) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3uy) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3y) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3s) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3us) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3u) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3L) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3UL) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> '\003') @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3.0f) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3.0) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y + <@@ Nullable.int8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y + <@@ Nullable.int8 (Nullable<_> 3.0M) @@>, box 3y + + <@@ Nullable.int16 (Nullable<_> 3uy) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3y) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3s) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3us) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3u) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3L) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3UL) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> '\003') @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3.0f) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3.0) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1s + <@@ Nullable.int16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1s + <@@ Nullable.int16 (Nullable<_> 3.0M) @@>, box 3s + + <@@ Nullable.uint16 (Nullable<_> 3uy) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3y) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3s) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3us) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3u) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3L) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3UL) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> '\003') @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3.0f) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3.0) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1us + <@@ Nullable.uint16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1us + <@@ Nullable.uint16 (Nullable<_> 3.0M) @@>, box 3us + + <@@ Nullable.int (Nullable<_> 3uy) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3y) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3s) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3us) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3u) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3L) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3UL) @@>, box 3 + <@@ Nullable.int (Nullable<_> '\003') @@>, box 3 + <@@ Nullable.int (Nullable<_> 3.0f) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3.0) @@>, box 3 + <@@ Nullable.int (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 + <@@ Nullable.int (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 + <@@ Nullable.int (Nullable<_> 3.0M) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3uy) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3y) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3s) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3us) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3u) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3L) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3UL) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> '\003') @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3.0f) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3.0) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 + <@@ Nullable.int32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 + <@@ Nullable.int32 (Nullable<_> 3.0M) @@>, box 3 + + <@@ Nullable.uint (Nullable<_> 3uy) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3y) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3s) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3us) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3u) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3L) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3UL) @@>, box 3u + <@@ Nullable.uint (Nullable<_> '\003') @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3.0f) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3.0) @@>, box 3u + <@@ Nullable.uint (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u + <@@ Nullable.uint (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u + <@@ Nullable.uint (Nullable<_> 3.0M) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3uy) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3y) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3s) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3us) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3u) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3L) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3UL) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> '\003') @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3.0f) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3.0) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u + <@@ Nullable.uint32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u + <@@ Nullable.uint32 (Nullable<_> 3.0M) @@>, box 3u + + <@@ Nullable.int64 (Nullable<_> 3uy) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3y) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3s) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3us) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3u) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3L) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3UL) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> '\003') @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3.0f) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3.0) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1L + <@@ Nullable.int64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1L + <@@ Nullable.int64 (Nullable<_> 3.0M) @@>, box 3L + + <@@ Nullable.uint64 (Nullable<_> 3uy) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3y) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3s) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3us) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3u) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3L) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3UL) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> '\003') @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3.0f) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3.0) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1UL + <@@ Nullable.uint64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1UL + <@@ Nullable.uint64 (Nullable<_> 3.0M) @@>, box 3UL + + <@@ Nullable.char (Nullable<_> 51uy) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51y) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51s) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51us) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51u) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51L) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51UL) @@>, box '3' + <@@ Nullable.char (Nullable<_> '3') @@>, box '3' + <@@ Nullable.char (Nullable<_> 51.0f) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51.0) @@>, box '3' + <@@ Nullable.char (Nullable<_> LanguagePrimitives.GenericOne) @@>, box '\001' + <@@ Nullable.char (Nullable<_> LanguagePrimitives.GenericOne) @@>, box '\001' + <@@ Nullable.char (Nullable<_> 51.0M) @@>, box '3' + + <@@ Nullable.single (Nullable<_> 3uy) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3y) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3s) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3us) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3u) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3L) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3UL) @@>, box 3f + <@@ Nullable.single (Nullable<_> '\003') @@>, box 3f + <@@ Nullable.single (Nullable<_> 3.0f) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3.0) @@>, box 3f + <@@ Nullable.single (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f + <@@ Nullable.single (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f + <@@ Nullable.single (Nullable<_> 3.0M) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3uy) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3y) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3s) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3us) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3u) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3L) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3UL) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> '\003') @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3.0f) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3.0) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f + <@@ Nullable.float32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f + <@@ Nullable.float32 (Nullable<_> 3.0M) @@>, box 3f + + <@@ Nullable.double (Nullable<_> 3uy) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3y) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3s) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3us) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3u) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3L) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3UL) @@>, box 3. + <@@ Nullable.double (Nullable<_> '\003') @@>, box 3. + <@@ Nullable.double (Nullable<_> 3.0f) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3.0) @@>, box 3. + <@@ Nullable.double (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. + <@@ Nullable.double (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. + <@@ Nullable.double (Nullable<_> 3.0M) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3uy) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3y) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3s) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3us) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3u) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3L) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3UL) @@>, box 3. + <@@ Nullable.float (Nullable<_> '\003') @@>, box 3. + <@@ Nullable.float (Nullable<_> 3.0f) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3.0) @@>, box 3. + <@@ Nullable.float (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. + <@@ Nullable.float (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. + <@@ Nullable.float (Nullable<_> 3.0M) @@>, box 3. + + <@@ Nullable.decimal (Nullable<_> 3uy) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3y) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3s) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3us) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3u) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3L) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3UL) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> '\003') @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3.0f) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3.0) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1m + <@@ Nullable.decimal (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1m + <@@ Nullable.decimal (Nullable<_> 3.0M) @@>, box 3m + + <@@ Nullable<_> 1y ?+ 4y @@>, box 5y + <@@ Nullable<_> 1uy ?+ 4uy @@>, box 5uy + <@@ Nullable<_> 1s ?+ 4s @@>, box 5s + <@@ Nullable<_> 1us ?+ 4us @@>, box 5us + <@@ Nullable<_> 1 ?+ 4 @@>, box 5 + <@@ Nullable<_> 1u ?+ 4u @@>, box 5u + <@@ Nullable<_> 1L ?+ 4L @@>, box 5L + <@@ Nullable<_> 1uL ?+ 4uL @@>, box 5uL + <@@ Nullable<_> 1.0f ?+ 4.0f @@>, box 5f + <@@ Nullable<_> 1.0 ?+ 4.0 @@>, box 5. + <@@ Nullable<_> 1m ?+ 4m @@>, box 5m + <@@ Nullable<_> '1' ?+ '\004' @@>, box '5' + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box 2n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box 2un - <@@ 1y +? Nullable<_> 4y @@>, box <| Nullable<_> 5y - <@@ 1uy +? Nullable<_> 4uy @@>, box <| Nullable<_> 5uy - <@@ 1s +? Nullable<_> 4s @@>, box <| Nullable<_> 5s - <@@ 1us +? Nullable<_> 4us @@>, box <| Nullable<_> 5us - <@@ 1 +? Nullable<_> 4 @@>, box <| Nullable<_> 5 - <@@ 1u +? Nullable<_> 4u @@>, box <| Nullable<_> 5u - <@@ 1L +? Nullable<_> 4L @@>, box <| Nullable<_> 5L - <@@ 1uL +? Nullable<_> 4uL @@>, box <| Nullable<_> 5uL - <@@ 1.0f +? Nullable<_> 4.0f @@>, box <| Nullable<_> 5f - <@@ 1.0 +? Nullable<_> 4.0 @@>, box <| Nullable<_> 5. - <@@ 1m +? Nullable<_> 4m @@>, box <| Nullable<_> 5m - <@@ '1' +? Nullable<_> '\004' @@>, box <| Nullable<_> '5' - <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2n - <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2un + <@@ 1y +? Nullable<_> 4y @@>, box 5y + <@@ 1uy +? Nullable<_> 4uy @@>, box 5uy + <@@ 1s +? Nullable<_> 4s @@>, box 5s + <@@ 1us +? Nullable<_> 4us @@>, box 5us + <@@ 1 +? Nullable<_> 4 @@>, box 5 + <@@ 1u +? Nullable<_> 4u @@>, box 5u + <@@ 1L +? Nullable<_> 4L @@>, box 5L + <@@ 1uL +? Nullable<_> 4uL @@>, box 5uL + <@@ 1.0f +? Nullable<_> 4.0f @@>, box 5f + <@@ 1.0 +? Nullable<_> 4.0 @@>, box 5. + <@@ 1m +? Nullable<_> 4m @@>, box 5m + <@@ '1' +? Nullable<_> '\004' @@>, box '5' + <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2n + <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2un - <@@ Nullable<_> 1y ?+? Nullable<_> 4y @@>, box <| Nullable<_> 5y - <@@ Nullable<_> 1uy ?+? Nullable<_> 4uy @@>, box <| Nullable<_> 5uy - <@@ Nullable<_> 1s ?+? Nullable<_> 4s @@>, box <| Nullable<_> 5s - <@@ Nullable<_> 1us ?+? Nullable<_> 4us @@>, box <| Nullable<_> 5us - <@@ Nullable<_> 1 ?+? Nullable<_> 4 @@>, box <| Nullable<_> 5 - <@@ Nullable<_> 1u ?+? Nullable<_> 4u @@>, box <| Nullable<_> 5u - <@@ Nullable<_> 1L ?+? Nullable<_> 4L @@>, box <| Nullable<_> 5L - <@@ Nullable<_> 1uL ?+? Nullable<_> 4uL @@>, box <| Nullable<_> 5uL - <@@ Nullable<_> 1.0f ?+? Nullable<_> 4.0f @@>, box <| Nullable<_> 5f - <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, box <| Nullable<_> 5. - <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, box <| Nullable<_> 5m - <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, box <| Nullable<_> '5' - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2n - <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> 2un + <@@ Nullable<_> 1y ?+? Nullable<_> 4y @@>, box 5y + <@@ Nullable<_> 1uy ?+? Nullable<_> 4uy @@>, box 5uy + <@@ Nullable<_> 1s ?+? Nullable<_> 4s @@>, box 5s + <@@ Nullable<_> 1us ?+? Nullable<_> 4us @@>, box 5us + <@@ Nullable<_> 1 ?+? Nullable<_> 4 @@>, box 5 + <@@ Nullable<_> 1u ?+? Nullable<_> 4u @@>, box 5u + <@@ Nullable<_> 1L ?+? Nullable<_> 4L @@>, box 5L + <@@ Nullable<_> 1uL ?+? Nullable<_> 4uL @@>, box 5uL + <@@ Nullable<_> 1.0f ?+? Nullable<_> 4.0f @@>, box 5f + <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, box 5. + <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, box 5m + <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, box '5' + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2un - <@@ Nullable<_> 1y ?= 1y @@>, box <| Nullable<_> true - <@@ Nullable<_> 1uy ?= 1uy @@>, box <| Nullable<_> true - <@@ Nullable<_> 1s ?= 1s @@>, box <| Nullable<_> true - <@@ Nullable<_> 1us ?= 1us @@>, box <| Nullable<_> true - <@@ Nullable<_> 1 ?= 1 @@>, box <| Nullable<_> true - <@@ Nullable<_> 1u ?= 1u @@>, box <| Nullable<_> true - <@@ Nullable<_> 1L ?= 1L @@>, box <| Nullable<_> true - <@@ Nullable<_> 1uL ?= 1uL @@>, box <| Nullable<_> true - <@@ Nullable<_> 1.0f ?= 1.0f @@>, box <| Nullable<_> true - <@@ Nullable<_> 1.0 ?= 1.0 @@>, box <| Nullable<_> true - <@@ Nullable<_> 1m ?= 1m @@>, box <| Nullable<_> true - <@@ Nullable<_> '1' ?= '1' @@>, box <| Nullable<_> true - <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true - <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true + <@@ Nullable<_> 1y ?= 1y @@>, box true + <@@ Nullable<_> 1uy ?= 1uy @@>, box true + <@@ Nullable<_> 1s ?= 1s @@>, box true + <@@ Nullable<_> 1us ?= 1us @@>, box true + <@@ Nullable<_> 1 ?= 1 @@>, box true + <@@ Nullable<_> 1u ?= 1u @@>, box true + <@@ Nullable<_> 1L ?= 1L @@>, box true + <@@ Nullable<_> 1uL ?= 1uL @@>, box true + <@@ Nullable<_> 1.0f ?= 1.0f @@>, box true + <@@ Nullable<_> 1.0 ?= 1.0 @@>, box true + <@@ Nullable<_> 1m ?= 1m @@>, box true + <@@ Nullable<_> '1' ?= '1' @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box true - <@@ 1y =? Nullable<_> 1y @@>, box <| Nullable<_> true - <@@ 1uy =? Nullable<_> 1uy @@>, box <| Nullable<_> true - <@@ 1s =? Nullable<_> 1s @@>, box <| Nullable<_> true - <@@ 1us =? Nullable<_> 1us @@>, box <| Nullable<_> true - <@@ 1 =? Nullable<_> 1 @@>, box <| Nullable<_> true - <@@ 1u =? Nullable<_> 1u @@>, box <| Nullable<_> true - <@@ 1L =? Nullable<_> 1L @@>, box <| Nullable<_> true - <@@ 1uL =? Nullable<_> 1uL @@>, box <| Nullable<_> true - <@@ 1.0f =? Nullable<_> 1.0f @@>, box <| Nullable<_> true - <@@ 1.0 =? Nullable<_> 1.0 @@>, box <| Nullable<_> true - <@@ 1m =? Nullable<_> 1m @@>, box <| Nullable<_> true - <@@ '1' =? Nullable<_> '1' @@>, box <| Nullable<_> true - <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true - <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true + <@@ 1y =? Nullable<_> 1y @@>, box true + <@@ 1uy =? Nullable<_> 1uy @@>, box true + <@@ 1s =? Nullable<_> 1s @@>, box true + <@@ 1us =? Nullable<_> 1us @@>, box true + <@@ 1 =? Nullable<_> 1 @@>, box true + <@@ 1u =? Nullable<_> 1u @@>, box true + <@@ 1L =? Nullable<_> 1L @@>, box true + <@@ 1uL =? Nullable<_> 1uL @@>, box true + <@@ 1.0f =? Nullable<_> 1.0f @@>, box true + <@@ 1.0 =? Nullable<_> 1.0 @@>, box true + <@@ 1m =? Nullable<_> 1m @@>, box true + <@@ '1' =? Nullable<_> '1' @@>, box true + <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box true - <@@ Nullable<_> 1y ?=? Nullable<_> 1y @@>, box <| Nullable<_> true - <@@ Nullable<_> 1uy ?=? Nullable<_> 1uy @@>, box <| Nullable<_> true - <@@ Nullable<_> 1s ?=? Nullable<_> 1s @@>, box <| Nullable<_> true - <@@ Nullable<_> 1us ?=? Nullable<_> 1us @@>, box <| Nullable<_> true - <@@ Nullable<_> 1 ?=? Nullable<_> 1 @@>, box <| Nullable<_> true - <@@ Nullable<_> 1u ?=? Nullable<_> 1u @@>, box <| Nullable<_> true - <@@ Nullable<_> 1L ?=? Nullable<_> 1L @@>, box <| Nullable<_> true - <@@ Nullable<_> 1uL ?=? Nullable<_> 1uL @@>, box <| Nullable<_> true - <@@ Nullable<_> 1.0f ?=? Nullable<_> 1.0f @@>, box <| Nullable<_> true - <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, box <| Nullable<_> true - <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, box <| Nullable<_> true - <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, box <| Nullable<_> true - <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true - <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box <| Nullable<_> true + <@@ Nullable<_> 1y ?=? Nullable<_> 1y @@>, box true + <@@ Nullable<_> 1uy ?=? Nullable<_> 1uy @@>, box true + <@@ Nullable<_> 1s ?=? Nullable<_> 1s @@>, box true + <@@ Nullable<_> 1us ?=? Nullable<_> 1us @@>, box true + <@@ Nullable<_> 1 ?=? Nullable<_> 1 @@>, box true + <@@ Nullable<_> 1u ?=? Nullable<_> 1u @@>, box true + <@@ Nullable<_> 1L ?=? Nullable<_> 1L @@>, box true + <@@ Nullable<_> 1uL ?=? Nullable<_> 1uL @@>, box true + <@@ Nullable<_> 1.0f ?=? Nullable<_> 1.0f @@>, box true + <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, box true + <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, box true + <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true ] tests |> List.map (fun (test, eval) -> From 51d397f526e51eab30dafd6ce514348d4e7a4217 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Tue, 22 Jun 2021 21:55:26 +0800 Subject: [PATCH 32/78] Undo that line, leave that to another time --- src/fsharp/FSharp.Core/Linq.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index b8f72a4fc6e..7b2d9cf0fab 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -396,7 +396,7 @@ module LeafExpressionConverter = | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual | NullableLessNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan - | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) + | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual // Detect the F# quotation encoding of decimal literals | MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) -> From bd11bdf48d73a7aaa611a599dc2f7d9242465d0a Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 23 Jun 2021 13:45:23 +0800 Subject: [PATCH 33/78] Ping... --- tests/fsharp/core/quotes/test.fsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index f36f2c4bf01..22e4777d102 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3607,6 +3607,22 @@ module WitnessTests = <@@ ~~~LanguagePrimitives.GenericOne @@>, box ~~~1n <@@ ~~~LanguagePrimitives.GenericOne @@>, box ~~~1un + <@@ 3y = 3y @@>, box true + <@@ 3uy = 3uy @@>, box true + <@@ 3s = 3s @@>, box true + <@@ 3us = 3us @@>, box true + <@@ 3 = 3 @@>, box true + <@@ 3u = 3u @@>, box true + <@@ 3L = 3L @@>, box true + <@@ 3UL = 3UL @@>, box true + <@@ '3' = '3' @@>, box true + <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box ~~~1n + <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box ~~~1un + <@@ 3f = 3f @@>, box true + <@@ 3. = 3. @@>, box true + <@@ 3m = 3m @@>, box true + <@@ "3" = "3" @@>, box true + <@@ byte 3uy @@>, box 3uy <@@ byte 3y @@>, box 3uy <@@ byte 3s @@>, box 3uy From 06c19c89ed81a6665c5c4972e78f22837fb170f0 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 24 Jun 2021 22:28:40 +0800 Subject: [PATCH 34/78] More tests to feed the CI? --- tests/fsharp/core/quotes/test.fsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 22e4777d102..a6c62a3b52a 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3616,12 +3616,28 @@ module WitnessTests = <@@ 3L = 3L @@>, box true <@@ 3UL = 3UL @@>, box true <@@ '3' = '3' @@>, box true - <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box ~~~1n - <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box ~~~1un + <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box true <@@ 3f = 3f @@>, box true <@@ 3. = 3. @@>, box true <@@ 3m = 3m @@>, box true <@@ "3" = "3" @@>, box true + + <@@ 3y <> 3y @@>, box false + <@@ 3uy <> 3uy @@>, box false + <@@ 3s <> 3s @@>, box false + <@@ 3us <> 3us @@>, box false + <@@ 3 <> 3 @@>, box false + <@@ 3u <> 3u @@>, box false + <@@ 3L <> 3L @@>, box false + <@@ 3UL <> 3UL @@>, box false + <@@ '3' <> '3' @@>, box false + <@@ LanguagePrimitives.GenericOne <> LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne <> LanguagePrimitives.GenericOne @@>, box false + <@@ 3f <> 3f @@>, box false + <@@ 3. <> 3. @@>, box false + <@@ 3m <> 3m @@>, box false + <@@ "3" <> "3" @@>, box false <@@ byte 3uy @@>, box 3uy <@@ byte 3y @@>, box 3uy From 79fe88e45cabcc4c5d9f4ed45614a41ada5c74c2 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 25 Jun 2021 01:53:48 +0800 Subject: [PATCH 35/78] Here, have more tests --- tests/fsharp/core/quotes/test.fsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index a6c62a3b52a..de5ced3afef 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -4540,6 +4540,21 @@ module WitnessTests = <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, box true <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + + <@@ Nullable<_> 3y ?<> 3y @@>, box false + <@@ Nullable<_> 3uy ?<> 3uy @@>, box false + <@@ Nullable<_> 3s ?<> 3s @@>, box false + <@@ Nullable<_> 3us ?<> 3us @@>, box false + <@@ Nullable<_> 3 ?<> 3 @@>, box false + <@@ Nullable<_> 3u ?<> 3u @@>, box false + <@@ Nullable<_> 3L ?<> 3L @@>, box false + <@@ Nullable<_> 3UL ?<> 3UL @@>, box false + <@@ Nullable<_> '3' ?<> '3' @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> 3f ?<> 3f @@>, box false + <@@ Nullable<_> 3. ?<> 3. @@>, box false + <@@ Nullable<_> 3m ?<> 3m @@>, box false ] tests |> List.map (fun (test, eval) -> From 3bf717227ccf523b97adb48ca77a92265fddab47 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 25 Jun 2021 13:25:33 +0800 Subject: [PATCH 36/78] Howdy CI --- tests/fsharp/core/quotes/test.fsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index de5ced3afef..080a8664796 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -4555,6 +4555,21 @@ module WitnessTests = <@@ Nullable<_> 3f ?<> 3f @@>, box false <@@ Nullable<_> 3. ?<> 3. @@>, box false <@@ Nullable<_> 3m ?<> 3m @@>, box false + + <@@ 3y <>? Nullable<_> 3y @@>, box false + <@@ 3uy <>? Nullable<_> 3uy @@>, box false + <@@ 3s <>? Nullable<_> 3s @@>, box false + <@@ 3us <>? Nullable<_> 3us @@>, box false + <@@ 3 <>? Nullable<_> 3 @@>, box false + <@@ 3u <>? Nullable<_> 3u @@>, box false + <@@ 3L <>? Nullable<_> 3L @@>, box false + <@@ 3UL <>? Nullable<_> 3UL @@>, box false + <@@ '3' <>? Nullable<_> '3' @@>, box false + <@@ LanguagePrimitives.GenericOne <>? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne <>? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ 3f <>? Nullable<_> 3f @@>, box false + <@@ 3. <>? Nullable<_> 3. @@>, box false + <@@ 3m <>? Nullable<_> 3m @@>, box false ] tests |> List.map (fun (test, eval) -> From 7cfbd15f230a659c4ca04f7df73db0b823232b4a Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 25 Jun 2021 20:07:47 +0800 Subject: [PATCH 37/78] Persisting in times of despair --- tests/fsharp/core/quotes/test.fsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 080a8664796..b151885ae7d 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -4570,6 +4570,21 @@ module WitnessTests = <@@ 3f <>? Nullable<_> 3f @@>, box false <@@ 3. <>? Nullable<_> 3. @@>, box false <@@ 3m <>? Nullable<_> 3m @@>, box false + + <@@ Nullable<_> 3y ?<>? Nullable<_> 3y @@>, box false + <@@ Nullable<_> 3uy ?<>? Nullable<_> 3uy @@>, box false + <@@ Nullable<_> 3s ?<>? Nullable<_> 3s @@>, box false + <@@ Nullable<_> 3us ?<>? Nullable<_> 3us @@>, box false + <@@ Nullable<_> 3 ?<>? Nullable<_> 3 @@>, box false + <@@ Nullable<_> 3u ?<>? Nullable<_> 3u @@>, box false + <@@ Nullable<_> 3L ?<>? Nullable<_> 3L @@>, box false + <@@ Nullable<_> 3UL ?<>? Nullable<_> 3UL @@>, box false + <@@ Nullable<_> '3' ?<>? Nullable<_> '3' @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<>? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<>? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> 3f ?<>? Nullable<_> 3f @@>, box false + <@@ Nullable<_> 3. ?<>? Nullable<_> 3. @@>, box false + <@@ Nullable<_> 3m ?<>? Nullable<_> 3m @@>, box false ] tests |> List.map (fun (test, eval) -> From 97a870837196a62ab4f62aa1df8da77ba8962bc1 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 4 Jul 2021 16:30:39 +0800 Subject: [PATCH 38/78] Is this it? --- src/fsharp/FSharp.Core/Linq.fs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 7b2d9cf0fab..56b50727424 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -441,21 +441,21 @@ module LeafExpressionConverter = | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) - | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) - | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) - | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) - | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) - - | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) - | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) - | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) - | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) + | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConvFallback inp env false x + | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConvFallback inp env false x + | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) -> transConvFallback inp env false x + | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) -> transConvFallback inp env false x + | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x + + | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) -> transConvFallback inp env false x + | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) -> transConvFallback inp env false x + | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) -> transConvFallback inp env false x + | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) -> transConvFallback inp env false x | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x - | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) - | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) - | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) + | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) -> transConvFallback inp env true x + | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) -> transConvFallback inp env true x + | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) -> transConvFallback inp env true x | CheckedConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env true x | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> From 7bcba82ce82ab2ee0d5bb3f38f17d70f54f9732f Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 4 Jul 2021 18:16:49 +0800 Subject: [PATCH 39/78] List is too long --- tests/fsharp/core/quotes/test.fsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 1bbe6b535c6..14019e2eb50 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3385,7 +3385,7 @@ module WitnessTests = test "check CallWithWitnesses all operators" (let tests = - [ <@@ sin 1.0 @@>, box 0x3FEAED548F090CEELF // Around 0.841470984807897 + [|<@@ sin 1.0 @@>, box 0x3FEAED548F090CEELF // Around 0.841470984807897 <@@ sin 1.0f @@>, box 0x3F576AA4lf // = 0.841471f <@@ sign 1.0f @@>, box 1 <@@ sqrt 1.0f @@>, box 1f @@ -4585,9 +4585,9 @@ module WitnessTests = <@@ Nullable<_> 3f ?<>? Nullable<_> 3f @@>, box false <@@ Nullable<_> 3. ?<>? Nullable<_> 3. @@>, box false <@@ Nullable<_> 3m ?<>? Nullable<_> 3m @@>, box false - ] + |] - tests |> List.map (fun (test, eval) -> + tests |> Array.map (fun (test, eval) -> begin printfn "--> Checking we can evaluate %A" test let res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test @@ -4618,7 +4618,7 @@ module WitnessTests = || (printfn "<-- FAILURE, failed after matching with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) | _ -> printfn " List.forall id) // Don't short circuit on a failed test + false) |> Array.forall id) // Don't short circuit on a failed test module MoreWitnessTests = From e228dac8596ea8743a37ecab88ebc310f35cafab Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 18:32:39 +0800 Subject: [PATCH 40/78] Introduce new conversions --- src/fsharp/ConstraintSolver.fs | 27 +++++---------------------- src/fsharp/FSharp.Core/prim-types.fs | 8 +++++++- tests/fsharp/core/libtest/test.fsx | 8 ++++++++ 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index f83c53204ab..c06db5feece 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -369,15 +369,11 @@ let isFpTy g ty = /// decimal or decimal<_> let isDecimalTy g ty = - typeEquivAux EraseMeasures g g.decimal_ty ty + typeEquivAux EraseMeasures g g.decimal_ty ty -let IsNonDecimalNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty +let IsNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty || isDecimalTy g ty -let IsNumericOrIntegralEnumType g ty = IsNonDecimalNumericOrIntegralEnumType g ty || isDecimalTy g ty - -let IsNonDecimalNumericType g ty = isIntegerTy g ty || isFpTy g ty - -let IsNumericType g ty = IsNonDecimalNumericType g ty || isDecimalTy g ty +let IsNumericType g ty = isIntegerTy g ty || isFpTy g ty || isDecimalTy g ty let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g ty || isBoolTy g ty @@ -1442,22 +1438,9 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload | _, _, false, "op_Explicit", [argty] when (// The input type. - (IsNonDecimalNumericOrIntegralEnumType g argty || isStringTy g argty || isCharTy g argty) && - // The output type - (IsNonDecimalNumericOrIntegralEnumType g rty || isCharTy g rty) && - // Exclusion: IntPtr and UIntPtr do not support .Parse() from string - not (isStringTy g argty && isNativeIntegerTy g rty) && - // Exclusion: No conversion from char to decimal - not (isCharTy g argty && isDecimalTy g rty)) -> - - return TTraitBuiltIn - - - | _, _, false, "op_Explicit", [argty] - when (// The input type. - (IsNumericOrIntegralEnumType g argty || isStringTy g argty) && + (IsNumericOrIntegralEnumType g argty || isStringTy g argty || isCharTy g argty) && // The output type - (isDecimalTy g rty)) -> + (IsNumericOrIntegralEnumType g rty || isCharTy g rty)) -> return TTraitBuiltIn diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 2b0c6e4b578..8905d5fcf2e 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3014,6 +3014,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u" (convPrim<_,float> value) : unativeint #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u" (convPrim<_,float32> value) : unativeint #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : unativeint #) + elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.u" (Decimal.op_Explicit (convPrim<_,decimal> value) : uint64) #) elif typeeq<'T, string> then convPrim<_,'U> (ParseUIntPtr (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, nativeint> then @@ -3030,6 +3031,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i" (convPrim<_,float> value) : nativeint #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i" (convPrim<_,float32> value) : nativeint #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : nativeint #) + elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.i" (Decimal.op_Explicit (convPrim<_,decimal> value) : int64) #) elif typeeq<'T, string> then convPrim<_,'U> (ParseIntPtr (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, char> then @@ -3046,6 +3048,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float> value) : char #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float32> value) : char #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u2" (convPrim<_,char> value) : char #) + elif typeeq<'T, decimal> then convPrim<_,'U> (Decimal.op_Explicit (convPrim<_,decimal> value) : char) elif typeeq<'T, string> then convPrim<_,'U> (System.Char.Parse (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, decimal> then @@ -3061,7 +3064,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, unativeint> then convPrim<_,'U> (Convert.ToDecimal (# "conv.u8" (convPrim<_,unativeint> value) : uint64 #)) elif typeeq<'T, float> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float> value)) elif typeeq<'T, float32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float32> value)) - elif typeeq<'T, char> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,char> value)) + elif typeeq<'T, char> then convPrim<_,'U> (Decimal.op_Implicit (convPrim<_,char> value)) elif typeeq<'T, decimal> then convPrim<'T,'U> value elif typeeq<'T, string> then convPrim<_,'U> (Decimal.Parse(convPrim<_,string> value, NumberStyles.Float,CultureInfo.InvariantCulture)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value @@ -4456,6 +4459,7 @@ namespace Microsoft.FSharp.Core 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 : char = (System.Decimal.op_Implicit ((# "" value : char #))) when ^T : unativeint = (System.Convert.ToDecimal(uint64 (# "" value : unativeint #))) when ^T : byte = (System.Convert.ToDecimal((# "" value : byte #))) when ^T : decimal = (# "" value : decimal #) @@ -4483,6 +4487,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : unativeint #) when ^T : unativeint = (# "" value : unativeint #) when ^T : byte = (# "conv.u" value : unativeint #) + when ^T : decimal = (# "conv.u" (uint64 value) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -4507,6 +4512,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : nativeint #) when ^T : unativeint = (# "" value : nativeint #) when ^T : byte = (# "conv.i" value : nativeint #) + when ^T : decimal = (# "conv.i" (Convert.ToInt64 value) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) [] diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index 8b31dc1dc55..befb7b73ea8 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -3659,6 +3659,14 @@ module Optimiations = begin let _ = check "opt.oi20c77qc" ('a' + '\025') ('z') let _ = check "opt.oi20c77wc" ('z' - '\025') ('a') + let _ = check "opt.oi20c77ec" (nativeint -3m) (-3n) + let _ = check "opt.oi20c77rc" (nativeint 3m) (3n) + let _ = check "opt.oi20c77tc" (unativeint 3m) (3un) + let _ = check "opt.oi20c77yc" (char 65535m) ('\uFFFF') + let _ = check "opt.oi20c77uc" (decimal '\uFFFF') (65535m) + let _ = check "opt.oi20c77ic" (nativeint "3") (3n) + let _ = check "opt.oi20c77oc" (nativeint "-3") (-3n) + let _ = check "opt.oi20c77pc" (unativeint "3") (3un) end From d6efaf829cd8fa0077c980adea3efaceebf5b546 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 18:37:49 +0800 Subject: [PATCH 41/78] Checked --- src/fsharp/FSharp.Core/prim-types.fs | 4 +++- tests/fsharp/core/libtest/test.fsx | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 8905d5fcf2e..c5829e9e152 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -4487,7 +4487,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : unativeint #) when ^T : unativeint = (# "" value : unativeint #) when ^T : byte = (# "conv.u" value : unativeint #) - when ^T : decimal = (# "conv.u" (uint64 value) : unativeint #) + when ^T : decimal = (# "conv.u" (Convert.ToUInt64 value) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -5147,6 +5147,7 @@ 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 #) + when ^T : decimal = (# "conv.ovf.u.un" (Convert.ToUInt64 value) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -5167,6 +5168,7 @@ 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 #) + when ^T : decimal = (# "conv.ovf.i.un" (Convert.ToInt64 value) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) module OperatorIntrinsics = diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index befb7b73ea8..3a9f5420959 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -3667,6 +3667,13 @@ module Optimiations = begin let _ = check "opt.oi20c77ic" (nativeint "3") (3n) let _ = check "opt.oi20c77oc" (nativeint "-3") (-3n) let _ = check "opt.oi20c77pc" (unativeint "3") (3un) + let _ = check "opt.oi20c77ac" (Checked.nativeint -3m) (-3n) + let _ = check "opt.oi20c77sc" (Checked.nativeint 3m) (3n) + let _ = check "opt.oi20c77dc" (Checked.unativeint 3m) (3un) + let _ = check "opt.oi20c77fc" (Checked.char 65535m) ('\uFFFF') + let _ = check "opt.oi20c77gc" (Checked.nativeint "3") (3n) + let _ = check "opt.oi20c77hc" (Checked.nativeint "-3") (-3n) + let _ = check "opt.oi20c77jc" (Checked.unativeint "3") (3un) end From 2acc8b5941e1fab0902ea6e809e8b5fc9f1c51d5 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 18:45:17 +0800 Subject: [PATCH 42/78] Check correctly --- tests/fsharp/core/libtest/test.fsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index 3a9f5420959..0b624ac7526 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -3667,13 +3667,15 @@ module Optimiations = begin let _ = check "opt.oi20c77ic" (nativeint "3") (3n) let _ = check "opt.oi20c77oc" (nativeint "-3") (-3n) let _ = check "opt.oi20c77pc" (unativeint "3") (3un) - let _ = check "opt.oi20c77ac" (Checked.nativeint -3m) (-3n) - let _ = check "opt.oi20c77sc" (Checked.nativeint 3m) (3n) - let _ = check "opt.oi20c77dc" (Checked.unativeint 3m) (3un) - let _ = check "opt.oi20c77fc" (Checked.char 65535m) ('\uFFFF') - let _ = check "opt.oi20c77gc" (Checked.nativeint "3") (3n) - let _ = check "opt.oi20c77hc" (Checked.nativeint "-3") (-3n) - let _ = check "opt.oi20c77jc" (Checked.unativeint "3") (3un) + let _ = check "opt.oi20c77ac" (Checked.(+) 'a' '\025') ('z') + let _ = check "opt.oi20c77sc" (Checked.(-) 'z' '\025') ('a') + let _ = check "opt.oi20c77dc" (Checked.nativeint -3m) (-3n) + let _ = check "opt.oi20c77fc" (Checked.nativeint 3m) (3n) + let _ = check "opt.oi20c77gc" (Checked.unativeint 3m) (3un) + let _ = check "opt.oi20c77hc" (Checked.char 65535m) ('\uFFFF') + let _ = check "opt.oi20c77jc" (Checked.nativeint "3") (3n) + let _ = check "opt.oi20c77kc" (Checked.nativeint "-3") (-3n) + let _ = check "opt.oi20c77lc" (Checked.unativeint "3") (3un) end From 365ca44272ed2a6cb2fe7edd88617dc3ed1c817a Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 19:12:27 +0800 Subject: [PATCH 43/78] Equality enhanced --- src/fsharp/FSharp.Core/Linq.fs | 187 +++++++++++---------- tests/fsharp/core/quotes/test.fsx | 262 ++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+), 94 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 56b50727424..a9a7bfc701f 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -362,101 +362,101 @@ module LeafExpressionConverter = Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr | GenericEqualityQ (_, _, [x1; x2]) - | EqualsQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Equal - | NotEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.NotEqual - | GreaterQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan - | GreaterEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual - | LessQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan - | LessEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual + | EqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) + | NotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) + | GreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) + | GreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) + | LessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) + | LessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Equal - | StaticNotEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.NotEqual - | StaticGreaterQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual - | StaticLessQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan - | StaticLessEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual - - | NullableEqualsQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Equal - | NullableNotEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.NotEqual - | NullableGreaterQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.GreaterThan - | NullableGreaterEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.GreaterThanOrEqual - | NullableLessQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.LessThan - | NullableLessEqQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.LessThanOrEqual - - | EqualsNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Equal - | NotEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.NotEqual - | GreaterNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.GreaterThan - | GreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.GreaterThanOrEqual - | LessNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.LessThan - | LessEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.LessThanOrEqual - - | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Equal - | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.NotEqual - | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThan - | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.GreaterThanOrEqual - | NullableLessNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThan - | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LessThanOrEqual + | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) + | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) + | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) + | StaticLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) + | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) + + | NullableEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) + | NullableNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) + | NullableGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) + | NullableGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) + | NullableLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) + | NullableLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) + + | EqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) + | NotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) + | GreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) + | GreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) + | LessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) + | LessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) + + | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) + | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) + | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) + | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) + | NullableLessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) + | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) // 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 (_, _, [x]) -> transUnaryOpFallback inp env x Expression.Negate <| methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x) - | PlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | MinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | MultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | DivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | ModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - - | ShiftLeftQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.LeftShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y) - | ShiftRightQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.RightShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y) - | BitwiseAndQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.And <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y) - | BitwiseOrQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Or <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y) - | BitwiseXorQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y) - | BitwiseNotQ (_, _, [x]) -> transUnaryOpFallback inp env x Expression.Not <| methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x) + | NegQ (_, _, [x]) -> transUnaryOp inp env x Expression.Negate <| methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x) + | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | DivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | ModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + + | ShiftLeftQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LeftShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y) + | ShiftRightQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.RightShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y) + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y) + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y) + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y) + | BitwiseNotQ (_, _, [x]) -> transUnaryOp inp env x Expression.Not <| methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x) - | CheckedNeg (_, _, [x]) -> transUnaryOpFallback inp env x Expression.NegateChecked <| methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x) - | CheckedPlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.AddChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y) - | CheckedMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y) - | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y) + | CheckedNeg (_, _, [x]) -> transUnaryOp inp env x Expression.NegateChecked <| methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x) + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y) + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y) + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y) - | NullablePlusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | PlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | NullablePlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | PlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | NullableMinusQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | MinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | NullableMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | MinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | NullableDivideQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | DivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | NullableDivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | DivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | NullableModuloQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 true Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env true x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOpFallback inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - - | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConvFallback inp env false x - | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConvFallback inp env false x - | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) -> transConvFallback inp env false x - | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) -> transConvFallback inp env false x - | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x - - | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) -> transConvFallback inp env false x - | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) -> transConvFallback inp env false x - | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) -> transConvFallback inp env false x - | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) -> transConvFallback inp env false x - | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env false x - - | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) -> transConvFallback inp env true x - | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) -> transConvFallback inp env true x - | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) -> transConvFallback inp env true x - | CheckedConvUIntPtrQ (_, _, [x]) -> transConvFallback inp env true x + | NullableModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + + | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConv inp env false x + | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConv inp env false x + | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) -> transConv inp env false x + | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) -> transConv inp env false x + | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) -> transConv inp env false x + + | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) -> transConv inp env false x + | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) -> transConv inp env false x + | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) -> transConv inp env false x + | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) -> transConv inp env false x + | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConv inp env false x + + | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) -> transConv inp env true x + | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) -> transConv inp env true x + | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) -> transConv inp env true x + | CheckedConvUIntPtrQ (_, _, [x]) -> transConv inp env true x | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> Expression.ArrayIndex(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr @@ -633,7 +633,7 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) - and transUnaryOpFallback inp env x (exprErasedConstructor: _ * _ -> _) fallback = + and transUnaryOp inp env x (exprErasedConstructor: _ * _ -> _) fallback = let e = ConvExprToLinqInContext env x try exprErasedConstructor(e, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. @@ -641,21 +641,20 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) |> asExpr - and transBinOp _inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ -> _) = + and transBinOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = 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 transBinOpFallback inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = - transBinOp inp env addConvertLeft x1 x2 addConvertRight (fun (e1, e2) -> - try exprErasedConstructor(e1, e2, null) with _ -> - // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t - let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo - exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) - ) - and transConvFallback (inp: Expr) env isChecked x = + try exprErasedConstructor(e1, e2, null) with _ -> + // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) + |> asExpr + and transBoolOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) fallback = + transBinOp inp env addConvertLeft x1 x2 addConvertRight (fun (left, right, methodInfo) -> exprErasedConstructor(left, right, false, methodInfo)) fallback + and transConv (inp: Expr) env isChecked x = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert try exprErasedConstructor(e, inp.Type, null) with _ -> diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 14019e2eb50..7d56a0c40d0 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3622,6 +3622,7 @@ module WitnessTests = <@@ 3. = 3. @@>, box true <@@ 3m = 3m @@>, box true <@@ "3" = "3" @@>, box true + <@@ [3] = [3] @@>, box true <@@ 3y <> 3y @@>, box false <@@ 3uy <> 3uy @@>, box false @@ -3638,6 +3639,75 @@ module WitnessTests = <@@ 3. <> 3. @@>, box false <@@ 3m <> 3m @@>, box false <@@ "3" <> "3" @@>, box false + <@@ [3] <> [3] @@>, box true + + <@@ 3y <= 3y @@>, box true + <@@ 3uy <= 3uy @@>, box true + <@@ 3s <= 3s @@>, box true + <@@ 3us <= 3us @@>, box true + <@@ 3 <= 3 @@>, box true + <@@ 3u <= 3u @@>, box true + <@@ 3L <= 3L @@>, box true + <@@ 3UL <= 3UL @@>, box true + <@@ '3' <= '3' @@>, box true + <@@ LanguagePrimitives.GenericOne <= LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne <= LanguagePrimitives.GenericOne @@>, box true + <@@ 3f <= 3f @@>, box true + <@@ 3. <= 3. @@>, box true + <@@ 3m <= 3m @@>, box true + <@@ "3" <= "3" @@>, box true + <@@ [3] <= [3] @@>, box true + + <@@ 3y < 3y @@>, box false + <@@ 3uy < 3uy @@>, box false + <@@ 3s < 3s @@>, box false + <@@ 3us < 3us @@>, box false + <@@ 3 < 3 @@>, box false + <@@ 3u < 3u @@>, box false + <@@ 3L < 3L @@>, box false + <@@ 3UL < 3UL @@>, box false + <@@ '3' < '3' @@>, box false + <@@ LanguagePrimitives.GenericOne < LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne < LanguagePrimitives.GenericOne @@>, box false + <@@ 3f < 3f @@>, box false + <@@ 3. < 3. @@>, box false + <@@ 3m < 3m @@>, box false + <@@ "3" < "3" @@>, box false + <@@ [3] < [3] @@>, box false + + <@@ 3y >= 3y @@>, box true + <@@ 3uy >= 3uy @@>, box true + <@@ 3s >= 3s @@>, box true + <@@ 3us >= 3us @@>, box true + <@@ 3 >= 3 @@>, box true + <@@ 3u >= 3u @@>, box true + <@@ 3L >= 3L @@>, box true + <@@ 3UL >= 3UL @@>, box true + <@@ '3' >= '3' @@>, box true + <@@ LanguagePrimitives.GenericOne >= LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne >= LanguagePrimitives.GenericOne @@>, box true + <@@ 3f >= 3f @@>, box true + <@@ 3. >= 3. @@>, box true + <@@ 3m >= 3m @@>, box true + <@@ "3" >= "3" @@>, box true + <@@ [3] >= [3] @@>, box true + + <@@ 3y > 3y @@>, box false + <@@ 3uy > 3uy @@>, box false + <@@ 3s > 3s @@>, box false + <@@ 3us > 3us @@>, box false + <@@ 3 > 3 @@>, box false + <@@ 3u > 3u @@>, box false + <@@ 3L > 3L @@>, box false + <@@ 3UL > 3UL @@>, box false + <@@ '3' > '3' @@>, box false + <@@ LanguagePrimitives.GenericOne > LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne > LanguagePrimitives.GenericOne @@>, box false + <@@ 3f > 3f @@>, box false + <@@ 3. > 3. @@>, box false + <@@ 3m > 3m @@>, box false + <@@ "3" > "3" @@>, box false + <@@ [3] > [3] @@>, box false <@@ byte 3uy @@>, box 3uy <@@ byte 3y @@>, box 3uy @@ -4585,6 +4655,198 @@ module WitnessTests = <@@ Nullable<_> 3f ?<>? Nullable<_> 3f @@>, box false <@@ Nullable<_> 3. ?<>? Nullable<_> 3. @@>, box false <@@ Nullable<_> 3m ?<>? Nullable<_> 3m @@>, box false + + <@@ Nullable<_> 3y ?<= 3y @@>, box true + <@@ Nullable<_> 3uy ?<= 3uy @@>, box true + <@@ Nullable<_> 3s ?<= 3s @@>, box true + <@@ Nullable<_> 3us ?<= 3us @@>, box true + <@@ Nullable<_> 3 ?<= 3 @@>, box true + <@@ Nullable<_> 3u ?<= 3u @@>, box true + <@@ Nullable<_> 3L ?<= 3L @@>, box true + <@@ Nullable<_> 3UL ?<= 3UL @@>, box true + <@@ Nullable<_> '3' ?<= '3' @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<= LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<= LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> 3f ?<= 3f @@>, box true + <@@ Nullable<_> 3. ?<= 3. @@>, box true + <@@ Nullable<_> 3m ?<= 3m @@>, box true + <@@ Nullable<_> "3" ?<= "3" @@>, box true + + <@@ 3y <=? Nullable<_> 3y @@>, box true + <@@ 3uy <=? Nullable<_> 3uy @@>, box true + <@@ 3s <=? Nullable<_> 3s @@>, box true + <@@ 3us <=? Nullable<_> 3us @@>, box true + <@@ 3 <=? Nullable<_> 3 @@>, box true + <@@ 3u <=? Nullable<_> 3u @@>, box true + <@@ 3L <=? Nullable<_> 3L @@>, box true + <@@ 3UL <=? Nullable<_> 3UL @@>, box true + <@@ '3' <=? Nullable<_> '3' @@>, box true + <@@ LanguagePrimitives.GenericOne <=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne <=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ 3f <=? Nullable<_> 3f @@>, box true + <@@ 3. <=? Nullable<_> 3. @@>, box true + <@@ 3m <=? Nullable<_> 3m @@>, box true + <@@ "3" <=? Nullable<_> "3" @@>, box true + + <@@ Nullable<_> 3y ?<=? Nullable<_> 3y @@>, box true + <@@ Nullable<_> 3uy ?<=? Nullable<_> 3uy @@>, box true + <@@ Nullable<_> 3s ?<=? Nullable<_> 3s @@>, box true + <@@ Nullable<_> 3us ?<=? Nullable<_> 3us @@>, box true + <@@ Nullable<_> 3 ?<=? Nullable<_> 3 @@>, box true + <@@ Nullable<_> 3u ?<=? Nullable<_> 3u @@>, box true + <@@ Nullable<_> 3L ?<=? Nullable<_> 3L @@>, box true + <@@ Nullable<_> 3UL ?<=? Nullable<_> 3UL @@>, box true + <@@ Nullable<_> '3' ?<=? Nullable<_> '3' @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?<=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> 3f ?<=? Nullable<_> 3f @@>, box true + <@@ Nullable<_> 3. ?<=? Nullable<_> 3. @@>, box true + <@@ Nullable<_> 3m ?<=? Nullable<_> 3m @@>, box true + <@@ Nullable<_> "3" ?<=? Nullable<_> "3" @@>, box true + + <@@ Nullable<_> 3y ?< 3y @@>, box false + <@@ Nullable<_> 3uy ?< 3uy @@>, box false + <@@ Nullable<_> 3s ?< 3s @@>, box false + <@@ Nullable<_> 3us ?< 3us @@>, box false + <@@ Nullable<_> 3 ?< 3 @@>, box false + <@@ Nullable<_> 3u ?< 3u @@>, box false + <@@ Nullable<_> 3L ?< 3L @@>, box false + <@@ Nullable<_> 3UL ?< 3UL @@>, box false + <@@ Nullable<_> '3' ?< '3' @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?< LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?< LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> 3f ?< 3f @@>, box false + <@@ Nullable<_> 3. ?< 3. @@>, box false + <@@ Nullable<_> 3m ?< 3m @@>, box false + <@@ Nullable<_> "3" ?< "3" @@>, box false + + <@@ 3y 3y @@>, box false + <@@ 3uy 3uy @@>, box false + <@@ 3s 3s @@>, box false + <@@ 3us 3us @@>, box false + <@@ 3 3 @@>, box false + <@@ 3u 3u @@>, box false + <@@ 3L 3L @@>, box false + <@@ 3UL 3UL @@>, box false + <@@ '3' '3' @@>, box false + <@@ LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ 3f 3f @@>, box false + <@@ 3. 3. @@>, box false + <@@ 3m 3m @@>, box false + <@@ "3" "3" @@>, box false + + <@@ Nullable<_> 3y ? 3y @@>, box false + <@@ Nullable<_> 3uy ? 3uy @@>, box false + <@@ Nullable<_> 3s ? 3s @@>, box false + <@@ Nullable<_> 3us ? 3us @@>, box false + <@@ Nullable<_> 3 ? 3 @@>, box false + <@@ Nullable<_> 3u ? 3u @@>, box false + <@@ Nullable<_> 3L ? 3L @@>, box false + <@@ Nullable<_> 3UL ? 3UL @@>, box false + <@@ Nullable<_> '3' ? '3' @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ? LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ? LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> 3f ? 3f @@>, box false + <@@ Nullable<_> 3. ? 3. @@>, box false + <@@ Nullable<_> 3m ? 3m @@>, box false + <@@ Nullable<_> "3" ? "3" @@>, box false + + <@@ Nullable<_> 3y ?>= 3y @@>, box true + <@@ Nullable<_> 3uy ?>= 3uy @@>, box true + <@@ Nullable<_> 3s ?>= 3s @@>, box true + <@@ Nullable<_> 3us ?>= 3us @@>, box true + <@@ Nullable<_> 3 ?>= 3 @@>, box true + <@@ Nullable<_> 3u ?>= 3u @@>, box true + <@@ Nullable<_> 3L ?>= 3L @@>, box true + <@@ Nullable<_> 3UL ?>= 3UL @@>, box true + <@@ Nullable<_> '3' ?>= '3' @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?>= LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?>= LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> 3f ?>= 3f @@>, box true + <@@ Nullable<_> 3. ?>= 3. @@>, box true + <@@ Nullable<_> 3m ?>= 3m @@>, box true + <@@ Nullable<_> "3" ?>= "3" @@>, box true + + <@@ 3y >=? Nullable<_> 3y @@>, box true + <@@ 3uy >=? Nullable<_> 3uy @@>, box true + <@@ 3s >=? Nullable<_> 3s @@>, box true + <@@ 3us >=? Nullable<_> 3us @@>, box true + <@@ 3 >=? Nullable<_> 3 @@>, box true + <@@ 3u >=? Nullable<_> 3u @@>, box true + <@@ 3L >=? Nullable<_> 3L @@>, box true + <@@ 3UL >=? Nullable<_> 3UL @@>, box true + <@@ '3' >=? Nullable<_> '3' @@>, box true + <@@ LanguagePrimitives.GenericOne >=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne >=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ 3f >=? Nullable<_> 3f @@>, box true + <@@ 3. >=? Nullable<_> 3. @@>, box true + <@@ 3m >=? Nullable<_> 3m @@>, box true + <@@ "3" >=? Nullable<_> "3" @@>, box true + + <@@ Nullable<_> 3y ?>=? Nullable<_> 3y @@>, box true + <@@ Nullable<_> 3uy ?>=? Nullable<_> 3uy @@>, box true + <@@ Nullable<_> 3s ?>=? Nullable<_> 3s @@>, box true + <@@ Nullable<_> 3us ?>=? Nullable<_> 3us @@>, box true + <@@ Nullable<_> 3 ?>=? Nullable<_> 3 @@>, box true + <@@ Nullable<_> 3u ?>=? Nullable<_> 3u @@>, box true + <@@ Nullable<_> 3L ?>=? Nullable<_> 3L @@>, box true + <@@ Nullable<_> 3UL ?>=? Nullable<_> 3UL @@>, box true + <@@ Nullable<_> '3' ?>=? Nullable<_> '3' @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?>=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> LanguagePrimitives.GenericOne ?>=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true + <@@ Nullable<_> 3f ?>=? Nullable<_> 3f @@>, box true + <@@ Nullable<_> 3. ?>=? Nullable<_> 3. @@>, box true + <@@ Nullable<_> 3m ?>=? Nullable<_> 3m @@>, box true + <@@ Nullable<_> "3" ?>=? Nullable<_> "3" @@>, box true + + <@@ Nullable<_> 3y ?> 3y @@>, box false + <@@ Nullable<_> 3uy ?> 3uy @@>, box false + <@@ Nullable<_> 3s ?> 3s @@>, box false + <@@ Nullable<_> 3us ?> 3us @@>, box false + <@@ Nullable<_> 3 ?> 3 @@>, box false + <@@ Nullable<_> 3u ?> 3u @@>, box false + <@@ Nullable<_> 3L ?> 3L @@>, box false + <@@ Nullable<_> 3UL ?> 3UL @@>, box false + <@@ Nullable<_> '3' ?> '3' @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> 3f ?> 3f @@>, box false + <@@ Nullable<_> 3. ?> 3. @@>, box false + <@@ Nullable<_> 3m ?> 3m @@>, box false + <@@ Nullable<_> "3" ?> "3" @@>, box false + + <@@ 3y >? Nullable<_> 3y @@>, box false + <@@ 3uy >? Nullable<_> 3uy @@>, box false + <@@ 3s >? Nullable<_> 3s @@>, box false + <@@ 3us >? Nullable<_> 3us @@>, box false + <@@ 3 >? Nullable<_> 3 @@>, box false + <@@ 3u >? Nullable<_> 3u @@>, box false + <@@ 3L >? Nullable<_> 3L @@>, box false + <@@ 3UL >? Nullable<_> 3UL @@>, box false + <@@ '3' >? Nullable<_> '3' @@>, box false + <@@ LanguagePrimitives.GenericOne >? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne >? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ 3f >? Nullable<_> 3f @@>, box false + <@@ 3. >? Nullable<_> 3. @@>, box false + <@@ 3m >? Nullable<_> 3m @@>, box false + <@@ "3" >? Nullable<_> "3" @@>, box false + + <@@ Nullable<_> 3y ?>? Nullable<_> 3y @@>, box false + <@@ Nullable<_> 3uy ?>? Nullable<_> 3uy @@>, box false + <@@ Nullable<_> 3s ?>? Nullable<_> 3s @@>, box false + <@@ Nullable<_> 3us ?>? Nullable<_> 3us @@>, box false + <@@ Nullable<_> 3 ?>? Nullable<_> 3 @@>, box false + <@@ Nullable<_> 3u ?>? Nullable<_> 3u @@>, box false + <@@ Nullable<_> 3L ?>? Nullable<_> 3L @@>, box false + <@@ Nullable<_> 3UL ?>? Nullable<_> 3UL @@>, box false + <@@ Nullable<_> '3' ?>? Nullable<_> '3' @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?>? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> LanguagePrimitives.GenericOne ?>? Nullable<_> LanguagePrimitives.GenericOne @@>, box false + <@@ Nullable<_> 3f ?>? Nullable<_> 3f @@>, box false + <@@ Nullable<_> 3. ?>? Nullable<_> 3. @@>, box false + <@@ Nullable<_> 3m ?>? Nullable<_> 3m @@>, box false + <@@ Nullable<_> "3" ?>? Nullable<_> "3" @@>, box false |] tests |> Array.map (fun (test, eval) -> From 598babf42bbc0d83577857f15bee58f82e5025dd Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 19:18:03 +0800 Subject: [PATCH 44/78] Quick fixes --- tests/fsharp/core/quotes/test.fsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 7d56a0c40d0..c79915647d0 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3639,7 +3639,7 @@ module WitnessTests = <@@ 3. <> 3. @@>, box false <@@ 3m <> 3m @@>, box false <@@ "3" <> "3" @@>, box false - <@@ [3] <> [3] @@>, box true + <@@ [3] <> [3] @@>, box false <@@ 3y <= 3y @@>, box true <@@ 3uy <= 3uy @@>, box true @@ -4670,7 +4670,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?<= 3f @@>, box true <@@ Nullable<_> 3. ?<= 3. @@>, box true <@@ Nullable<_> 3m ?<= 3m @@>, box true - <@@ Nullable<_> "3" ?<= "3" @@>, box true <@@ 3y <=? Nullable<_> 3y @@>, box true <@@ 3uy <=? Nullable<_> 3uy @@>, box true @@ -4686,7 +4685,6 @@ module WitnessTests = <@@ 3f <=? Nullable<_> 3f @@>, box true <@@ 3. <=? Nullable<_> 3. @@>, box true <@@ 3m <=? Nullable<_> 3m @@>, box true - <@@ "3" <=? Nullable<_> "3" @@>, box true <@@ Nullable<_> 3y ?<=? Nullable<_> 3y @@>, box true <@@ Nullable<_> 3uy ?<=? Nullable<_> 3uy @@>, box true @@ -4702,7 +4700,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?<=? Nullable<_> 3f @@>, box true <@@ Nullable<_> 3. ?<=? Nullable<_> 3. @@>, box true <@@ Nullable<_> 3m ?<=? Nullable<_> 3m @@>, box true - <@@ Nullable<_> "3" ?<=? Nullable<_> "3" @@>, box true <@@ Nullable<_> 3y ?< 3y @@>, box false <@@ Nullable<_> 3uy ?< 3uy @@>, box false @@ -4718,7 +4715,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?< 3f @@>, box false <@@ Nullable<_> 3. ?< 3. @@>, box false <@@ Nullable<_> 3m ?< 3m @@>, box false - <@@ Nullable<_> "3" ?< "3" @@>, box false <@@ 3y 3y @@>, box false <@@ 3uy 3uy @@>, box false @@ -4734,7 +4730,6 @@ module WitnessTests = <@@ 3f 3f @@>, box false <@@ 3. 3. @@>, box false <@@ 3m 3m @@>, box false - <@@ "3" "3" @@>, box false <@@ Nullable<_> 3y ? 3y @@>, box false <@@ Nullable<_> 3uy ? 3uy @@>, box false @@ -4750,7 +4745,6 @@ module WitnessTests = <@@ Nullable<_> 3f ? 3f @@>, box false <@@ Nullable<_> 3. ? 3. @@>, box false <@@ Nullable<_> 3m ? 3m @@>, box false - <@@ Nullable<_> "3" ? "3" @@>, box false <@@ Nullable<_> 3y ?>= 3y @@>, box true <@@ Nullable<_> 3uy ?>= 3uy @@>, box true @@ -4766,7 +4760,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?>= 3f @@>, box true <@@ Nullable<_> 3. ?>= 3. @@>, box true <@@ Nullable<_> 3m ?>= 3m @@>, box true - <@@ Nullable<_> "3" ?>= "3" @@>, box true <@@ 3y >=? Nullable<_> 3y @@>, box true <@@ 3uy >=? Nullable<_> 3uy @@>, box true @@ -4782,7 +4775,6 @@ module WitnessTests = <@@ 3f >=? Nullable<_> 3f @@>, box true <@@ 3. >=? Nullable<_> 3. @@>, box true <@@ 3m >=? Nullable<_> 3m @@>, box true - <@@ "3" >=? Nullable<_> "3" @@>, box true <@@ Nullable<_> 3y ?>=? Nullable<_> 3y @@>, box true <@@ Nullable<_> 3uy ?>=? Nullable<_> 3uy @@>, box true @@ -4798,7 +4790,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?>=? Nullable<_> 3f @@>, box true <@@ Nullable<_> 3. ?>=? Nullable<_> 3. @@>, box true <@@ Nullable<_> 3m ?>=? Nullable<_> 3m @@>, box true - <@@ Nullable<_> "3" ?>=? Nullable<_> "3" @@>, box true <@@ Nullable<_> 3y ?> 3y @@>, box false <@@ Nullable<_> 3uy ?> 3uy @@>, box false @@ -4814,7 +4805,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?> 3f @@>, box false <@@ Nullable<_> 3. ?> 3. @@>, box false <@@ Nullable<_> 3m ?> 3m @@>, box false - <@@ Nullable<_> "3" ?> "3" @@>, box false <@@ 3y >? Nullable<_> 3y @@>, box false <@@ 3uy >? Nullable<_> 3uy @@>, box false @@ -4830,7 +4820,6 @@ module WitnessTests = <@@ 3f >? Nullable<_> 3f @@>, box false <@@ 3. >? Nullable<_> 3. @@>, box false <@@ 3m >? Nullable<_> 3m @@>, box false - <@@ "3" >? Nullable<_> "3" @@>, box false <@@ Nullable<_> 3y ?>? Nullable<_> 3y @@>, box false <@@ Nullable<_> 3uy ?>? Nullable<_> 3uy @@>, box false @@ -4846,7 +4835,6 @@ module WitnessTests = <@@ Nullable<_> 3f ?>? Nullable<_> 3f @@>, box false <@@ Nullable<_> 3. ?>? Nullable<_> 3. @@>, box false <@@ Nullable<_> 3m ?>? Nullable<_> 3m @@>, box false - <@@ Nullable<_> "3" ?>? Nullable<_> "3" @@>, box false |] tests |> Array.map (fun (test, eval) -> From 3f77797f552593695857ea00cd2443a3b31a2578 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 21:00:30 +0800 Subject: [PATCH 45/78] Solved it --- src/fsharp/ConstraintSolver.fs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index c06db5feece..f5bf7fb72a5 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -371,9 +371,13 @@ let isFpTy g ty = let isDecimalTy g ty = typeEquivAux EraseMeasures g g.decimal_ty ty -let IsNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty || isDecimalTy g ty +let IsNonDecimalNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty -let IsNumericType g ty = isIntegerTy g ty || isFpTy g ty || isDecimalTy g ty +let IsNumericOrIntegralEnumType g ty = IsNonDecimalNumericOrIntegralEnumType g ty || isDecimalTy g ty + +let IsNonDecimalNumericType g ty = isIntegerTy g ty || isFpTy g ty + +let IsNumericType g ty = IsNonDecimalNumericType g ty || isDecimalTy g ty let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g ty || isBoolTy g ty @@ -1436,13 +1440,31 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace rty argty return TTraitBuiltIn + // Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in | _, _, false, "op_Explicit", [argty] when (// The input type. - (IsNumericOrIntegralEnumType g argty || isStringTy g argty || isCharTy g argty) && + (IsNonDecimalNumericOrIntegralEnumType g argty || isStringTy g argty || isCharTy g argty) && // The output type - (IsNumericOrIntegralEnumType g rty || isCharTy g rty)) -> + (IsNonDecimalNumericOrIntegralEnumType g rty || isCharTy g rty)) -> return TTraitBuiltIn + + // Conversions from non-decimal numbers / strings to decimals are built-in + | _, _, false, "op_Explicit", [argty] + when (// The input type. + (IsNumericOrIntegralEnumType g argty || isStringTy g argty) && + // The output type + (isDecimalTy g rty)) -> + return TTraitBuiltIn + + // Conversions from decimal numbers to native numbers are built-in + // The rest of decimal conversions are handled via op_Explicit lookup (which also looks for op_Implicit) + | _, _, false, "op_Explicit", [argty] + when (// The input type. + (isDecimalTy g argty) && + // The output type + (isNativeIntegerTy g rty)) -> + return TTraitBuiltIn | [], _, false, "Pow", [argty1; argty2] when isFpTy g argty1 -> From 61420dc1875165de7ffb8e15c36e3951817b634c Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 5 Jul 2021 21:06:44 +0800 Subject: [PATCH 46/78] Remove unused branch --- src/fsharp/ConstraintSolver.fs | 4 ++-- src/fsharp/FSharp.Core/prim-types.fs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index f5bf7fb72a5..1fdd56c3e13 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1449,7 +1449,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload return TTraitBuiltIn - // Conversions from non-decimal numbers / strings to decimals are built-in + // Conversions from (including decimal) numbers / strings to decimals are built-in | _, _, false, "op_Explicit", [argty] when (// The input type. (IsNumericOrIntegralEnumType g argty || isStringTy g argty) && @@ -1457,7 +1457,7 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload (isDecimalTy g rty)) -> return TTraitBuiltIn - // Conversions from decimal numbers to native numbers are built-in + // Conversions from decimal numbers to native integers are built-in // The rest of decimal conversions are handled via op_Explicit lookup (which also looks for op_Implicit) | _, _, false, "op_Explicit", [argty] when (// The input type. diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index c5829e9e152..61eed4af11a 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -4458,8 +4458,7 @@ namespace Microsoft.FSharp.Core 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 : char = (System.Decimal.op_Implicit ((# "" value : char #))) + 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 #))) when ^T : decimal = (# "" value : decimal #) From 15c028fb0bf424198b41c5b10c789e45a1025b89 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Tue, 6 Jul 2021 00:32:05 +0800 Subject: [PATCH 47/78] Fix char->decimal --- src/fsharp/ConstraintSolver.fs | 6 +++--- src/fsharp/FSharp.Core/prim-types.fs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 1fdd56c3e13..7efd6f403fa 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1449,16 +1449,16 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload return TTraitBuiltIn - // Conversions from (including decimal) numbers / strings to decimals are built-in + // Conversions from (including decimal) numbers / strings / chars to decimals are built-in | _, _, false, "op_Explicit", [argty] when (// The input type. - (IsNumericOrIntegralEnumType g argty || isStringTy g argty) && + (IsNumericOrIntegralEnumType g argty || isStringTy g argty || isCharTy g argty) && // The output type (isDecimalTy g rty)) -> return TTraitBuiltIn // Conversions from decimal numbers to native integers are built-in - // The rest of decimal conversions are handled via op_Explicit lookup (which also looks for op_Implicit) + // The rest of decimal conversions are handled via op_Explicit lookup on System.Decimal (which also looks for op_Implicit) | _, _, false, "op_Explicit", [argty] when (// The input type. (isDecimalTy g argty) && diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 61eed4af11a..fc8570aa5e3 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3064,7 +3064,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, unativeint> then convPrim<_,'U> (Convert.ToDecimal (# "conv.u8" (convPrim<_,unativeint> value) : uint64 #)) elif typeeq<'T, float> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float> value)) elif typeeq<'T, float32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float32> value)) - elif typeeq<'T, char> then convPrim<_,'U> (Decimal.op_Implicit (convPrim<_,char> value)) + elif typeeq<'T, char> then convPrim<_,'U> (Convert.ToDecimal (# "" (convPrim<_,char> value) : uint16 #)) elif typeeq<'T, decimal> then convPrim<'T,'U> value elif typeeq<'T, string> then convPrim<_,'U> (Decimal.Parse(convPrim<_,string> value, NumberStyles.Float,CultureInfo.InvariantCulture)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value @@ -4461,6 +4461,7 @@ namespace Microsoft.FSharp.Core 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 #))) + when ^T : char = (System.Convert.ToDecimal((# "" value : uint16 #))) // Don't use the char overload which unconditionally raises an exception when ^T : decimal = (# "" value : decimal #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> decimal) (value)) From 4213b3e0143cfe3e09191416a1a7210728caa603 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 01:13:46 +0800 Subject: [PATCH 48/78] No <| --- src/fsharp/FSharp.Core/Linq.fs | 130 ++++++++++++++++----------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index a9a7bfc701f..6f807215b91 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -362,84 +362,84 @@ module LeafExpressionConverter = Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr | GenericEqualityQ (_, _, [x1; x2]) - | EqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) - | NotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) - | GreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) - | GreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) - | LessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) - | LessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) + | EqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) + | NotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) + | GreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | GreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | LessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | LessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) - | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) - | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) - | StaticLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) - | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) - - | NullableEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) - | NullableNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) - | NullableGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) - | NullableGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) - | NullableLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) - | NullableLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) - - | EqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) - | NotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) - | GreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) - | GreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) - | LessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) - | LessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) - - | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal <| methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y) - | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y) - | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y) - | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y) - | NullableLessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y) - | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual <| methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y) + | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) + | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) + | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | StaticLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) + + | NullableEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) + | NullableNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) + | NullableGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | NullableGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | NullableLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | NullableLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) + + | EqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) + | NotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) + | GreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | GreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | LessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | LessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) + + | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) + | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) + | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | NullableLessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) // 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 (_, _, [x]) -> transUnaryOp inp env x Expression.Negate <| methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x) - | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | DivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | ModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - - | ShiftLeftQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LeftShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y) - | ShiftRightQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.RightShift <| methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y) - | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y) - | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or <| methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y) - | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr <| methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y) - | BitwiseNotQ (_, _, [x]) -> transUnaryOp inp env x Expression.Not <| methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x) + | NegQ (_, _, [x]) -> transUnaryOp inp env x Expression.Negate (methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x)) + | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | DivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | ModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + + | ShiftLeftQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LeftShift (methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y)) + | ShiftRightQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.RightShift (methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y)) + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y)) + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y)) + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y)) + | BitwiseNotQ (_, _, [x]) -> transUnaryOp inp env x Expression.Not (methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x)) - | CheckedNeg (_, _, [x]) -> transUnaryOp inp env x Expression.NegateChecked <| methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x) - | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y) - | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y) - | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked <| methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y) + | CheckedNeg (_, _, [x]) -> transUnaryOp inp env x Expression.NegateChecked (methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x)) + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y)) + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y)) + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y)) - | NullablePlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | PlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add <| methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y) + | NullablePlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | PlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | NullableMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | MinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract <| methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y) + | NullableMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | MinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply <| methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y) + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | NullableDivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | DivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide <| methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y) + | NullableDivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | DivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | NullableModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo <| methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y) + | NullableModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConv inp env false x | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConv inp env false x From 600941b7e2f7e2d61fe36da555f6d2e27221cb9e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 01:21:52 +0800 Subject: [PATCH 49/78] Fix conversion --- src/fsharp/FSharp.Core/prim-types.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index fc8570aa5e3..84677a9a388 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -5168,7 +5168,7 @@ 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 #) - when ^T : decimal = (# "conv.ovf.i.un" (Convert.ToInt64 value) : unativeint #) + when ^T : decimal = (# "conv.ovf.i" (Convert.ToInt64 value) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) module OperatorIntrinsics = From d7961ce52b996931e189b1b3af522d080afd2b3b Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 01:25:07 +0800 Subject: [PATCH 50/78] Wait wait fix fix --- src/fsharp/FSharp.Core/prim-types.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 84677a9a388..f7360d84cc6 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -5168,7 +5168,7 @@ 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 #) - when ^T : decimal = (# "conv.ovf.i" (Convert.ToInt64 value) : unativeint #) + when ^T : decimal = (# "conv.ovf.i" (Convert.ToInt64 value) : nativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) module OperatorIntrinsics = From 329610144e2930ef36c2a1a386ea9d9964496787 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 01:33:33 +0800 Subject: [PATCH 51/78] Retype it --- src/fsharp/FSharp.Core/prim-types.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index f7360d84cc6..a0cf2c794e5 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -4487,7 +4487,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : unativeint #) when ^T : unativeint = (# "" value : unativeint #) when ^T : byte = (# "conv.u" value : unativeint #) - when ^T : decimal = (# "conv.u" (Convert.ToUInt64 value) : unativeint #) + when ^T : decimal = (# "conv.u" (Convert.ToUInt64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -4512,7 +4512,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : nativeint #) when ^T : unativeint = (# "" value : nativeint #) when ^T : byte = (# "conv.i" value : nativeint #) - when ^T : decimal = (# "conv.i" (Convert.ToInt64 value) : unativeint #) + when ^T : decimal = (# "conv.i" (Convert.ToInt64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) [] @@ -5147,7 +5147,7 @@ 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 #) - when ^T : decimal = (# "conv.ovf.u.un" (Convert.ToUInt64 value) : unativeint #) + when ^T : decimal = (# "conv.ovf.u.un" (Convert.ToUInt64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -5168,7 +5168,7 @@ 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 #) - when ^T : decimal = (# "conv.ovf.i" (Convert.ToInt64 value) : nativeint #) + when ^T : decimal = (# "conv.ovf.i" (Convert.ToInt64 (# "" value : decimal #)) : nativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) module OperatorIntrinsics = From 8ce408bc58488cd619312c249ba90ede384e2364 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 01:40:23 +0800 Subject: [PATCH 52/78] Respect truncation! --- src/fsharp/FSharp.Core/prim-types.fs | 4 ++-- tests/fsharp/core/libtest/test.fsx | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index a0cf2c794e5..bf4d7992636 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -5147,7 +5147,7 @@ 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 #) - when ^T : decimal = (# "conv.ovf.u.un" (Convert.ToUInt64 (# "" value : decimal #)) : unativeint #) + when ^T : decimal = (# "conv.ovf.u.un" (uint64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -5168,7 +5168,7 @@ 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 #) - when ^T : decimal = (# "conv.ovf.i" (Convert.ToInt64 (# "" value : decimal #)) : nativeint #) + when ^T : decimal = (# "conv.ovf.i" (int64 (# "" value : decimal #)) : nativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) module OperatorIntrinsics = diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index 0b624ac7526..0739afe3462 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -3676,6 +3676,16 @@ module Optimiations = begin let _ = check "opt.oi20c77jc" (Checked.nativeint "3") (3n) let _ = check "opt.oi20c77kc" (Checked.nativeint "-3") (-3n) let _ = check "opt.oi20c77lc" (Checked.unativeint "3") (3un) + let _ = check "opt.oi20c77zc" (int8 3.9m) (3y) + let _ = check "opt.oi20c77xc" (uint8 3.9m) (3uy) + let _ = check "opt.oi20c77cc" (int16 3.9m) (3s) + let _ = check "opt.oi20c77vc" (uint16 3.9m) (3us) + let _ = check "opt.oi20c77bc" (int32 3.9m) (3l) + let _ = check "opt.oi20c77nc" (uint32 3.9m) (3ul) + let _ = check "opt.oi20c77mc" (int64 3.9m) (3L) + let _ = check "opt.oi20c77,c" (uint64 3.9m) (3uL) + let _ = check "opt.oi20c77.c" (nativeint 3.9m) (3n) + let _ = check "opt.oi20c77/c" (unativeint 3.9m) (3un) end From 2c22e457abcdefb5ab1ef00f0cb945ed30fe48f5 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 01:42:01 +0800 Subject: [PATCH 53/78] Truncate! --- src/fsharp/FSharp.Core/prim-types.fs | 4 ++-- tests/fsharp/core/libtest/test.fsx | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index bf4d7992636..f047c9f7f00 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -4487,7 +4487,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : unativeint #) when ^T : unativeint = (# "" value : unativeint #) when ^T : byte = (# "conv.u" value : unativeint #) - when ^T : decimal = (# "conv.u" (Convert.ToUInt64 (# "" value : decimal #)) : unativeint #) + when ^T : decimal = (# "conv.u" (uint64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) [] @@ -4512,7 +4512,7 @@ namespace Microsoft.FSharp.Core when ^T : char = (# "conv.u" value : nativeint #) when ^T : unativeint = (# "" value : nativeint #) when ^T : byte = (# "conv.i" value : nativeint #) - when ^T : decimal = (# "conv.i" (Convert.ToInt64 (# "" value : decimal #)) : unativeint #) + when ^T : decimal = (# "conv.i" (int64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) [] diff --git a/tests/fsharp/core/libtest/test.fsx b/tests/fsharp/core/libtest/test.fsx index 0739afe3462..1381e0f2525 100644 --- a/tests/fsharp/core/libtest/test.fsx +++ b/tests/fsharp/core/libtest/test.fsx @@ -3686,6 +3686,16 @@ module Optimiations = begin let _ = check "opt.oi20c77,c" (uint64 3.9m) (3uL) let _ = check "opt.oi20c77.c" (nativeint 3.9m) (3n) let _ = check "opt.oi20c77/c" (unativeint 3.9m) (3un) + let _ = check "opt.oi20c77zc'" (Checked.int8 3.9m) (3y) + let _ = check "opt.oi20c77xc'" (Checked.uint8 3.9m) (3uy) + let _ = check "opt.oi20c77cc'" (Checked.int16 3.9m) (3s) + let _ = check "opt.oi20c77vc'" (Checked.uint16 3.9m) (3us) + let _ = check "opt.oi20c77bc'" (Checked.int32 3.9m) (3l) + let _ = check "opt.oi20c77nc'" (Checked.uint32 3.9m) (3ul) + let _ = check "opt.oi20c77mc'" (Checked.int64 3.9m) (3L) + let _ = check "opt.oi20c77,c'" (Checked.uint64 3.9m) (3uL) + let _ = check "opt.oi20c77.c'" (Checked.nativeint 3.9m) (3n) + let _ = check "opt.oi20c77/c'" (Checked.unativeint 3.9m) (3un) end From 0107215d688440dd49d6364ead7f7adb77612f3a Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 16:01:49 +0800 Subject: [PATCH 54/78] Simplifying refactor --- src/fsharp/FSharp.Core/Linq.fs | 456 +++++++++++++++--------------- tests/fsharp/core/quotes/test.fsx | 262 +++++++++-------- 2 files changed, 367 insertions(+), 351 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 6f807215b91..da9bdc0fe1e 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -87,150 +87,152 @@ module LeafExpressionConverter = if isg1 then minfo2.IsGenericMethod && gmd = minfo2.GetGenericMethodDefinition() else minfo = minfo2 ) -> - Some (obj, (minfo2.GetGenericArguments() |> Array.toList), args) + Some (obj, minfo2, args) | _ -> None) - - let (|SpecificCallToMethod|_|) (mhandle: System.RuntimeMethodHandle) = + let (|SpecificCallToMethod'|_|) (mhandle: System.RuntimeMethodHandle) = 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.( ? 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.( 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 (|ConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.nativeint x)) - let (|ConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.unativeint x)) + + let (|SpecificCallToMethod|_|) (mhandle: System.RuntimeMethodHandle) = + (|SpecificCallToMethod'|_|) mhandle >> Option.map (fun (obj, minfo, args) -> obj, minfo.GetGenericArguments() |> Array.toList, args) + + 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.( ? 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.( 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 (|ConvIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Operators.nativeint x)) + let (|ConvUIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Operators.unativeint 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 (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.nativeint x)) - let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.unativeint x)) + 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 (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Nullable.nativeint x)) + let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Nullable.unativeint x)) let (|UnboxGeneric|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.UnboxGeneric x)) 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 (|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 (|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)) - let (|CheckedConvByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.byte x)) - let (|CheckedConvUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint16 x)) - let (|CheckedConvUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint32 x)) - let (|CheckedConvUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint64 x)) - let (|CheckedConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.nativeint x)) - let (|CheckedConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.unativeint x)) + 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)) + let (|CheckedConvByteQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.byte x)) + let (|CheckedConvUInt16Q|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.uint16 x)) + let (|CheckedConvUInt32Q|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.uint32 x)) + let (|CheckedConvUInt64Q|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.uint64 x)) + let (|CheckedConvIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.nativeint x)) + let (|CheckedConvUIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.unativeint x)) let (|ImplicitExpressionConversionHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> ImplicitExpressionConversionHelper x)) - let (|MemberInitializationHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> MemberInitializationHelper x)) - let (|NewAnonymousObjectHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> NewAnonymousObjectHelper x)) + let (|MemberInitializationHelperQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> MemberInitializationHelper x)) + let (|NewAnonymousObjectHelperQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> NewAnonymousObjectHelper x)) let (|ArrayLookupQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.IntrinsicFunctions.GetArray x y)) //let (|ArrayAssignQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun -> LanguagePrimitives.IntrinsicFunctions.SetArray : int[] -> int -> int -> unit)) @@ -358,105 +360,106 @@ module LeafExpressionConverter = 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) -> + | PlusQ (_, m, [x1; x2]) when + m.GetGenericArguments() = [|typeof; typeof; typeof|] -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr - | GenericEqualityQ (_, _, [x1; x2]) - | EqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) - | NotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) - | GreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) - | GreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) - | LessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) - | LessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) + | GenericEqualityQ (_, m, [x1; x2]) + | EqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m + | NotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m + | GreaterQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThan m + | GreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m + | LessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m + | LessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) - | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) - | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) - | StaticLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) - | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) - - | NullableEqualsQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) - | NullableNotEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) - | NullableGreaterQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) - | NullableGreaterEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) - | NullableLessQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) - | NullableLessEqQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 true Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) - - | EqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) - | NotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) - | GreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) - | GreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) - | LessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) - | LessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env true x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) - - | NullableEqualsNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) - | NullableNotEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) - | NullableGreaterNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) - | NullableGreaterEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) - | NullableLessNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) - | NullableLessEqNullableQ (_, _, [x1; x2]) -> transBoolOp inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) + | StaticEqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m + | StaticNotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m + | StaticGreaterQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThan m + | StaticGreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m + | StaticLessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m + | StaticLessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m + + | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.Equal m + | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.NotEqual m + | NullableGreaterQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.GreaterThan m + | NullableGreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.GreaterThanOrEqual m + | NullableLessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.LessThan m + | NullableLessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.LessThanOrEqual m + + | EqualsNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.Equal m + | NotEqNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.NotEqual m + | GreaterNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.GreaterThan m + | GreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.GreaterThanOrEqual m + | LessNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.LessThan m + | LessEqNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.LessThanOrEqual m + + | NullableEqualsNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m + | NullableNotEqNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m + | NullableGreaterNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThan m + | NullableGreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m + | NullableLessNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m + | NullableLessEqNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m // 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 (_, _, [x]) -> transUnaryOp inp env x Expression.Negate (methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x)) - | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | DivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | ModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - - | ShiftLeftQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LeftShift (methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y)) - | ShiftRightQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.RightShift (methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y)) - | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y)) - | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y)) - | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y)) - | BitwiseNotQ (_, _, [x]) -> transUnaryOp inp env x Expression.Not (methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x)) + | NegQ (_, m, [x]) -> transUnaryOp env x Expression.Negate m + | PlusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Add m + | MinusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Subtract m + | MultiplyQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Multiply m + | DivideQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Divide m + | ModuloQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Modulo m + + | ShiftLeftQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LeftShift m + | ShiftRightQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.RightShift m + | BitwiseAndQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.And m + | BitwiseOrQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Or m + | BitwiseXorQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.ExclusiveOr m + | BitwiseNotQ (_, m, [x]) -> transUnaryOp env x Expression.Not m - | CheckedNeg (_, _, [x]) -> transUnaryOp inp env x Expression.NegateChecked (methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x)) - | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y)) - | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y)) - | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y)) + | CheckedNeg (_, m, [x]) -> transUnaryOp env x Expression.NegateChecked m + | CheckedPlusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.AddChecked m + | CheckedMinusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.SubtractChecked m + | CheckedMultiplyQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.MultiplyChecked m - | NullablePlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | PlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | NullablePlusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Add m + | PlusNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Add m + | NullablePlusNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Add m - | NullableMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | MinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | NullableMinusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Subtract m + | MinusNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Subtract m + | NullableMinusNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Subtract m - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | NullableMultiplyQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Multiply m + | MultiplyNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Multiply m + | NullableMultiplyNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Multiply m - | NullableDivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | DivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | NullableDivideQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Divide m + | DivideNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Divide m + | NullableDivideNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Divide m - | NullableModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - - | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConv inp env false x - | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConv inp env false x - | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) -> transConv inp env false x - | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) -> transConv inp env false x - | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) -> transConv inp env false x - - | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) -> transConv inp env false x - | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) -> transConv inp env false x - | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) -> transConv inp env false x - | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) -> transConv inp env false x - | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConv inp env false x - - | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) -> transConv inp env true x - | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) -> transConv inp env true x - | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) -> transConv inp env true x - | CheckedConvUIntPtrQ (_, _, [x]) -> transConv inp env true x + | NullableModuloQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Modulo m + | ModuloNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Modulo m + | NullableModuloNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Modulo m + + | ConvNullableCharQ (_, m, [x]) | ConvNullableDecimalQ (_, m, [x]) | ConvNullableFloatQ (_, m, [x]) | ConvNullableDoubleQ (_, m, [x]) -> transConv inp env false x m + | ConvNullableFloat32Q (_, m, [x]) | ConvNullableSingleQ (_, m, [x]) | ConvNullableSByteQ (_, m, [x]) | ConvNullableInt8Q (_, m, [x]) -> transConv inp env false x m + | ConvNullableInt16Q (_, m, [x]) | ConvNullableInt32Q (_, m, [x]) | ConvNullableIntQ (_, m, [x]) | ConvNullableInt64Q (_, m, [x]) -> transConv inp env false x m + | ConvNullableByteQ (_, m, [x]) | ConvNullableUInt8Q (_, m, [x]) | ConvNullableUInt16Q (_, m, [x]) | ConvNullableUInt32Q (_, m, [x]) -> transConv inp env false x m + | ConvNullableUInt64Q (_, m, [x]) | ConvNullableIntPtrQ (_, m, [x]) | ConvNullableUIntPtrQ (_, m, [x]) -> transConv inp env false x m + + | ConvCharQ (_, m, [x]) | ConvDecimalQ (_, m, [x]) | ConvFloatQ (_, m, [x]) | ConvDoubleQ (_, m, [x]) -> transConv inp env false x m + | ConvFloat32Q (_, m, [x]) | ConvSingleQ (_, m, [x]) | ConvSByteQ (_, m, [x]) | ConvInt8Q (_, m, [x]) -> transConv inp env false x m + | ConvInt16Q (_, m, [x]) | ConvInt32Q (_, m, [x]) | ConvIntQ (_, m, [x]) | ConvInt64Q (_, m, [x]) -> transConv inp env false x m + | ConvByteQ (_, m, [x]) | ConvUInt8Q (_, m, [x]) | ConvUInt16Q (_, m, [x]) | ConvUInt32Q (_, m, [x]) -> transConv inp env false x m + | ConvUInt64Q (_, m, [x]) | ConvIntPtrQ (_, m, [x]) | ConvUIntPtrQ (_, m, [x]) -> transConv inp env false x m + + | CheckedConvCharQ (_, m, [x]) | CheckedConvSByteQ (_, m, [x]) | CheckedConvInt8Q (_, m, [x]) | CheckedConvInt16Q (_, m, [x]) -> transConv inp env true x m + | CheckedConvInt32Q (_, m, [x]) | CheckedConvInt64Q (_, m, [x]) | CheckedConvByteQ (_, m, [x]) | CheckedConvUInt8Q (_, m, [x]) -> transConv inp env true x m + | CheckedConvUInt16Q (_, m, [x]) | CheckedConvUInt32Q (_, m, [x]) | CheckedConvUInt64Q (_, m, [x]) | CheckedConvIntPtrQ (_, m, [x]) -> transConv inp env true x m + | CheckedConvUIntPtrQ (_, m, [x]) -> transConv inp env true x m | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> Expression.ArrayIndex(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr @@ -633,36 +636,29 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) - and transUnaryOp inp env x (exprErasedConstructor: _ * _ -> _) fallback = + and transUnaryOp env x (exprErasedConstructor: _ * _ -> _) method = let e = ConvExprToLinqInContext env x try exprErasedConstructor(e, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t - let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo - exprErasedConstructor(e, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) + exprErasedConstructor(e, method) |> asExpr - and transBinOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = + and transBinOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) method = 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 - try exprErasedConstructor(e1, e2, null) with _ -> + 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 + try exprErasedConstructor(e1', e2', null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t - let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo - exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) + exprErasedConstructor(e1, e2, method) |> asExpr - and transBoolOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) fallback = - transBinOp inp env addConvertLeft x1 x2 addConvertRight (fun (left, right, methodInfo) -> exprErasedConstructor(left, right, false, methodInfo)) fallback - and transConv (inp: Expr) env isChecked x = + and transBoolOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) = + transBinOp env addConvertLeft x1 x2 addConvertRight (fun (left, right, methodInfo) -> exprErasedConstructor(left, right, false, methodInfo)) + and transConv (inp: Expr) env isChecked x method = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert try exprErasedConstructor(e, inp.Type, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t - // The dynamic implementations of checked conversion operators refer to LanguagePrimitives.ExplicitDynamic which is unchecked! This is a bug and should definitely be fixed. - let method = Reflection.MethodInfo.GetMethodFromHandle (methodhandleof (fun x -> LanguagePrimitives.ExplicitDynamic x)) :?> Reflection.MethodInfo - exprErasedConstructor(e, inp.Type, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) + exprErasedConstructor(e, inp.Type, method) |> asExpr and ConvObjArg env objOpt coerceTo : Expression = diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 2fdb7514c56..ca992fbebe7 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3607,108 +3607,6 @@ module WitnessTests = <@@ ~~~LanguagePrimitives.GenericOne @@>, box ~~~1n <@@ ~~~LanguagePrimitives.GenericOne @@>, box ~~~1un - <@@ 3y = 3y @@>, box true - <@@ 3uy = 3uy @@>, box true - <@@ 3s = 3s @@>, box true - <@@ 3us = 3us @@>, box true - <@@ 3 = 3 @@>, box true - <@@ 3u = 3u @@>, box true - <@@ 3L = 3L @@>, box true - <@@ 3UL = 3UL @@>, box true - <@@ '3' = '3' @@>, box true - <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box true - <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box true - <@@ 3f = 3f @@>, box true - <@@ 3. = 3. @@>, box true - <@@ 3m = 3m @@>, box true - <@@ "3" = "3" @@>, box true - <@@ [3] = [3] @@>, box true - - <@@ 3y <> 3y @@>, box false - <@@ 3uy <> 3uy @@>, box false - <@@ 3s <> 3s @@>, box false - <@@ 3us <> 3us @@>, box false - <@@ 3 <> 3 @@>, box false - <@@ 3u <> 3u @@>, box false - <@@ 3L <> 3L @@>, box false - <@@ 3UL <> 3UL @@>, box false - <@@ '3' <> '3' @@>, box false - <@@ LanguagePrimitives.GenericOne <> LanguagePrimitives.GenericOne @@>, box false - <@@ LanguagePrimitives.GenericOne <> LanguagePrimitives.GenericOne @@>, box false - <@@ 3f <> 3f @@>, box false - <@@ 3. <> 3. @@>, box false - <@@ 3m <> 3m @@>, box false - <@@ "3" <> "3" @@>, box false - <@@ [3] <> [3] @@>, box false - - <@@ 3y <= 3y @@>, box true - <@@ 3uy <= 3uy @@>, box true - <@@ 3s <= 3s @@>, box true - <@@ 3us <= 3us @@>, box true - <@@ 3 <= 3 @@>, box true - <@@ 3u <= 3u @@>, box true - <@@ 3L <= 3L @@>, box true - <@@ 3UL <= 3UL @@>, box true - <@@ '3' <= '3' @@>, box true - <@@ LanguagePrimitives.GenericOne <= LanguagePrimitives.GenericOne @@>, box true - <@@ LanguagePrimitives.GenericOne <= LanguagePrimitives.GenericOne @@>, box true - <@@ 3f <= 3f @@>, box true - <@@ 3. <= 3. @@>, box true - <@@ 3m <= 3m @@>, box true - <@@ "3" <= "3" @@>, box true - <@@ [3] <= [3] @@>, box true - - <@@ 3y < 3y @@>, box false - <@@ 3uy < 3uy @@>, box false - <@@ 3s < 3s @@>, box false - <@@ 3us < 3us @@>, box false - <@@ 3 < 3 @@>, box false - <@@ 3u < 3u @@>, box false - <@@ 3L < 3L @@>, box false - <@@ 3UL < 3UL @@>, box false - <@@ '3' < '3' @@>, box false - <@@ LanguagePrimitives.GenericOne < LanguagePrimitives.GenericOne @@>, box false - <@@ LanguagePrimitives.GenericOne < LanguagePrimitives.GenericOne @@>, box false - <@@ 3f < 3f @@>, box false - <@@ 3. < 3. @@>, box false - <@@ 3m < 3m @@>, box false - <@@ "3" < "3" @@>, box false - <@@ [3] < [3] @@>, box false - - <@@ 3y >= 3y @@>, box true - <@@ 3uy >= 3uy @@>, box true - <@@ 3s >= 3s @@>, box true - <@@ 3us >= 3us @@>, box true - <@@ 3 >= 3 @@>, box true - <@@ 3u >= 3u @@>, box true - <@@ 3L >= 3L @@>, box true - <@@ 3UL >= 3UL @@>, box true - <@@ '3' >= '3' @@>, box true - <@@ LanguagePrimitives.GenericOne >= LanguagePrimitives.GenericOne @@>, box true - <@@ LanguagePrimitives.GenericOne >= LanguagePrimitives.GenericOne @@>, box true - <@@ 3f >= 3f @@>, box true - <@@ 3. >= 3. @@>, box true - <@@ 3m >= 3m @@>, box true - <@@ "3" >= "3" @@>, box true - <@@ [3] >= [3] @@>, box true - - <@@ 3y > 3y @@>, box false - <@@ 3uy > 3uy @@>, box false - <@@ 3s > 3s @@>, box false - <@@ 3us > 3us @@>, box false - <@@ 3 > 3 @@>, box false - <@@ 3u > 3u @@>, box false - <@@ 3L > 3L @@>, box false - <@@ 3UL > 3UL @@>, box false - <@@ '3' > '3' @@>, box false - <@@ LanguagePrimitives.GenericOne > LanguagePrimitives.GenericOne @@>, box false - <@@ LanguagePrimitives.GenericOne > LanguagePrimitives.GenericOne @@>, box false - <@@ 3f > 3f @@>, box false - <@@ 3. > 3. @@>, box false - <@@ 3m > 3m @@>, box false - <@@ "3" > "3" @@>, box false - <@@ [3] > [3] @@>, box false - <@@ byte 3uy @@>, box 3uy <@@ byte 3y @@>, box 3uy <@@ byte 3s @@>, box 3uy @@ -4565,6 +4463,144 @@ module WitnessTests = <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, box '5' <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2n <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2un + |] + + tests |> Array.map (fun (test, eval) -> + begin + printfn "--> Checking we can evaluate %A" test + let res = FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation test + let b = res = eval + if b then printfn "--- Success, it is %A which is equal to %A" res eval + else printfn "!!! FAILURE, it is %A which is not equal to %A" res eval + b + end + && + match test with + | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> + minfo1.IsStatic && + minfo2.IsStatic && + minfo2.Name = minfo1.Name + "$W" && + (* + (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && + minfo2.GetParameters().Length = 3 && + (printfn "checking witnessArgs.Length..."; true) && + witnessArgs.Length = 1 && + (printfn "checking args.Length..."; true) && + args.Length = 2 && + (printfn "witnessArgs..."; true) && + (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && + (printfn "args..."; true) && + (match args with [ _; _ ] -> true | _ -> false) + *) + (printfn "<-- Successfully checked with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) + || (printfn "<-- FAILURE, failed after matching with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) + | _ -> + printfn " Array.forall id) // Don't short circuit on a failed test + + test "check non-CallWithWitnesses operators" + (let tests = [| + <@@ 3y = 3y @@>, box true + <@@ 3uy = 3uy @@>, box true + <@@ 3s = 3s @@>, box true + <@@ 3us = 3us @@>, box true + <@@ 3 = 3 @@>, box true + <@@ 3u = 3u @@>, box true + <@@ 3L = 3L @@>, box true + <@@ 3UL = 3UL @@>, box true + <@@ '3' = '3' @@>, box true + <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne = LanguagePrimitives.GenericOne @@>, box true + <@@ 3f = 3f @@>, box true + <@@ 3. = 3. @@>, box true + <@@ 3m = 3m @@>, box true + <@@ "3" = "3" @@>, box true + <@@ [3] = [3] @@>, box true + + <@@ 3y <> 3y @@>, box false + <@@ 3uy <> 3uy @@>, box false + <@@ 3s <> 3s @@>, box false + <@@ 3us <> 3us @@>, box false + <@@ 3 <> 3 @@>, box false + <@@ 3u <> 3u @@>, box false + <@@ 3L <> 3L @@>, box false + <@@ 3UL <> 3UL @@>, box false + <@@ '3' <> '3' @@>, box false + <@@ LanguagePrimitives.GenericOne <> LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne <> LanguagePrimitives.GenericOne @@>, box false + <@@ 3f <> 3f @@>, box false + <@@ 3. <> 3. @@>, box false + <@@ 3m <> 3m @@>, box false + <@@ "3" <> "3" @@>, box false + <@@ [3] <> [3] @@>, box false + + <@@ 3y <= 3y @@>, box true + <@@ 3uy <= 3uy @@>, box true + <@@ 3s <= 3s @@>, box true + <@@ 3us <= 3us @@>, box true + <@@ 3 <= 3 @@>, box true + <@@ 3u <= 3u @@>, box true + <@@ 3L <= 3L @@>, box true + <@@ 3UL <= 3UL @@>, box true + <@@ '3' <= '3' @@>, box true + <@@ LanguagePrimitives.GenericOne <= LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne <= LanguagePrimitives.GenericOne @@>, box true + <@@ 3f <= 3f @@>, box true + <@@ 3. <= 3. @@>, box true + <@@ 3m <= 3m @@>, box true + <@@ "3" <= "3" @@>, box true + <@@ [3] <= [3] @@>, box true + + <@@ 3y < 3y @@>, box false + <@@ 3uy < 3uy @@>, box false + <@@ 3s < 3s @@>, box false + <@@ 3us < 3us @@>, box false + <@@ 3 < 3 @@>, box false + <@@ 3u < 3u @@>, box false + <@@ 3L < 3L @@>, box false + <@@ 3UL < 3UL @@>, box false + <@@ '3' < '3' @@>, box false + <@@ LanguagePrimitives.GenericOne < LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne < LanguagePrimitives.GenericOne @@>, box false + <@@ 3f < 3f @@>, box false + <@@ 3. < 3. @@>, box false + <@@ 3m < 3m @@>, box false + <@@ "3" < "3" @@>, box false + <@@ [3] < [3] @@>, box false + + <@@ 3y >= 3y @@>, box true + <@@ 3uy >= 3uy @@>, box true + <@@ 3s >= 3s @@>, box true + <@@ 3us >= 3us @@>, box true + <@@ 3 >= 3 @@>, box true + <@@ 3u >= 3u @@>, box true + <@@ 3L >= 3L @@>, box true + <@@ 3UL >= 3UL @@>, box true + <@@ '3' >= '3' @@>, box true + <@@ LanguagePrimitives.GenericOne >= LanguagePrimitives.GenericOne @@>, box true + <@@ LanguagePrimitives.GenericOne >= LanguagePrimitives.GenericOne @@>, box true + <@@ 3f >= 3f @@>, box true + <@@ 3. >= 3. @@>, box true + <@@ 3m >= 3m @@>, box true + <@@ "3" >= "3" @@>, box true + <@@ [3] >= [3] @@>, box true + + <@@ 3y > 3y @@>, box false + <@@ 3uy > 3uy @@>, box false + <@@ 3s > 3s @@>, box false + <@@ 3us > 3us @@>, box false + <@@ 3 > 3 @@>, box false + <@@ 3u > 3u @@>, box false + <@@ 3L > 3L @@>, box false + <@@ 3UL > 3UL @@>, box false + <@@ '3' > '3' @@>, box false + <@@ LanguagePrimitives.GenericOne > LanguagePrimitives.GenericOne @@>, box false + <@@ LanguagePrimitives.GenericOne > LanguagePrimitives.GenericOne @@>, box false + <@@ 3f > 3f @@>, box false + <@@ 3. > 3. @@>, box false + <@@ 3m > 3m @@>, box false + <@@ "3" > "3" @@>, box false + <@@ [3] > [3] @@>, box false <@@ Nullable<_> 1y ?= 1y @@>, box true <@@ Nullable<_> 1uy ?= 1uy @@>, box true @@ -4849,27 +4885,11 @@ module WitnessTests = && match test with | CallWithWitnesses(None, minfo1, minfo2, witnessArgs, args) -> - minfo1.IsStatic && - minfo2.IsStatic && - minfo2.Name = minfo1.Name + "$W" && - (* - (printfn "checking minfo2.GetParameters().Length = %d..." (minfo2.GetParameters().Length); true) && - minfo2.GetParameters().Length = 3 && - (printfn "checking witnessArgs.Length..."; true) && - witnessArgs.Length = 1 && - (printfn "checking args.Length..."; true) && - args.Length = 2 && - (printfn "witnessArgs..."; true) && - (match witnessArgs with [ Lambda _ ] -> true | _ -> false) && - (printfn "args..."; true) && - (match args with [ _; _ ] -> true | _ -> false) - *) - (printfn "<-- Successfully checked with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) - || (printfn "<-- FAILURE, failed after matching with Quotations.Patterns.(|CallWithWitnesses|_|)"; true) + printfn " - printfn " Array.forall id) // Don't short circuit on a failed test - module MoreWitnessTests = open System.Runtime.CompilerServices From 824bf821a770d35a8e784da3913508c81d0864c8 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 16:06:55 +0800 Subject: [PATCH 55/78] Consistent naming --- src/fsharp/FSharp.Core/Linq.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index da9bdc0fe1e..90fd59e5996 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -652,7 +652,7 @@ module LeafExpressionConverter = exprErasedConstructor(e1, e2, method) |> asExpr and transBoolOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) = - transBinOp env addConvertLeft x1 x2 addConvertRight (fun (left, right, methodInfo) -> exprErasedConstructor(left, right, false, methodInfo)) + transBinOp env addConvertLeft x1 x2 addConvertRight (fun (left, right, method) -> exprErasedConstructor(left, right, false, method)) and transConv (inp: Expr) env isChecked x method = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert From 6014407afc09c0e3a48be9773e3547443cba87aa Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 19:22:17 +0800 Subject: [PATCH 56/78] Only invoke the method directly for boolean operators --- src/fsharp/FSharp.Core/Linq.fs | 131 ++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 58 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 90fd59e5996..e64cd5f50d8 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -405,61 +405,61 @@ module LeafExpressionConverter = | MakeDecimalQ (_, _, [Int32 lo; Int32 med; Int32 hi; Bool isNegative; Byte scale]) -> Expression.Constant (new System.Decimal(lo, med, hi, isNegative, scale)) |> asExpr - | NegQ (_, m, [x]) -> transUnaryOp env x Expression.Negate m - | PlusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Add m - | MinusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Subtract m - | MultiplyQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Multiply m - | DivideQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Divide m - | ModuloQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Modulo m - - | ShiftLeftQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.LeftShift m - | ShiftRightQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.RightShift m - | BitwiseAndQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.And m - | BitwiseOrQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Or m - | BitwiseXorQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.ExclusiveOr m - | BitwiseNotQ (_, m, [x]) -> transUnaryOp env x Expression.Not m + | NegQ (_, _, [x]) -> transUnaryOp inp env x Expression.Negate (methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x)) + | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | DivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | ModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + + | ShiftLeftQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LeftShift (methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y)) + | ShiftRightQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.RightShift (methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y)) + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y)) + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y)) + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y)) + | BitwiseNotQ (_, _, [x]) -> transUnaryOp inp env x Expression.Not (methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x)) - | CheckedNeg (_, m, [x]) -> transUnaryOp env x Expression.NegateChecked m - | CheckedPlusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.AddChecked m - | CheckedMinusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.SubtractChecked m - | CheckedMultiplyQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.MultiplyChecked m + | CheckedNeg (_, _, [x]) -> transUnaryOp inp env x Expression.NegateChecked (methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x)) + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y)) + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y)) + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y)) - | NullablePlusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Add m - | PlusNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Add m - | NullablePlusNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Add m + | NullablePlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | PlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | NullableMinusQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Subtract m - | MinusNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Subtract m - | NullableMinusNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Subtract m + | NullableMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | MinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | NullableMultiplyQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Multiply m - | MultiplyNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Multiply m - | NullableMultiplyNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Multiply m + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | NullableDivideQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Divide m - | DivideNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Divide m - | NullableDivideNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Divide m + | NullableDivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | DivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | NullableModuloQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 true Expression.Modulo m - | ModuloNullableQ (_, m, [x1; x2]) -> transBinOp env true x1 x2 false Expression.Modulo m - | NullableModuloNullableQ (_, m, [x1; x2]) -> transBinOp env false x1 x2 false Expression.Modulo m - - | ConvNullableCharQ (_, m, [x]) | ConvNullableDecimalQ (_, m, [x]) | ConvNullableFloatQ (_, m, [x]) | ConvNullableDoubleQ (_, m, [x]) -> transConv inp env false x m - | ConvNullableFloat32Q (_, m, [x]) | ConvNullableSingleQ (_, m, [x]) | ConvNullableSByteQ (_, m, [x]) | ConvNullableInt8Q (_, m, [x]) -> transConv inp env false x m - | ConvNullableInt16Q (_, m, [x]) | ConvNullableInt32Q (_, m, [x]) | ConvNullableIntQ (_, m, [x]) | ConvNullableInt64Q (_, m, [x]) -> transConv inp env false x m - | ConvNullableByteQ (_, m, [x]) | ConvNullableUInt8Q (_, m, [x]) | ConvNullableUInt16Q (_, m, [x]) | ConvNullableUInt32Q (_, m, [x]) -> transConv inp env false x m - | ConvNullableUInt64Q (_, m, [x]) | ConvNullableIntPtrQ (_, m, [x]) | ConvNullableUIntPtrQ (_, m, [x]) -> transConv inp env false x m - - | ConvCharQ (_, m, [x]) | ConvDecimalQ (_, m, [x]) | ConvFloatQ (_, m, [x]) | ConvDoubleQ (_, m, [x]) -> transConv inp env false x m - | ConvFloat32Q (_, m, [x]) | ConvSingleQ (_, m, [x]) | ConvSByteQ (_, m, [x]) | ConvInt8Q (_, m, [x]) -> transConv inp env false x m - | ConvInt16Q (_, m, [x]) | ConvInt32Q (_, m, [x]) | ConvIntQ (_, m, [x]) | ConvInt64Q (_, m, [x]) -> transConv inp env false x m - | ConvByteQ (_, m, [x]) | ConvUInt8Q (_, m, [x]) | ConvUInt16Q (_, m, [x]) | ConvUInt32Q (_, m, [x]) -> transConv inp env false x m - | ConvUInt64Q (_, m, [x]) | ConvIntPtrQ (_, m, [x]) | ConvUIntPtrQ (_, m, [x]) -> transConv inp env false x m - - | CheckedConvCharQ (_, m, [x]) | CheckedConvSByteQ (_, m, [x]) | CheckedConvInt8Q (_, m, [x]) | CheckedConvInt16Q (_, m, [x]) -> transConv inp env true x m - | CheckedConvInt32Q (_, m, [x]) | CheckedConvInt64Q (_, m, [x]) | CheckedConvByteQ (_, m, [x]) | CheckedConvUInt8Q (_, m, [x]) -> transConv inp env true x m - | CheckedConvUInt16Q (_, m, [x]) | CheckedConvUInt32Q (_, m, [x]) | CheckedConvUInt64Q (_, m, [x]) | CheckedConvIntPtrQ (_, m, [x]) -> transConv inp env true x m - | CheckedConvUIntPtrQ (_, m, [x]) -> transConv inp env true x m + | NullableModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + + | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConv inp env false x + | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConv inp env false x + | ConvNullableInt16Q (_, _, [x]) | ConvNullableInt32Q (_, _, [x]) | ConvNullableIntQ (_, _, [x]) | ConvNullableInt64Q (_, _, [x]) -> transConv inp env false x + | ConvNullableByteQ (_, _, [x]) | ConvNullableUInt8Q (_, _, [x]) | ConvNullableUInt16Q (_, _, [x]) | ConvNullableUInt32Q (_, _, [x]) -> transConv inp env false x + | ConvNullableUInt64Q (_, _, [x]) | ConvNullableIntPtrQ (_, _, [x]) | ConvNullableUIntPtrQ (_, _, [x]) -> transConv inp env false x + + | ConvCharQ (_, _, [x]) | ConvDecimalQ (_, _, [x]) | ConvFloatQ (_, _, [x]) | ConvDoubleQ (_, _, [x]) -> transConv inp env false x + | ConvFloat32Q (_, _, [x]) | ConvSingleQ (_, _, [x]) | ConvSByteQ (_, _, [x]) | ConvInt8Q (_, _, [x]) -> transConv inp env false x + | ConvInt16Q (_, _, [x]) | ConvInt32Q (_, _, [x]) | ConvIntQ (_, _, [x]) | ConvInt64Q (_, _, [x]) -> transConv inp env false x + | ConvByteQ (_, _, [x]) | ConvUInt8Q (_, _, [x]) | ConvUInt16Q (_, _, [x]) | ConvUInt32Q (_, _, [x]) -> transConv inp env false x + | ConvUInt64Q (_, _, [x]) | ConvIntPtrQ (_, _, [x]) | ConvUIntPtrQ (_, _, [x]) -> transConv inp env false x + + | CheckedConvCharQ (_, _, [x]) | CheckedConvSByteQ (_, _, [x]) | CheckedConvInt8Q (_, _, [x]) | CheckedConvInt16Q (_, _, [x]) -> transConv inp env true x + | CheckedConvInt32Q (_, _, [x]) | CheckedConvInt64Q (_, _, [x]) | CheckedConvByteQ (_, _, [x]) | CheckedConvUInt8Q (_, _, [x]) -> transConv inp env true x + | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) -> transConv inp env true x + | CheckedConvUIntPtrQ (_, _, [x]) -> transConv inp env true x | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> Expression.ArrayIndex(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr @@ -636,29 +636,44 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) - and transUnaryOp env x (exprErasedConstructor: _ * _ -> _) method = + and transUnaryOp inp env x (exprErasedConstructor: _ * _ -> _) fallback = let e = ConvExprToLinqInContext env x try exprErasedConstructor(e, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - exprErasedConstructor(e, method) + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) |> asExpr - and transBinOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) method = + and transBinOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = + 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 + try exprErasedConstructor(e1, e2, null) with _ -> + // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) + |> asExpr + // Boolean equality / comparison operators do not take witnesses and the referenced methods are callable directly + and transBoolOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = 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 - try exprErasedConstructor(e1', e2', null) with _ -> + try exprErasedConstructor(e1', e2', false, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - exprErasedConstructor(e1, e2, method) + exprErasedConstructor(e1, e2, false, method) |> asExpr - and transBoolOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) = - transBinOp env addConvertLeft x1 x2 addConvertRight (fun (left, right, method) -> exprErasedConstructor(left, right, false, method)) - and transConv (inp: Expr) env isChecked x method = + and transConv (inp: Expr) env isChecked x = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert try exprErasedConstructor(e, inp.Type, null) with _ -> // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - exprErasedConstructor(e, inp.Type, method) + let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + // The dynamic implementations of checked conversion operators refer to LanguagePrimitives.ExplicitDynamic which is unchecked! This is a bug and should definitely be fixed. + let method = Reflection.MethodInfo.GetMethodFromHandle (methodhandleof (fun x -> LanguagePrimitives.ExplicitDynamic x)) :?> Reflection.MethodInfo + exprErasedConstructor(e, inp.Type, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) |> asExpr and ConvObjArg env objOpt coerceTo : Expression = From bad346daad9cdda159d818fd99fbc7cf31e84e30 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 7 Jul 2021 19:23:35 +0800 Subject: [PATCH 57/78] Fix comment --- src/fsharp/FSharp.Core/Linq.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index e64cd5f50d8..3558785603b 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -662,7 +662,7 @@ module LeafExpressionConverter = 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 try exprErasedConstructor(e1', e2', false, null) with _ -> - // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. + // LINQ Expressions cannot recognize boolean operators on F# types that are not defined on the types themselves. In this case, use the F# operator as the user-defined method. exprErasedConstructor(e1, e2, false, method) |> asExpr and transConv (inp: Expr) env isChecked x = From e5765a082f0be05c359afbf7a79486e0b0df6637 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 8 Jul 2021 00:08:00 +0800 Subject: [PATCH 58/78] Related? --- src/fsharp/FSharp.Core/Linq.fs | 2 +- src/fsharp/FSharp.Core/prim-types.fs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 3558785603b..eb7dc9b6322 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -371,7 +371,7 @@ module LeafExpressionConverter = | GreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m | LessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m | LessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m - | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr + | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr | StaticEqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m | StaticNotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index f047c9f7f00..8636f7f0b64 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3014,7 +3014,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u" (convPrim<_,float> value) : unativeint #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u" (convPrim<_,float32> value) : unativeint #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : unativeint #) - elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.u" (Decimal.op_Explicit (convPrim<_,decimal> value) : uint64) #) + elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.u" (Decimal.op_Explicit (convPrim<_,decimal> value) : uint64) : unativeint #) elif typeeq<'T, string> then convPrim<_,'U> (ParseUIntPtr (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, nativeint> then @@ -3031,7 +3031,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i" (convPrim<_,float> value) : nativeint #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i" (convPrim<_,float32> value) : nativeint #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : nativeint #) - elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.i" (Decimal.op_Explicit (convPrim<_,decimal> value) : int64) #) + elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.i" (Decimal.op_Explicit (convPrim<_,decimal> value) : int64) : nativeint #) elif typeeq<'T, string> then convPrim<_,'U> (ParseIntPtr (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, char> then From cd679546b6e52d87a5867a964a5bc983f4fd4c5e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 8 Jul 2021 01:19:34 +0800 Subject: [PATCH 59/78] Fix test --- tests/fsharp/core/quotes/test.fsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index ca992fbebe7..9d744ff9a5d 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -4515,7 +4515,9 @@ module WitnessTests = <@@ 3. = 3. @@>, box true <@@ 3m = 3m @@>, box true <@@ "3" = "3" @@>, box true - <@@ [3] = [3] @@>, box true + <@@ [3] = [3] @@>, box false // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. + <@@ [|3|] = [|3|] @@>, box false // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. + <@@ seq { 3 } = seq { 3 } @@>, box false // Reference equality <@@ 3y <> 3y @@>, box false <@@ 3uy <> 3uy @@>, box false @@ -4532,7 +4534,9 @@ module WitnessTests = <@@ 3. <> 3. @@>, box false <@@ 3m <> 3m @@>, box false <@@ "3" <> "3" @@>, box false - <@@ [3] <> [3] @@>, box false + <@@ [3] <> [3] @@>, box true // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. + <@@ [|3|] <> [|3|] @@>, box true // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. + <@@ seq { 3 } <> seq { 3 } @@>, box true // Reference equality <@@ 3y <= 3y @@>, box true <@@ 3uy <= 3uy @@>, box true @@ -4550,6 +4554,7 @@ module WitnessTests = <@@ 3m <= 3m @@>, box true <@@ "3" <= "3" @@>, box true <@@ [3] <= [3] @@>, box true + <@@ [|3|] <= [|3|] @@>, box true <@@ 3y < 3y @@>, box false <@@ 3uy < 3uy @@>, box false @@ -4567,6 +4572,7 @@ module WitnessTests = <@@ 3m < 3m @@>, box false <@@ "3" < "3" @@>, box false <@@ [3] < [3] @@>, box false + <@@ [|3|] < [|3|] @@>, box false <@@ 3y >= 3y @@>, box true <@@ 3uy >= 3uy @@>, box true @@ -4584,6 +4590,7 @@ module WitnessTests = <@@ 3m >= 3m @@>, box true <@@ "3" >= "3" @@>, box true <@@ [3] >= [3] @@>, box true + <@@ [|3|] >= [|3|] @@>, box true <@@ 3y > 3y @@>, box false <@@ 3uy > 3uy @@>, box false @@ -4601,6 +4608,7 @@ module WitnessTests = <@@ 3m > 3m @@>, box false <@@ "3" > "3" @@>, box false <@@ [3] > [3] @@>, box false + <@@ [|3|] > [|3|] @@>, box false <@@ Nullable<_> 1y ?= 1y @@>, box true <@@ Nullable<_> 1uy ?= 1uy @@>, box true From ceed28ac58af68cb30aa16f54fbefe3be35580a1 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 8 Jul 2021 02:10:39 +0800 Subject: [PATCH 60/78] More tests --- tests/fsharp/core/quotes/test.fsx | 202 ++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 9d744ff9a5d..9618e2a465a 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3403,6 +3403,8 @@ module WitnessTests = <@@ 1.0f + 4.0f @@>, box 5f <@@ 1.0 + 4.0 @@>, box 5. <@@ 1m + 4m @@>, box 5m + <@@ 1m + 4m @@>, box 5m + <@@ 1I + 4I @@>, box 5I <@@ '1' + '\004' @@>, box '5' <@@ "abc" + "def" @@>, box "abcdef" <@@ LanguagePrimitives.GenericOne + LanguagePrimitives.GenericOne @@>, box 2n @@ -3434,6 +3436,8 @@ module WitnessTests = <@@ 4.0f - 1.0f @@>, box 3f <@@ 4.0 - 1.0 @@>, box 3. <@@ 4m - 1m @@>, box 3m + <@@ 4m - 1m @@>, box 3m + <@@ 4I - 1I @@>, box 3I <@@ '4' - '\001' @@>, box '3' <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, box 0n <@@ LanguagePrimitives.GenericOne - LanguagePrimitives.GenericOne @@>, box 0un @@ -3463,6 +3467,8 @@ module WitnessTests = <@@ 2.0f * 4.0f @@>, box 8f <@@ 2.0 * 4.0 @@>, box 8. <@@ 2m * 4m @@>, box 8m + <@@ 2m * 4m @@>, box 8m + <@@ 2I * 4I @@>, box 8I <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, box 1un <@@ Checked.(*) 2y 4y @@>, box 8y @@ -3490,6 +3496,8 @@ module WitnessTests = <@@ 6.0f / 3.0f @@>, box 2f <@@ 6.0 / 3.0 @@>, box 2. <@@ 6m / 3m @@>, box 2m + <@@ 6m / 3m @@>, box 2m + <@@ 6I / 3I @@>, box 2I <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne / LanguagePrimitives.GenericOne @@>, box 1un @@ -3504,6 +3512,8 @@ module WitnessTests = <@@ 9.0f % 4.0f @@>, box 1f <@@ 9.0 % 4.0 @@>, box 1. <@@ 9m % 4m @@>, box 1m + <@@ 9m % 4m @@>, box 1m + <@@ 9I % 4I @@>, box 1I <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, box 0n <@@ LanguagePrimitives.GenericOne % LanguagePrimitives.GenericOne @@>, box 0un @@ -3518,6 +3528,8 @@ module WitnessTests = <@@ +(1f) @@>, box 1f <@@ +(1.) @@>, box 1. <@@ +(1m) @@>, box 1m + <@@ +(1m) @@>, box 1m + <@@ +(1I) @@>, box 1I <@@ +(LanguagePrimitives.GenericOne) @@>, box 1n <@@ +(LanguagePrimitives.GenericOne) @@>, box 1un @@ -3528,6 +3540,8 @@ module WitnessTests = <@@ -(1f) @@>, box -1f <@@ -(1.) @@>, box -1. <@@ -(1m) @@>, box -1m + <@@ -(1m) @@>, box -1m + <@@ -(1I) @@>, box -1I <@@ -(LanguagePrimitives.GenericOne) @@>, box -1n <@@ Checked.(~-) (1y) @@>, box -1y <@@ Checked.(~-) (1s) @@>, box -1s @@ -3536,10 +3550,13 @@ module WitnessTests = <@@ Checked.(~-) (1f) @@>, box -1f <@@ Checked.(~-) (1.) @@>, box -1. <@@ Checked.(~-) (1m) @@>, box -1m + <@@ Checked.(~-) (1m) @@>, box -1m + <@@ Checked.(~-) (1I) @@>, box -1I <@@ Checked.(~-) (LanguagePrimitives.GenericOne) @@>, box -1n <@@ 4f ** 3f @@>, box 64f <@@ 4. ** 3. @@>, box 64. + <@@ 4I ** 3 @@>, box 64I <@@ 1y <<< 3 @@>, box 8y <@@ 1uy <<< 3 @@>, box 8uy @@ -3549,6 +3566,7 @@ module WitnessTests = <@@ 1u <<< 3 @@>, box 8u <@@ 1L <<< 3 @@>, box 8L <@@ 1UL <<< 3 @@>, box 8UL + <@@ 1I <<< 3 @@>, box 8I <@@ LanguagePrimitives.GenericOne <<< 3 @@>, box 8n <@@ LanguagePrimitives.GenericOne <<< 3 @@>, box 8un @@ -3560,6 +3578,7 @@ module WitnessTests = <@@ 1u >>> 3 @@>, box 0u <@@ 1L >>> 3 @@>, box 0L <@@ 1UL >>> 3 @@>, box 0UL + <@@ 1I >>> 3 @@>, box 0I <@@ LanguagePrimitives.GenericOne >>> 3 @@>, box 0n <@@ LanguagePrimitives.GenericOne >>> 3 @@>, box 0un @@ -3571,6 +3590,7 @@ module WitnessTests = <@@ 1u &&& 3u @@>, box 1u <@@ 1L &&& 3L @@>, box 1L <@@ 1UL &&& 3UL @@>, box 1UL + <@@ 1I &&& 3I @@>, box 1I <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne &&& LanguagePrimitives.GenericOne @@>, box 1un @@ -3582,6 +3602,7 @@ module WitnessTests = <@@ 1u ||| 3u @@>, box 3u <@@ 1L ||| 3L @@>, box 3L <@@ 1UL ||| 3UL @@>, box 3UL + <@@ 1I ||| 3I @@>, box 3I <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne ||| LanguagePrimitives.GenericOne @@>, box 1un @@ -3593,6 +3614,7 @@ module WitnessTests = <@@ 1u ^^^ 3u @@>, box 2u <@@ 1L ^^^ 3L @@>, box 2L <@@ 1UL ^^^ 3UL @@>, box 2UL + <@@ 1I ^^^ 3I @@>, box 2I <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, box 0n <@@ LanguagePrimitives.GenericOne ^^^ LanguagePrimitives.GenericOne @@>, box 0un @@ -3618,6 +3640,8 @@ module WitnessTests = <@@ byte '\003' @@>, box 3uy <@@ byte 3.0f @@>, box 3uy <@@ byte 3.0 @@>, box 3uy + <@@ byte 3.0 @@>, box 3uy + <@@ byte 3I @@>, box 3uy <@@ byte LanguagePrimitives.GenericOne @@>, box 1uy <@@ byte LanguagePrimitives.GenericOne @@>, box 1uy <@@ byte 3.0M @@>, box 3uy @@ -3633,6 +3657,8 @@ module WitnessTests = <@@ uint8 '\003' @@>, box 3uy <@@ uint8 3.0f @@>, box 3uy <@@ uint8 3.0 @@>, box 3uy + <@@ uint8 3.0 @@>, box 3uy + <@@ uint8 3I @@>, box 3uy <@@ uint8 LanguagePrimitives.GenericOne @@>, box 1uy <@@ uint8 LanguagePrimitives.GenericOne @@>, box 1uy <@@ uint8 3.0M @@>, box 3uy @@ -3648,6 +3674,8 @@ module WitnessTests = <@@ Checked.byte '\003' @@>, box 3uy <@@ Checked.byte 3.0f @@>, box 3uy <@@ Checked.byte 3.0 @@>, box 3uy + <@@ Checked.byte 3.0 @@>, box 3uy + <@@ Checked.byte 3I @@>, box 3uy <@@ Checked.byte LanguagePrimitives.GenericOne @@>, box 1uy <@@ Checked.byte LanguagePrimitives.GenericOne @@>, box 1uy <@@ Checked.byte 3.0M @@>, box 3uy @@ -3663,6 +3691,8 @@ module WitnessTests = <@@ Checked.uint8 '\003' @@>, box 3uy <@@ Checked.uint8 3.0f @@>, box 3uy <@@ Checked.uint8 3.0 @@>, box 3uy + <@@ Checked.uint8 3.0 @@>, box 3uy + <@@ Checked.uint8 3I @@>, box 3uy <@@ Checked.uint8 LanguagePrimitives.GenericOne @@>, box 1uy <@@ Checked.uint8 LanguagePrimitives.GenericOne @@>, box 1uy <@@ Checked.uint8 3.0M @@>, box 3uy @@ -3679,6 +3709,8 @@ module WitnessTests = <@@ sbyte '\003' @@>, box 3y <@@ sbyte 3.0f @@>, box 3y <@@ sbyte 3.0 @@>, box 3y + <@@ sbyte 3.0 @@>, box 3y + <@@ sbyte 3I @@>, box 3y <@@ sbyte LanguagePrimitives.GenericOne @@>, box 1y <@@ sbyte LanguagePrimitives.GenericOne @@>, box 1y <@@ sbyte 3.0M @@>, box 3y @@ -3694,6 +3726,8 @@ module WitnessTests = <@@ int8 '\003' @@>, box 3y <@@ int8 3.0f @@>, box 3y <@@ int8 3.0 @@>, box 3y + <@@ int8 3.0 @@>, box 3y + <@@ int8 3I @@>, box 3y <@@ int8 LanguagePrimitives.GenericOne @@>, box 1y <@@ int8 LanguagePrimitives.GenericOne @@>, box 1y <@@ int8 3.0M @@>, box 3y @@ -3709,6 +3743,8 @@ module WitnessTests = <@@ Checked.sbyte '\003' @@>, box 3y <@@ Checked.sbyte 3.0f @@>, box 3y <@@ Checked.sbyte 3.0 @@>, box 3y + <@@ Checked.sbyte 3.0 @@>, box 3y + <@@ Checked.sbyte 3I @@>, box 3y <@@ Checked.sbyte LanguagePrimitives.GenericOne @@>, box 1y <@@ Checked.sbyte LanguagePrimitives.GenericOne @@>, box 1y <@@ Checked.sbyte 3.0M @@>, box 3y @@ -3724,6 +3760,8 @@ module WitnessTests = <@@ Checked.int8 '\003' @@>, box 3y <@@ Checked.int8 3.0f @@>, box 3y <@@ Checked.int8 3.0 @@>, box 3y + <@@ Checked.int8 3.0 @@>, box 3y + <@@ Checked.int8 3I @@>, box 3y <@@ Checked.int8 LanguagePrimitives.GenericOne @@>, box 1y <@@ Checked.int8 LanguagePrimitives.GenericOne @@>, box 1y <@@ Checked.int8 3.0M @@>, box 3y @@ -3740,6 +3778,8 @@ module WitnessTests = <@@ int16 '\003' @@>, box 3s <@@ int16 3.0f @@>, box 3s <@@ int16 3.0 @@>, box 3s + <@@ int16 3.0 @@>, box 3s + <@@ int16 3I @@>, box 3s <@@ int16 LanguagePrimitives.GenericOne @@>, box 1s <@@ int16 LanguagePrimitives.GenericOne @@>, box 1s <@@ int16 3.0M @@>, box 3s @@ -3755,6 +3795,8 @@ module WitnessTests = <@@ Checked.int16 '\003' @@>, box 3s <@@ Checked.int16 3.0f @@>, box 3s <@@ Checked.int16 3.0 @@>, box 3s + <@@ Checked.int16 3.0 @@>, box 3s + <@@ Checked.int16 3I @@>, box 3s <@@ Checked.int16 LanguagePrimitives.GenericOne @@>, box 1s <@@ Checked.int16 LanguagePrimitives.GenericOne @@>, box 1s <@@ Checked.int16 3.0M @@>, box 3s @@ -3771,6 +3813,8 @@ module WitnessTests = <@@ uint16 '\003' @@>, box 3us <@@ uint16 3.0f @@>, box 3us <@@ uint16 3.0 @@>, box 3us + <@@ uint16 3.0 @@>, box 3us + <@@ uint16 3I @@>, box 3us <@@ uint16 LanguagePrimitives.GenericOne @@>, box 1us <@@ uint16 LanguagePrimitives.GenericOne @@>, box 1us <@@ uint16 3.0M @@>, box 3us @@ -3786,6 +3830,8 @@ module WitnessTests = <@@ Checked.uint16 '\003' @@>, box 3us <@@ Checked.uint16 3.0f @@>, box 3us <@@ Checked.uint16 3.0 @@>, box 3us + <@@ Checked.uint16 3.0 @@>, box 3us + <@@ Checked.uint16 3I @@>, box 3us <@@ Checked.uint16 LanguagePrimitives.GenericOne @@>, box 1us <@@ Checked.uint16 LanguagePrimitives.GenericOne @@>, box 1us <@@ Checked.uint16 3.0M @@>, box 3us @@ -3802,6 +3848,8 @@ module WitnessTests = <@@ int '\003' @@>, box 3 <@@ int 3.0f @@>, box 3 <@@ int 3.0 @@>, box 3 + <@@ int 3.0 @@>, box 3 + <@@ int 3I @@>, box 3 <@@ int LanguagePrimitives.GenericOne @@>, box 1 <@@ int LanguagePrimitives.GenericOne @@>, box 1 <@@ int 3.0M @@>, box 3 @@ -3817,6 +3865,8 @@ module WitnessTests = <@@ int32 '\003' @@>, box 3 <@@ int32 3.0f @@>, box 3 <@@ int32 3.0 @@>, box 3 + <@@ int32 3.0 @@>, box 3 + <@@ int32 3I @@>, box 3 <@@ int32 LanguagePrimitives.GenericOne @@>, box 1 <@@ int32 LanguagePrimitives.GenericOne @@>, box 1 <@@ int32 3.0M @@>, box 3 @@ -3832,6 +3882,8 @@ module WitnessTests = <@@ Checked.int '\003' @@>, box 3 <@@ Checked.int 3.0f @@>, box 3 <@@ Checked.int 3.0 @@>, box 3 + <@@ Checked.int 3.0 @@>, box 3 + <@@ Checked.int 3I @@>, box 3 <@@ Checked.int LanguagePrimitives.GenericOne @@>, box 1 <@@ Checked.int LanguagePrimitives.GenericOne @@>, box 1 <@@ Checked.int 3.0M @@>, box 3 @@ -3847,6 +3899,8 @@ module WitnessTests = <@@ Checked.int32 '\003' @@>, box 3 <@@ Checked.int32 3.0f @@>, box 3 <@@ Checked.int32 3.0 @@>, box 3 + <@@ Checked.int32 3.0 @@>, box 3 + <@@ Checked.int32 3I @@>, box 3 <@@ Checked.int32 LanguagePrimitives.GenericOne @@>, box 1 <@@ Checked.int32 LanguagePrimitives.GenericOne @@>, box 1 <@@ Checked.int32 3.0M @@>, box 3 @@ -3863,6 +3917,8 @@ module WitnessTests = <@@ uint '\003' @@>, box 3u <@@ uint 3.0f @@>, box 3u <@@ uint 3.0 @@>, box 3u + <@@ uint 3.0 @@>, box 3u + <@@ uint 3I @@>, box 3u <@@ uint LanguagePrimitives.GenericOne @@>, box 1u <@@ uint LanguagePrimitives.GenericOne @@>, box 1u <@@ uint 3.0M @@>, box 3u @@ -3878,6 +3934,8 @@ module WitnessTests = <@@ uint32 '\003' @@>, box 3u <@@ uint32 3.0f @@>, box 3u <@@ uint32 3.0 @@>, box 3u + <@@ uint32 3.0 @@>, box 3u + <@@ uint32 3I @@>, box 3u <@@ uint32 LanguagePrimitives.GenericOne @@>, box 1u <@@ uint32 LanguagePrimitives.GenericOne @@>, box 1u <@@ uint32 3.0M @@>, box 3u @@ -3893,6 +3951,8 @@ module WitnessTests = <@@ Checked.uint32 '\003' @@>, box 3u <@@ Checked.uint32 3.0f @@>, box 3u <@@ Checked.uint32 3.0 @@>, box 3u + <@@ Checked.uint32 3.0 @@>, box 3u + <@@ Checked.uint32 3I @@>, box 3u <@@ Checked.uint32 LanguagePrimitives.GenericOne @@>, box 1u <@@ Checked.uint32 LanguagePrimitives.GenericOne @@>, box 1u <@@ Checked.uint32 3.0M @@>, box 3u @@ -3909,6 +3969,8 @@ module WitnessTests = <@@ int64 '\003' @@>, box 3L <@@ int64 3.0f @@>, box 3L <@@ int64 3.0 @@>, box 3L + <@@ int64 3.0 @@>, box 3L + <@@ int64 3I @@>, box 3L <@@ int64 LanguagePrimitives.GenericOne @@>, box 1L <@@ int64 LanguagePrimitives.GenericOne @@>, box 1L <@@ int64 3.0M @@>, box 3L @@ -3924,6 +3986,8 @@ module WitnessTests = <@@ Checked.int64 '\003' @@>, box 3L <@@ Checked.int64 3.0f @@>, box 3L <@@ Checked.int64 3.0 @@>, box 3L + <@@ Checked.int64 3.0 @@>, box 3L + <@@ Checked.int64 3I @@>, box 3L <@@ Checked.int64 LanguagePrimitives.GenericOne @@>, box 1L <@@ Checked.int64 LanguagePrimitives.GenericOne @@>, box 1L <@@ Checked.int64 3.0M @@>, box 3L @@ -3940,6 +4004,8 @@ module WitnessTests = <@@ uint64 '\003' @@>, box 3UL <@@ uint64 3.0f @@>, box 3UL <@@ uint64 3.0 @@>, box 3UL + <@@ uint64 3.0 @@>, box 3UL + <@@ uint64 3I @@>, box 3UL <@@ uint64 LanguagePrimitives.GenericOne @@>, box 1UL <@@ uint64 LanguagePrimitives.GenericOne @@>, box 1UL <@@ uint64 3.0M @@>, box 3UL @@ -3955,6 +4021,8 @@ module WitnessTests = <@@ Checked.uint64 '\003' @@>, box 3UL <@@ Checked.uint64 3.0f @@>, box 3UL <@@ Checked.uint64 3.0 @@>, box 3UL + <@@ Checked.uint64 3.0 @@>, box 3UL + <@@ Checked.uint64 3I @@>, box 3UL <@@ Checked.uint64 LanguagePrimitives.GenericOne @@>, box 1UL <@@ Checked.uint64 LanguagePrimitives.GenericOne @@>, box 1UL <@@ Checked.uint64 3.0M @@>, box 3UL @@ -3971,6 +4039,7 @@ module WitnessTests = <@@ char '3' @@>, box '3' <@@ char 51.0f @@>, box '3' <@@ char 51.0 @@>, box '3' + <@@ char 51.0 @@>, box '3' <@@ char LanguagePrimitives.GenericOne @@>, box '\001' <@@ char LanguagePrimitives.GenericOne @@>, box '\001' <@@ char 51.0M @@>, box '3' @@ -3986,6 +4055,7 @@ module WitnessTests = <@@ Checked.char '3' @@>, box '3' <@@ Checked.char 51.0f @@>, box '3' <@@ Checked.char 51.0 @@>, box '3' + <@@ Checked.char 51.0 @@>, box '3' <@@ Checked.char LanguagePrimitives.GenericOne @@>, box '\001' <@@ Checked.char LanguagePrimitives.GenericOne @@>, box '\001' <@@ Checked.char 51.0M @@>, box '3' @@ -4002,6 +4072,7 @@ module WitnessTests = <@@ nativeint '\003' @@>, box 3n <@@ nativeint 3.0f @@>, box 3n <@@ nativeint 3.0 @@>, box 3n + <@@ nativeint 3.0 @@>, box 3n <@@ nativeint LanguagePrimitives.GenericOne @@>, box 1n <@@ nativeint LanguagePrimitives.GenericOne @@>, box 1n <@@ nativeint 3.0M @@>, box 3n @@ -4017,6 +4088,7 @@ module WitnessTests = <@@ Checked.nativeint '\003' @@>, box 3n <@@ Checked.nativeint 3.0f @@>, box 3n <@@ Checked.nativeint 3.0 @@>, box 3n + <@@ Checked.nativeint 3.0 @@>, box 3n <@@ Checked.nativeint LanguagePrimitives.GenericOne @@>, box 1n <@@ Checked.nativeint LanguagePrimitives.GenericOne @@>, box 1n <@@ Checked.nativeint 3.0M @@>, box 3n @@ -4033,6 +4105,7 @@ module WitnessTests = <@@ unativeint '\003' @@>, box 3un <@@ unativeint 3.0f @@>, box 3un <@@ unativeint 3.0 @@>, box 3un + <@@ unativeint 3.0 @@>, box 3un <@@ unativeint LanguagePrimitives.GenericOne @@>, box 1un <@@ unativeint LanguagePrimitives.GenericOne @@>, box 1un <@@ unativeint 3.0M @@>, box 3un @@ -4048,6 +4121,7 @@ module WitnessTests = <@@ Checked.unativeint '\003' @@>, box 3un <@@ Checked.unativeint 3.0f @@>, box 3un <@@ Checked.unativeint 3.0 @@>, box 3un + <@@ Checked.unativeint 3.0 @@>, box 3un <@@ Checked.unativeint LanguagePrimitives.GenericOne @@>, box 1un <@@ Checked.unativeint LanguagePrimitives.GenericOne @@>, box 1un <@@ Checked.unativeint 3.0M @@>, box 3un @@ -4064,6 +4138,8 @@ module WitnessTests = <@@ single '\003' @@>, box 3f <@@ single 3.0f @@>, box 3f <@@ single 3.0 @@>, box 3f + <@@ single 3.0 @@>, box 3f + <@@ single 3I @@>, box 3f <@@ single LanguagePrimitives.GenericOne @@>, box 1f <@@ single LanguagePrimitives.GenericOne @@>, box 1f <@@ single 3.0M @@>, box 3f @@ -4079,6 +4155,8 @@ module WitnessTests = <@@ float32 '\003' @@>, box 3f <@@ float32 3.0f @@>, box 3f <@@ float32 3.0 @@>, box 3f + <@@ float32 3.0 @@>, box 3f + <@@ float32 3I @@>, box 3f <@@ float32 LanguagePrimitives.GenericOne @@>, box 1f <@@ float32 LanguagePrimitives.GenericOne @@>, box 1f <@@ float32 3.0M @@>, box 3f @@ -4095,6 +4173,8 @@ module WitnessTests = <@@ double '\003' @@>, box 3. <@@ double 3.0f @@>, box 3. <@@ double 3.0 @@>, box 3. + <@@ double 3.0 @@>, box 3. + <@@ double 3I @@>, box 3. <@@ double LanguagePrimitives.GenericOne @@>, box 1. <@@ double LanguagePrimitives.GenericOne @@>, box 1. <@@ double 3.0M @@>, box 3. @@ -4110,6 +4190,8 @@ module WitnessTests = <@@ float '\003' @@>, box 3. <@@ float 3.0f @@>, box 3. <@@ float 3.0 @@>, box 3. + <@@ float 3.0 @@>, box 3. + <@@ float 3I @@>, box 3. <@@ float LanguagePrimitives.GenericOne @@>, box 1. <@@ float LanguagePrimitives.GenericOne @@>, box 1. <@@ float 3.0M @@>, box 3. @@ -4126,34 +4208,65 @@ module WitnessTests = <@@ decimal '\003' @@>, box 3m <@@ decimal 3.0f @@>, box 3m <@@ decimal 3.0 @@>, box 3m + <@@ decimal 3.0 @@>, box 3m + <@@ decimal 3I @@>, box 3m <@@ decimal LanguagePrimitives.GenericOne @@>, box 1m <@@ decimal LanguagePrimitives.GenericOne @@>, box 1m <@@ decimal 3.0M @@>, box 3m <@@ decimal "3" @@>, box 3m + <@@ LanguagePrimitives.GenericZero @@>, box 0uy + <@@ LanguagePrimitives.GenericZero @@>, box 0uy + <@@ LanguagePrimitives.GenericZero @@>, box 0y + <@@ LanguagePrimitives.GenericZero @@>, box 0y + <@@ LanguagePrimitives.GenericZero @@>, box 0s + <@@ LanguagePrimitives.GenericZero @@>, box 0us <@@ LanguagePrimitives.GenericZero @@>, box 0 + <@@ LanguagePrimitives.GenericZero @@>, box 0 + <@@ LanguagePrimitives.GenericZero @@>, box 0u + <@@ LanguagePrimitives.GenericZero @@>, box 0u <@@ LanguagePrimitives.GenericZero @@>, box 0L <@@ LanguagePrimitives.GenericZero @@>, box 0UL + <@@ LanguagePrimitives.GenericZero @@>, box 0I <@@ LanguagePrimitives.GenericZero @@>, box '\000' <@@ LanguagePrimitives.GenericZero @@>, box 0n <@@ LanguagePrimitives.GenericZero @@>, box 0un <@@ LanguagePrimitives.GenericZero @@>, box 0f <@@ LanguagePrimitives.GenericZero @@>, box 0. + <@@ LanguagePrimitives.GenericZero @@>, box 0m + <@@ LanguagePrimitives.GenericZero> @@>, box 0m + + <@@ LanguagePrimitives.GenericOne @@>, box 1uy + <@@ LanguagePrimitives.GenericOne @@>, box 1uy + <@@ LanguagePrimitives.GenericOne @@>, box 1y + <@@ LanguagePrimitives.GenericOne @@>, box 1y + <@@ LanguagePrimitives.GenericOne @@>, box 1s + <@@ LanguagePrimitives.GenericOne @@>, box 1us <@@ LanguagePrimitives.GenericOne @@>, box 1 + <@@ LanguagePrimitives.GenericOne @@>, box 1 + <@@ LanguagePrimitives.GenericOne @@>, box 1u + <@@ LanguagePrimitives.GenericOne @@>, box 1u <@@ LanguagePrimitives.GenericOne @@>, box 1L <@@ LanguagePrimitives.GenericOne @@>, box 1UL + <@@ LanguagePrimitives.GenericOne @@>, box 1I <@@ LanguagePrimitives.GenericOne @@>, box '\001' <@@ LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne @@>, box 1un <@@ LanguagePrimitives.GenericOne @@>, box 1f <@@ LanguagePrimitives.GenericOne @@>, box 1. + <@@ LanguagePrimitives.GenericOne @@>, box 1m + <@@ LanguagePrimitives.GenericOne> @@>, box 1m + <@@ List.sum [ 1; 2 ] @@>, box 3 + <@@ List.sum [ 1I; 2I ] @@>, box 3I <@@ List.sum [ 1.0f; 2.0f ] @@>, box 3f <@@ List.sum [ 1.0; 2.0 ] @@>, box 3. <@@ List.sum [ 1.0M; 2.0M ] @@>, box 3m + <@@ List.sum [ 1.0M; 2.0M ] @@>, box 3m <@@ List.average [ 1.0; 2.0 ] @@>, box 1.5 <@@ List.average [ 1.0f; 2.0f ] @@>, box 1.5f <@@ List.average [ 1.0M; 2.0M ] @@>, box 1.5m + <@@ List.average [ 1.0M; 2.0M ] @@>, box 1.5m <@@ Nullable.byte (Nullable<_> 3uy) @@>, box 3uy <@@ Nullable.byte (Nullable<_> 3y) @@>, box 3uy @@ -4166,6 +4279,8 @@ module WitnessTests = <@@ Nullable.byte (Nullable<_> '\003') @@>, box 3uy <@@ Nullable.byte (Nullable<_> 3.0f) @@>, box 3uy <@@ Nullable.byte (Nullable<_> 3.0) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3.0) @@>, box 3uy + <@@ Nullable.byte (Nullable<_> 3I) @@>, box 3uy <@@ Nullable.byte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy <@@ Nullable.byte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy <@@ Nullable.byte (Nullable<_> 3.0M) @@>, box 3uy @@ -4180,6 +4295,8 @@ module WitnessTests = <@@ Nullable.uint8 (Nullable<_> '\003') @@>, box 3uy <@@ Nullable.uint8 (Nullable<_> 3.0f) @@>, box 3uy <@@ Nullable.uint8 (Nullable<_> 3.0) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3.0) @@>, box 3uy + <@@ Nullable.uint8 (Nullable<_> 3I) @@>, box 3uy <@@ Nullable.uint8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy <@@ Nullable.uint8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1uy <@@ Nullable.uint8 (Nullable<_> 3.0M) @@>, box 3uy @@ -4195,6 +4312,8 @@ module WitnessTests = <@@ Nullable.sbyte (Nullable<_> '\003') @@>, box 3y <@@ Nullable.sbyte (Nullable<_> 3.0f) @@>, box 3y <@@ Nullable.sbyte (Nullable<_> 3.0) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3.0) @@>, box 3y + <@@ Nullable.sbyte (Nullable<_> 3I) @@>, box 3y <@@ Nullable.sbyte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y <@@ Nullable.sbyte (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y <@@ Nullable.sbyte (Nullable<_> 3.0M) @@>, box 3y @@ -4209,6 +4328,8 @@ module WitnessTests = <@@ Nullable.int8 (Nullable<_> '\003') @@>, box 3y <@@ Nullable.int8 (Nullable<_> 3.0f) @@>, box 3y <@@ Nullable.int8 (Nullable<_> 3.0) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3.0) @@>, box 3y + <@@ Nullable.int8 (Nullable<_> 3I) @@>, box 3y <@@ Nullable.int8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y <@@ Nullable.int8 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1y <@@ Nullable.int8 (Nullable<_> 3.0M) @@>, box 3y @@ -4224,6 +4345,8 @@ module WitnessTests = <@@ Nullable.int16 (Nullable<_> '\003') @@>, box 3s <@@ Nullable.int16 (Nullable<_> 3.0f) @@>, box 3s <@@ Nullable.int16 (Nullable<_> 3.0) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3.0) @@>, box 3s + <@@ Nullable.int16 (Nullable<_> 3I) @@>, box 3s <@@ Nullable.int16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1s <@@ Nullable.int16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1s <@@ Nullable.int16 (Nullable<_> 3.0M) @@>, box 3s @@ -4239,6 +4362,8 @@ module WitnessTests = <@@ Nullable.uint16 (Nullable<_> '\003') @@>, box 3us <@@ Nullable.uint16 (Nullable<_> 3.0f) @@>, box 3us <@@ Nullable.uint16 (Nullable<_> 3.0) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3.0) @@>, box 3us + <@@ Nullable.uint16 (Nullable<_> 3I) @@>, box 3us <@@ Nullable.uint16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1us <@@ Nullable.uint16 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1us <@@ Nullable.uint16 (Nullable<_> 3.0M) @@>, box 3us @@ -4254,6 +4379,8 @@ module WitnessTests = <@@ Nullable.int (Nullable<_> '\003') @@>, box 3 <@@ Nullable.int (Nullable<_> 3.0f) @@>, box 3 <@@ Nullable.int (Nullable<_> 3.0) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3.0) @@>, box 3 + <@@ Nullable.int (Nullable<_> 3I) @@>, box 3 <@@ Nullable.int (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 <@@ Nullable.int (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 <@@ Nullable.int (Nullable<_> 3.0M) @@>, box 3 @@ -4268,6 +4395,8 @@ module WitnessTests = <@@ Nullable.int32 (Nullable<_> '\003') @@>, box 3 <@@ Nullable.int32 (Nullable<_> 3.0f) @@>, box 3 <@@ Nullable.int32 (Nullable<_> 3.0) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3.0) @@>, box 3 + <@@ Nullable.int32 (Nullable<_> 3I) @@>, box 3 <@@ Nullable.int32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 <@@ Nullable.int32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1 <@@ Nullable.int32 (Nullable<_> 3.0M) @@>, box 3 @@ -4283,6 +4412,8 @@ module WitnessTests = <@@ Nullable.uint (Nullable<_> '\003') @@>, box 3u <@@ Nullable.uint (Nullable<_> 3.0f) @@>, box 3u <@@ Nullable.uint (Nullable<_> 3.0) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3.0) @@>, box 3u + <@@ Nullable.uint (Nullable<_> 3I) @@>, box 3u <@@ Nullable.uint (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u <@@ Nullable.uint (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u <@@ Nullable.uint (Nullable<_> 3.0M) @@>, box 3u @@ -4297,6 +4428,8 @@ module WitnessTests = <@@ Nullable.uint32 (Nullable<_> '\003') @@>, box 3u <@@ Nullable.uint32 (Nullable<_> 3.0f) @@>, box 3u <@@ Nullable.uint32 (Nullable<_> 3.0) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3.0) @@>, box 3u + <@@ Nullable.uint32 (Nullable<_> 3I) @@>, box 3u <@@ Nullable.uint32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u <@@ Nullable.uint32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1u <@@ Nullable.uint32 (Nullable<_> 3.0M) @@>, box 3u @@ -4312,6 +4445,8 @@ module WitnessTests = <@@ Nullable.int64 (Nullable<_> '\003') @@>, box 3L <@@ Nullable.int64 (Nullable<_> 3.0f) @@>, box 3L <@@ Nullable.int64 (Nullable<_> 3.0) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3.0) @@>, box 3L + <@@ Nullable.int64 (Nullable<_> 3I) @@>, box 3L <@@ Nullable.int64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1L <@@ Nullable.int64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1L <@@ Nullable.int64 (Nullable<_> 3.0M) @@>, box 3L @@ -4327,6 +4462,8 @@ module WitnessTests = <@@ Nullable.uint64 (Nullable<_> '\003') @@>, box 3UL <@@ Nullable.uint64 (Nullable<_> 3.0f) @@>, box 3UL <@@ Nullable.uint64 (Nullable<_> 3.0) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3.0) @@>, box 3UL + <@@ Nullable.uint64 (Nullable<_> 3I) @@>, box 3UL <@@ Nullable.uint64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1UL <@@ Nullable.uint64 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1UL <@@ Nullable.uint64 (Nullable<_> 3.0M) @@>, box 3UL @@ -4342,6 +4479,7 @@ module WitnessTests = <@@ Nullable.char (Nullable<_> '3') @@>, box '3' <@@ Nullable.char (Nullable<_> 51.0f) @@>, box '3' <@@ Nullable.char (Nullable<_> 51.0) @@>, box '3' + <@@ Nullable.char (Nullable<_> 51.0) @@>, box '3' <@@ Nullable.char (Nullable<_> LanguagePrimitives.GenericOne) @@>, box '\001' <@@ Nullable.char (Nullable<_> LanguagePrimitives.GenericOne) @@>, box '\001' <@@ Nullable.char (Nullable<_> 51.0M) @@>, box '3' @@ -4357,6 +4495,8 @@ module WitnessTests = <@@ Nullable.single (Nullable<_> '\003') @@>, box 3f <@@ Nullable.single (Nullable<_> 3.0f) @@>, box 3f <@@ Nullable.single (Nullable<_> 3.0) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3.0) @@>, box 3f + <@@ Nullable.single (Nullable<_> 3I) @@>, box 3f <@@ Nullable.single (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f <@@ Nullable.single (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f <@@ Nullable.single (Nullable<_> 3.0M) @@>, box 3f @@ -4371,6 +4511,8 @@ module WitnessTests = <@@ Nullable.float32 (Nullable<_> '\003') @@>, box 3f <@@ Nullable.float32 (Nullable<_> 3.0f) @@>, box 3f <@@ Nullable.float32 (Nullable<_> 3.0) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3.0) @@>, box 3f + <@@ Nullable.float32 (Nullable<_> 3I) @@>, box 3f <@@ Nullable.float32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f <@@ Nullable.float32 (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1f <@@ Nullable.float32 (Nullable<_> 3.0M) @@>, box 3f @@ -4386,6 +4528,8 @@ module WitnessTests = <@@ Nullable.double (Nullable<_> '\003') @@>, box 3. <@@ Nullable.double (Nullable<_> 3.0f) @@>, box 3. <@@ Nullable.double (Nullable<_> 3.0) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3.0) @@>, box 3. + <@@ Nullable.double (Nullable<_> 3I) @@>, box 3. <@@ Nullable.double (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. <@@ Nullable.double (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. <@@ Nullable.double (Nullable<_> 3.0M) @@>, box 3. @@ -4400,6 +4544,8 @@ module WitnessTests = <@@ Nullable.float (Nullable<_> '\003') @@>, box 3. <@@ Nullable.float (Nullable<_> 3.0f) @@>, box 3. <@@ Nullable.float (Nullable<_> 3.0) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3.0) @@>, box 3. + <@@ Nullable.float (Nullable<_> 3I) @@>, box 3. <@@ Nullable.float (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. <@@ Nullable.float (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1. <@@ Nullable.float (Nullable<_> 3.0M) @@>, box 3. @@ -4415,6 +4561,8 @@ module WitnessTests = <@@ Nullable.decimal (Nullable<_> '\003') @@>, box 3m <@@ Nullable.decimal (Nullable<_> 3.0f) @@>, box 3m <@@ Nullable.decimal (Nullable<_> 3.0) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3.0) @@>, box 3m + <@@ Nullable.decimal (Nullable<_> 3I) @@>, box 3m <@@ Nullable.decimal (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1m <@@ Nullable.decimal (Nullable<_> LanguagePrimitives.GenericOne) @@>, box 1m <@@ Nullable.decimal (Nullable<_> 3.0M) @@>, box 3m @@ -4430,6 +4578,8 @@ module WitnessTests = <@@ Nullable<_> 1.0f ?+ 4.0f @@>, box 5f <@@ Nullable<_> 1.0 ?+ 4.0 @@>, box 5. <@@ Nullable<_> 1m ?+ 4m @@>, box 5m + <@@ Nullable<_> 1m ?+ 4m @@>, box 5m + <@@ Nullable<_> 1I ?+ 4I @@>, box 5I <@@ Nullable<_> '1' ?+ '\004' @@>, box '5' <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box 2n <@@ Nullable<_> LanguagePrimitives.GenericOne ?+ LanguagePrimitives.GenericOne @@>, box 2un @@ -4445,6 +4595,8 @@ module WitnessTests = <@@ 1.0f +? Nullable<_> 4.0f @@>, box 5f <@@ 1.0 +? Nullable<_> 4.0 @@>, box 5. <@@ 1m +? Nullable<_> 4m @@>, box 5m + <@@ 1m +? Nullable<_> 4m @@>, box 5m + <@@ 1I +? Nullable<_> 4I @@>, box 5I <@@ '1' +? Nullable<_> '\004' @@>, box '5' <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2n <@@ LanguagePrimitives.GenericOne +? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2un @@ -4460,6 +4612,8 @@ module WitnessTests = <@@ Nullable<_> 1.0f ?+? Nullable<_> 4.0f @@>, box 5f <@@ Nullable<_> 1.0 ?+? Nullable<_> 4.0 @@>, box 5. <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, box 5m + <@@ Nullable<_> 1m ?+? Nullable<_> 4m @@>, box 5m + <@@ Nullable<_> 1I ?+? Nullable<_> 4I @@>, box 5I <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, box '5' <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2n <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2un @@ -4514,6 +4668,8 @@ module WitnessTests = <@@ 3f = 3f @@>, box true <@@ 3. = 3. @@>, box true <@@ 3m = 3m @@>, box true + <@@ 3m = 3m @@>, box true + <@@ 3I = 3I @@>, box true <@@ "3" = "3" @@>, box true <@@ [3] = [3] @@>, box false // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. <@@ [|3|] = [|3|] @@>, box false // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. @@ -4533,6 +4689,8 @@ module WitnessTests = <@@ 3f <> 3f @@>, box false <@@ 3. <> 3. @@>, box false <@@ 3m <> 3m @@>, box false + <@@ 3m <> 3m @@>, box false + <@@ 3I <> 3I @@>, box false <@@ "3" <> "3" @@>, box false <@@ [3] <> [3] @@>, box true // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. <@@ [|3|] <> [|3|] @@>, box true // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. @@ -4552,6 +4710,8 @@ module WitnessTests = <@@ 3f <= 3f @@>, box true <@@ 3. <= 3. @@>, box true <@@ 3m <= 3m @@>, box true + <@@ 3m <= 3m @@>, box true + <@@ 3I <= 3I @@>, box true <@@ "3" <= "3" @@>, box true <@@ [3] <= [3] @@>, box true <@@ [|3|] <= [|3|] @@>, box true @@ -4570,6 +4730,8 @@ module WitnessTests = <@@ 3f < 3f @@>, box false <@@ 3. < 3. @@>, box false <@@ 3m < 3m @@>, box false + <@@ 3m < 3m @@>, box false + <@@ 3I < 3I @@>, box false <@@ "3" < "3" @@>, box false <@@ [3] < [3] @@>, box false <@@ [|3|] < [|3|] @@>, box false @@ -4588,6 +4750,8 @@ module WitnessTests = <@@ 3f >= 3f @@>, box true <@@ 3. >= 3. @@>, box true <@@ 3m >= 3m @@>, box true + <@@ 3m >= 3m @@>, box true + <@@ 3I >= 3I @@>, box true <@@ "3" >= "3" @@>, box true <@@ [3] >= [3] @@>, box true <@@ [|3|] >= [|3|] @@>, box true @@ -4606,6 +4770,8 @@ module WitnessTests = <@@ 3f > 3f @@>, box false <@@ 3. > 3. @@>, box false <@@ 3m > 3m @@>, box false + <@@ 3m > 3m @@>, box false + <@@ 3I > 3I @@>, box false <@@ "3" > "3" @@>, box false <@@ [3] > [3] @@>, box false <@@ [|3|] > [|3|] @@>, box false @@ -4621,6 +4787,8 @@ module WitnessTests = <@@ Nullable<_> 1.0f ?= 1.0f @@>, box true <@@ Nullable<_> 1.0 ?= 1.0 @@>, box true <@@ Nullable<_> 1m ?= 1m @@>, box true + <@@ Nullable<_> 1m ?= 1m @@>, box true + <@@ Nullable<_> 1I ?= 1I @@>, box true <@@ Nullable<_> '1' ?= '1' @@>, box true <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box true <@@ Nullable<_> LanguagePrimitives.GenericOne ?= LanguagePrimitives.GenericOne @@>, box true @@ -4636,6 +4804,8 @@ module WitnessTests = <@@ 1.0f =? Nullable<_> 1.0f @@>, box true <@@ 1.0 =? Nullable<_> 1.0 @@>, box true <@@ 1m =? Nullable<_> 1m @@>, box true + <@@ 1m =? Nullable<_> 1m @@>, box true + <@@ 1I =? Nullable<_> 1I @@>, box true <@@ '1' =? Nullable<_> '1' @@>, box true <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box true <@@ LanguagePrimitives.GenericOne =? Nullable<_> LanguagePrimitives.GenericOne @@>, box true @@ -4651,6 +4821,8 @@ module WitnessTests = <@@ Nullable<_> 1.0f ?=? Nullable<_> 1.0f @@>, box true <@@ Nullable<_> 1.0 ?=? Nullable<_> 1.0 @@>, box true <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, box true + <@@ Nullable<_> 1m ?=? Nullable<_> 1m @@>, box true + <@@ Nullable<_> 1I ?=? Nullable<_> 1I @@>, box true <@@ Nullable<_> '1' ?=? Nullable<_> '1' @@>, box true <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true <@@ Nullable<_> LanguagePrimitives.GenericOne ?=? Nullable<_> LanguagePrimitives.GenericOne @@>, box true @@ -4669,6 +4841,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?<> 3f @@>, box false <@@ Nullable<_> 3. ?<> 3. @@>, box false <@@ Nullable<_> 3m ?<> 3m @@>, box false + <@@ Nullable<_> 3m ?<> 3m @@>, box false + <@@ Nullable<_> 3I ?<> 3I @@>, box false <@@ 3y <>? Nullable<_> 3y @@>, box false <@@ 3uy <>? Nullable<_> 3uy @@>, box false @@ -4684,6 +4858,8 @@ module WitnessTests = <@@ 3f <>? Nullable<_> 3f @@>, box false <@@ 3. <>? Nullable<_> 3. @@>, box false <@@ 3m <>? Nullable<_> 3m @@>, box false + <@@ 3m <>? Nullable<_> 3m @@>, box false + <@@ 3I <>? Nullable<_> 3I @@>, box false <@@ Nullable<_> 3y ?<>? Nullable<_> 3y @@>, box false <@@ Nullable<_> 3uy ?<>? Nullable<_> 3uy @@>, box false @@ -4699,6 +4875,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?<>? Nullable<_> 3f @@>, box false <@@ Nullable<_> 3. ?<>? Nullable<_> 3. @@>, box false <@@ Nullable<_> 3m ?<>? Nullable<_> 3m @@>, box false + <@@ Nullable<_> 3m ?<>? Nullable<_> 3m @@>, box false + <@@ Nullable<_> 3I ?<>? Nullable<_> 3I @@>, box false <@@ Nullable<_> 3y ?<= 3y @@>, box true <@@ Nullable<_> 3uy ?<= 3uy @@>, box true @@ -4714,6 +4892,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?<= 3f @@>, box true <@@ Nullable<_> 3. ?<= 3. @@>, box true <@@ Nullable<_> 3m ?<= 3m @@>, box true + <@@ Nullable<_> 3m ?<= 3m @@>, box true + <@@ Nullable<_> 3I ?<= 3I @@>, box true <@@ 3y <=? Nullable<_> 3y @@>, box true <@@ 3uy <=? Nullable<_> 3uy @@>, box true @@ -4729,6 +4909,8 @@ module WitnessTests = <@@ 3f <=? Nullable<_> 3f @@>, box true <@@ 3. <=? Nullable<_> 3. @@>, box true <@@ 3m <=? Nullable<_> 3m @@>, box true + <@@ 3m <=? Nullable<_> 3m @@>, box true + <@@ 3I <=? Nullable<_> 3I @@>, box true <@@ Nullable<_> 3y ?<=? Nullable<_> 3y @@>, box true <@@ Nullable<_> 3uy ?<=? Nullable<_> 3uy @@>, box true @@ -4744,6 +4926,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?<=? Nullable<_> 3f @@>, box true <@@ Nullable<_> 3. ?<=? Nullable<_> 3. @@>, box true <@@ Nullable<_> 3m ?<=? Nullable<_> 3m @@>, box true + <@@ Nullable<_> 3m ?<=? Nullable<_> 3m @@>, box true + <@@ Nullable<_> 3I ?<=? Nullable<_> 3I @@>, box true <@@ Nullable<_> 3y ?< 3y @@>, box false <@@ Nullable<_> 3uy ?< 3uy @@>, box false @@ -4759,6 +4943,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?< 3f @@>, box false <@@ Nullable<_> 3. ?< 3. @@>, box false <@@ Nullable<_> 3m ?< 3m @@>, box false + <@@ Nullable<_> 3m ?< 3m @@>, box false + <@@ Nullable<_> 3I ?< 3I @@>, box false <@@ 3y 3y @@>, box false <@@ 3uy 3uy @@>, box false @@ -4774,6 +4960,8 @@ module WitnessTests = <@@ 3f 3f @@>, box false <@@ 3. 3. @@>, box false <@@ 3m 3m @@>, box false + <@@ 3m 3m @@>, box false + <@@ 3I 3I @@>, box false <@@ Nullable<_> 3y ? 3y @@>, box false <@@ Nullable<_> 3uy ? 3uy @@>, box false @@ -4789,6 +4977,8 @@ module WitnessTests = <@@ Nullable<_> 3f ? 3f @@>, box false <@@ Nullable<_> 3. ? 3. @@>, box false <@@ Nullable<_> 3m ? 3m @@>, box false + <@@ Nullable<_> 3m ? 3m @@>, box false + <@@ Nullable<_> 3I ? 3I @@>, box false <@@ Nullable<_> 3y ?>= 3y @@>, box true <@@ Nullable<_> 3uy ?>= 3uy @@>, box true @@ -4804,6 +4994,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?>= 3f @@>, box true <@@ Nullable<_> 3. ?>= 3. @@>, box true <@@ Nullable<_> 3m ?>= 3m @@>, box true + <@@ Nullable<_> 3m ?>= 3m @@>, box true + <@@ Nullable<_> 3I ?>= 3I @@>, box true <@@ 3y >=? Nullable<_> 3y @@>, box true <@@ 3uy >=? Nullable<_> 3uy @@>, box true @@ -4819,6 +5011,8 @@ module WitnessTests = <@@ 3f >=? Nullable<_> 3f @@>, box true <@@ 3. >=? Nullable<_> 3. @@>, box true <@@ 3m >=? Nullable<_> 3m @@>, box true + <@@ 3m >=? Nullable<_> 3m @@>, box true + <@@ 3I >=? Nullable<_> 3I @@>, box true <@@ Nullable<_> 3y ?>=? Nullable<_> 3y @@>, box true <@@ Nullable<_> 3uy ?>=? Nullable<_> 3uy @@>, box true @@ -4834,6 +5028,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?>=? Nullable<_> 3f @@>, box true <@@ Nullable<_> 3. ?>=? Nullable<_> 3. @@>, box true <@@ Nullable<_> 3m ?>=? Nullable<_> 3m @@>, box true + <@@ Nullable<_> 3m ?>=? Nullable<_> 3m @@>, box true + <@@ Nullable<_> 3I ?>=? Nullable<_> 3I @@>, box true <@@ Nullable<_> 3y ?> 3y @@>, box false <@@ Nullable<_> 3uy ?> 3uy @@>, box false @@ -4849,6 +5045,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?> 3f @@>, box false <@@ Nullable<_> 3. ?> 3. @@>, box false <@@ Nullable<_> 3m ?> 3m @@>, box false + <@@ Nullable<_> 3m ?> 3m @@>, box false + <@@ Nullable<_> 3I ?> 3I @@>, box false <@@ 3y >? Nullable<_> 3y @@>, box false <@@ 3uy >? Nullable<_> 3uy @@>, box false @@ -4864,6 +5062,8 @@ module WitnessTests = <@@ 3f >? Nullable<_> 3f @@>, box false <@@ 3. >? Nullable<_> 3. @@>, box false <@@ 3m >? Nullable<_> 3m @@>, box false + <@@ 3m >? Nullable<_> 3m @@>, box false + <@@ 3I >? Nullable<_> 3I @@>, box false <@@ Nullable<_> 3y ?>? Nullable<_> 3y @@>, box false <@@ Nullable<_> 3uy ?>? Nullable<_> 3uy @@>, box false @@ -4879,6 +5079,8 @@ module WitnessTests = <@@ Nullable<_> 3f ?>? Nullable<_> 3f @@>, box false <@@ Nullable<_> 3. ?>? Nullable<_> 3. @@>, box false <@@ Nullable<_> 3m ?>? Nullable<_> 3m @@>, box false + <@@ Nullable<_> 3m ?>? Nullable<_> 3m @@>, box false + <@@ Nullable<_> 3I ?>? Nullable<_> 3I @@>, box false |] tests |> Array.map (fun (test, eval) -> From 9df2c8ea454ff44e40befcde1fc7a65938b13d28 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 8 Jul 2021 12:08:18 +0800 Subject: [PATCH 61/78] Update test.fsx --- tests/fsharp/core/quotes/test.fsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 9618e2a465a..ed36d5d9488 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3420,6 +3420,8 @@ module WitnessTests = <@@ Checked.(+) 1.0f 4.0f @@>, box 5f <@@ Checked.(+) 1.0 4.0 @@>, box 5. <@@ Checked.(+) 1m 4m @@>, box 5m + <@@ Checked.(+) 1m 4m @@>, box 5m + <@@ Checked.(+) 1I 4I @@>, box 5I <@@ Checked.(+) '1' '\004' @@>, box '5' <@@ Checked.(+) "abc" "def" @@>, box "abcdef" <@@ Checked.(+) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 2n @@ -3452,6 +3454,8 @@ module WitnessTests = <@@ Checked.(-) 4.0f 1.0f @@>, box 3f <@@ Checked.(-) 4.0 1.0 @@>, box 3. <@@ Checked.(-) 4m 1m @@>, box 3m + <@@ Checked.(-) 4m 1m @@>, box 3m + <@@ Checked.(-) 4I 1I @@>, box 3I <@@ Checked.(-) '4' '\001' @@>, box '3' <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 0n <@@ Checked.(-) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 0un @@ -3482,6 +3486,8 @@ module WitnessTests = <@@ Checked.(*) 2.0f 4.0f @@>, box 8f <@@ Checked.(*) 2.0 4.0 @@>, box 8. <@@ Checked.(*) 2m 4m @@>, box 8m + <@@ Checked.(*) 2m 4m @@>, box 8m + <@@ Checked.(*) 2I 4I @@>, box 8I <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 1n <@@ Checked.(*) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box 1un @@ -4255,7 +4261,7 @@ module WitnessTests = <@@ LanguagePrimitives.GenericOne @@>, box 1f <@@ LanguagePrimitives.GenericOne @@>, box 1. <@@ LanguagePrimitives.GenericOne @@>, box 1m - <@@ LanguagePrimitives.GenericOne> @@>, box 1m + //<@@ LanguagePrimitives.GenericOne> @@>, box 1m // Doesn't typecheck <@@ List.sum [ 1; 2 ] @@>, box 3 <@@ List.sum [ 1I; 2I ] @@>, box 3I From 1e34460ec44eeb8851e6de752606c69ffac55f90 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 8 Jul 2021 13:34:54 +0800 Subject: [PATCH 62/78] Oops wrong value --- tests/fsharp/core/quotes/test.fsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index ed36d5d9488..55516e27046 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -5105,7 +5105,7 @@ module WitnessTests = false | _ -> printfn "<-- Success, it did not match Quotations.Patterns.(|CallWithWitnesses|_|)" - false) |> Array.forall id) // Don't short circuit on a failed test + true) |> Array.forall id) // Don't short circuit on a failed test module MoreWitnessTests = open System.Runtime.CompilerServices From 68bae885bccc4940b043e9b76a949e51eb64f24e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 14 Jul 2021 18:46:28 +0800 Subject: [PATCH 63/78] More operations --- src/fsharp/FSharp.Core/Linq.fs | 439 ++++++++++++++++++------------ src/fsharp/FSharp.Core/Linq.fsi | 2 +- src/fsharp/FSharp.Core/Query.fs | 24 +- tests/fsharp/core/quotes/test.fsx | 305 ++++++++++++++++++++- 4 files changed, 575 insertions(+), 195 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index eb7dc9b6322..75e9fbc4073 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -75,6 +75,71 @@ module LeafExpressionConverter = let NullableConstructor = typedefof>.GetConstructors().[0] + + let arrayOf3StringTypes = [|typeof; typeof; typeof|] + + let getNonNullableType typ = match Nullable.GetUnderlyingType typ with null -> typ | t -> t + + // https://github.com/dotnet/runtime/blob/cf7e7a46f8a4a6225a8f1e059a846ccdebf0454c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L110 + /// Can LINQ Expressions' (UnaryExpression/BinaryExpression)'s arithmetic operations construct a (SimpleBinaryExpression/UnaryExpression) from the types in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsArithmeticType typ = + let typ = getNonNullableType typ + not typ.IsEnum && match Type.GetTypeCode typ with + | TypeCode.Int16 + | TypeCode.Int32 + | TypeCode.Int64 + | TypeCode.Double + | TypeCode.Single + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> true + | _ -> false + // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L132 + /// Can LINQ Expressions' UnaryExpression.(Checked)Negate construct a UnaryExpression from the types in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsArithmeticTypeButNotUnsignedInt typ = + isLinqExpressionsArithmeticType typ && + let typ = getNonNullableType typ + not typ.IsEnum && match Type.GetTypeCode typ with + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> false + | _ -> true + // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L149 + /// Can LINQ Expressions' UnaryExpression.Not construct a UnaryExpression from the types in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsIntegerOrBool typ = + let typ = getNonNullableType typ + not typ.IsEnum && match Type.GetTypeCode typ with + | TypeCode.Int64 + | TypeCode.Int32 + | TypeCode.Int16 + | TypeCode.UInt64 + | TypeCode.UInt32 + | TypeCode.UInt16 + | TypeCode.Boolean + | TypeCode.SByte + | TypeCode.Byte -> true + | _ -> false + // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L47 + /// Can LINQ Expressions' BinaryExpression's comparison operations construct a (SimpleBinaryExpression/LogicalBinaryExpression) from the types in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsNumeric typ = + let typ = getNonNullableType typ + not typ.IsEnum && match Type.GetTypeCode typ with + | TypeCode.Char + | TypeCode.SByte + | TypeCode.Byte + | TypeCode.Int16 + | TypeCode.Int32 + | TypeCode.Int64 + | TypeCode.Double + | TypeCode.Single + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> true + | _ -> false + // https://github.com/dotnet/runtime/blob/afaf666eff08435123eb649ac138419f4c9b9344/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1047 + /// Can LINQ Expressions' BinaryExpression's eqaulity operations provide built-in equality from the types in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsEquatable typ = + isLinqExpressionsNumeric typ || typ = typeof || typ = typeof || getNonNullableType(typ).IsEnum let SpecificCallToMethodInfo (minfo: System.Reflection.MethodInfo) = let isg1 = minfo.IsGenericMethod @@ -90,150 +155,150 @@ module LeafExpressionConverter = Some (obj, minfo2, args) | _ -> None) - let (|SpecificCallToMethod'|_|) (mhandle: System.RuntimeMethodHandle) = + let (|SpecificCallToMethod|_|) (mhandle: System.RuntimeMethodHandle) = let minfo = (System.Reflection.MethodInfo.GetMethodFromHandle mhandle) :?> MethodInfo SpecificCallToMethodInfo minfo - let (|SpecificCallToMethod|_|) (mhandle: System.RuntimeMethodHandle) = - (|SpecificCallToMethod'|_|) mhandle >> Option.map (fun (obj, minfo, args) -> obj, minfo.GetGenericArguments() |> Array.toList, args) - - 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.( ? 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.( 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 (|ConvIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Operators.nativeint x)) - let (|ConvUIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Operators.unativeint x)) + let (|SpecificCallToGenericMethod|_|) (mhandle: System.RuntimeMethodHandle) = + (|SpecificCallToMethod|_|) mhandle >> Option.map (fun (obj, minfo, args) -> obj, minfo.GetGenericArguments() |> Array.toList, args) + + 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.( ? 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.( 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 (|ConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.nativeint x)) + let (|ConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Operators.unativeint 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 (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Nullable.nativeint x)) - let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Nullable.unativeint x)) - - let (|UnboxGeneric|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.UnboxGeneric x)) - 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 (|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 (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.nativeint x)) + let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.unativeint x)) + + let (|UnboxGeneric|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.UnboxGeneric x)) + let (|TypeTestGeneric|_|) = (|SpecificCallToGenericMethod|_|) (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 (|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)) - let (|CheckedConvByteQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.byte x)) - let (|CheckedConvUInt16Q|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.uint16 x)) - let (|CheckedConvUInt32Q|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.uint32 x)) - let (|CheckedConvUInt64Q|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.uint64 x)) - let (|CheckedConvIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.nativeint x)) - let (|CheckedConvUIntPtrQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> Checked.unativeint x)) - let (|ImplicitExpressionConversionHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> ImplicitExpressionConversionHelper x)) - let (|MemberInitializationHelperQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> MemberInitializationHelper x)) - let (|NewAnonymousObjectHelperQ|_|) = (|SpecificCallToMethod'|_|) (methodhandleof (fun x -> NewAnonymousObjectHelper x)) - let (|ArrayLookupQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.IntrinsicFunctions.GetArray x y)) + 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)) + let (|CheckedConvByteQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.byte x)) + let (|CheckedConvUInt16Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint16 x)) + let (|CheckedConvUInt32Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint32 x)) + let (|CheckedConvUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint64 x)) + let (|CheckedConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.nativeint x)) + let (|CheckedConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.unativeint x)) + let (|ImplicitExpressionConversionHelperQ|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun x -> ImplicitExpressionConversionHelper x)) + let (|MemberInitializationHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> MemberInitializationHelper x)) + let (|NewAnonymousObjectHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> NewAnonymousObjectHelper x)) + let (|ArrayLookupQ|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.IntrinsicFunctions.GetArray x y)) //let (|ArrayAssignQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun -> LanguagePrimitives.IntrinsicFunctions.SetArray : int[] -> int -> int -> unit)) //let (|ArrayTypeQ|_|) (ty:System.Type) = if ty.IsArray && ty.GetArrayRank() = 1 then Some (ty.GetElementType()) else None @@ -360,52 +425,51 @@ module LeafExpressionConverter = Expression.New(ctor, argsR, [| for p in props -> (p :> MemberInfo) |]) |> asExpr // Do the same thing as C# compiler for string addition - | PlusQ (_, m, [x1; x2]) when - m.GetGenericArguments() = [|typeof; typeof; typeof|] -> + | PlusQ (_, m, [x1; x2]) when m.GetGenericArguments() = arrayOf3StringTypes -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr | GenericEqualityQ (_, m, [x1; x2]) - | EqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m - | NotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m - | GreaterQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThan m - | GreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m - | LessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m - | LessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m + | EqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.Equal m + | NotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.NotEqual m + | GreaterQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThan m + | GreaterEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThanOrEqual m + | LessQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThan m + | LessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThanOrEqual m | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m - | StaticNotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m - | StaticGreaterQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThan m - | StaticGreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m - | StaticLessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m - | StaticLessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m - - | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.Equal m - | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.NotEqual m - | NullableGreaterQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.GreaterThan m - | NullableGreaterEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.GreaterThanOrEqual m - | NullableLessQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.LessThan m - | NullableLessEqQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 true Expression.LessThanOrEqual m - - | EqualsNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.Equal m - | NotEqNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.NotEqual m - | GreaterNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.GreaterThan m - | GreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.GreaterThanOrEqual m - | LessNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.LessThan m - | LessEqNullableQ (_, m, [x1; x2]) -> transBoolOp env true x1 x2 false Expression.LessThanOrEqual m - - | NullableEqualsNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.Equal m - | NullableNotEqNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.NotEqual m - | NullableGreaterNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThan m - | NullableGreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.GreaterThanOrEqual m - | NullableLessNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThan m - | NullableLessEqNullableQ (_, m, [x1; x2]) -> transBoolOp env false x1 x2 false Expression.LessThanOrEqual m + | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env false x1 x2 false Expression.Equal (methodhandleof (fun x -> LanguagePrimitives.EqualityDynamic x)) + | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun x -> LanguagePrimitives.InequalityDynamic x)) + | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun x -> LanguagePrimitives.GreaterThanDynamic x)) + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.GreaterThanOrEqualDynamic x)) + | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.LessThan (methodhandleof (fun x -> LanguagePrimitives.LessThanDynamic x)) + | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.LessThanOrEqualDynamic x)) + + | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.Equal m + | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.NotEqual m + | NullableGreaterQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.GreaterThan m + | NullableGreaterEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.GreaterThanOrEqual m + | NullableLessQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.LessThan m + | NullableLessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.LessThanOrEqual m + + | EqualsNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.Equal m + | NotEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.NotEqual m + | GreaterNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.GreaterThan m + | GreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.GreaterThanOrEqual m + | LessNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.LessThan m + | LessEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.LessThanOrEqual m + + | NullableEqualsNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.Equal m + | NullableNotEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.NotEqual m + | NullableGreaterNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThan m + | NullableGreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThanOrEqual m + | NullableLessNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThan m + | NullableLessEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThanOrEqual m // 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 (_, _, [x]) -> transUnaryOp inp env x Expression.Negate (methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x)) + | NegQ (_, _, [x]) -> transUnaryOp isLinqExpressionsArithmeticTypeButNotUnsignedInt inp env x Expression.Negate (methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x)) | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) @@ -417,9 +481,9 @@ module LeafExpressionConverter = | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y)) | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y)) | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y)) - | BitwiseNotQ (_, _, [x]) -> transUnaryOp inp env x Expression.Not (methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x)) + | BitwiseNotQ (_, _, [x]) -> transUnaryOp isLinqExpressionsIntegerOrBool inp env x Expression.Not (methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x)) - | CheckedNeg (_, _, [x]) -> transUnaryOp inp env x Expression.NegateChecked (methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x)) + | CheckedNeg (_, _, [x]) -> transUnaryOp isLinqExpressionsArithmeticTypeButNotUnsignedInt inp env x Expression.NegateChecked (methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x)) | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y)) | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y)) | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y)) @@ -636,27 +700,27 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) - and transUnaryOp inp env x (exprErasedConstructor: _ * _ -> _) fallback = + and transUnaryOp linqExpressionsCondition inp env x (exprErasedConstructor: _ * _ -> _) fallback = let e = ConvExprToLinqInContext env x - try exprErasedConstructor(e, null) with _ -> - // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + if linqExpressionsCondition e.Type then + exprErasedConstructor(e, null) + else let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo - exprErasedConstructor(e, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) + exprErasedConstructor(e, method.MakeGenericMethod [| getNonNullableType x.Type; getNonNullableType inp.Type |]) |> asExpr and transBinOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = 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 - try exprErasedConstructor(e1, e2, null) with _ -> - // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + if e1.Type = e2.Type && isLinqExpressionsArithmeticType e1.Type then + exprErasedConstructor(e1, e2, null) + else let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo - exprErasedConstructor(e1, e2, method.MakeGenericMethod [| nullableUnderlyingType x1; nullableUnderlyingType x2; nullableUnderlyingType inp |]) + exprErasedConstructor(e1, e2, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) |> asExpr // Boolean equality / comparison operators do not take witnesses and the referenced methods are callable directly - and transBoolOp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = + and transBoolOpNoWitness env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = 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 @@ -665,6 +729,19 @@ module LeafExpressionConverter = // LINQ Expressions cannot recognize boolean operators on F# types that are not defined on the types themselves. In this case, use the F# operator as the user-defined method. exprErasedConstructor(e1, e2, false, method) |> asExpr + // But the static boolean operators do take witnesses! + and transBoolOp linqExpressionsCondition inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) fallback = + 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 + if e1.Type = e2.Type && linqExpressionsCondition e1.Type then + // The false for (liftToNull: bool) indicates whether equality operators return a Nullable like in VB.NET (null when either argument is null) instead of bool like in C# (nulls equate to nulls). F# follows C# here. + exprErasedConstructor(e1, e2, false, null) + else + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e1, e2, false, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) + |> asExpr and transConv (inp: Expr) env isChecked x = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert diff --git a/src/fsharp/FSharp.Core/Linq.fsi b/src/fsharp/FSharp.Core/Linq.fsi index cc62fe99b58..9c4cfa245ce 100644 --- a/src/fsharp/FSharp.Core/Linq.fsi +++ b/src/fsharp/FSharp.Core/Linq.fsi @@ -61,4 +61,4 @@ module LeafExpressionConverter = /// A runtime helper used to evaluate nested quotation literals. val SubstHelperRaw : Expr * Var[] * obj[] -> Expr - val internal (|SpecificCallToMethod|_|) : System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option) + val internal (|SpecificCallToGenericMethod|_|) : System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option) diff --git a/src/fsharp/FSharp.Core/Query.fs b/src/fsharp/FSharp.Core/Query.fs index 8d54ff85228..4aa1055db44 100644 --- a/src/fsharp/FSharp.Core/Query.fs +++ b/src/fsharp/FSharp.Core/Query.fs @@ -317,21 +317,21 @@ module Query = // Match 'f x' let (|SpecificCall1|_|) q = - let (|CallQ|_|) = (|SpecificCallToMethod|_|) q + let (|CallQ|_|) = (|SpecificCallToGenericMethod|_|) q function | CallQ (Some builderObj, tyargs, [arg1]) -> Some(builderObj, tyargs, arg1) | _ -> None // Match 'f x y' or 'f (x, y)' let (|SpecificCall2|_|) q = - let (|CallQ|_|) = (|SpecificCallToMethod|_|) q + let (|CallQ|_|) = (|SpecificCallToGenericMethod|_|) q function | CallQ (Some builderObj, tyargs, [arg1; arg2]) -> Some(builderObj, tyargs, arg1, arg2) | _ -> None // Match 'f x y z' or 'f (x, y, z)' let (|SpecificCall3|_|) q = - let (|CallQ|_|) = (|SpecificCallToMethod|_|) q + let (|CallQ|_|) = (|SpecificCallToGenericMethod|_|) q function | CallQ (Some builderObj, tyargs, [arg1; arg2; arg3]) -> Some(builderObj, tyargs, arg1, arg2, arg3) | _ -> None @@ -1040,19 +1040,19 @@ module Query = | MacroReduction reduced -> Some (walk reduced) | _ -> None) - let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b :QueryBuilder, v) -> b.Run v)) + let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b :QueryBuilder, v) -> b.Run v)) - let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr<'a>) -> b.Run v) : 'a) + let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr<'a>) -> b.Run v) : 'a) - let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr> ) -> b.Run v)) + let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr> ) -> b.Run v)) - let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder, source: QuerySource, body) -> b.For(source, body))) + let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b:QueryBuilder, source: QuerySource, body) -> b.For(source, body))) let (|CallQueryBuilderYield|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value) -> b.Yield value)) - let (|CallQueryBuilderYieldFrom|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder, values) -> b.YieldFrom values)) + let (|CallQueryBuilderYieldFrom|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b:QueryBuilder, values) -> b.YieldFrom values)) - let (|CallQueryBuilderZero|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder) -> b.Zero())) + let (|CallQueryBuilderZero|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b:QueryBuilder) -> b.Zero())) let (|CallQueryBuilderSourceIQueryable|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value: IQueryable<_>) -> b.Source value)) @@ -1118,11 +1118,11 @@ module Query = let (|CallSkipWhile|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2) -> query.SkipWhile(arg1, arg2))) - let (|CallJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.Join(arg1, arg2, arg3, arg4, arg5))) + let (|CallJoin|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.Join(arg1, arg2, arg3, arg4, arg5))) - let (|CallGroupJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.GroupJoin(arg1, arg2, arg3, arg4, arg5))) + let (|CallGroupJoin|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.GroupJoin(arg1, arg2, arg3, arg4, arg5))) - let (|CallLeftOuterJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.LeftOuterJoin(arg1, arg2, arg3, arg4, arg5))) + let (|CallLeftOuterJoin|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.LeftOuterJoin(arg1, arg2, arg3, arg4, arg5))) let (|CallAverageBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1: QuerySource, arg2:(double->double)) -> query.AverageBy(arg1, arg2))) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 55516e27046..7d77931d032 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -3471,7 +3471,7 @@ module WitnessTests = <@@ 2.0f * 4.0f @@>, box 8f <@@ 2.0 * 4.0 @@>, box 8. <@@ 2m * 4m @@>, box 8m - <@@ 2m * 4m @@>, box 8m + <@@ 2m * 4m @@>, box 8m <@@ 2I * 4I @@>, box 8I <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, box 1n <@@ LanguagePrimitives.GenericOne * LanguagePrimitives.GenericOne @@>, box 1un @@ -4623,6 +4623,309 @@ module WitnessTests = <@@ Nullable<_> '1' ?+? Nullable<_> '\004' @@>, box '5' <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2n <@@ Nullable<_> LanguagePrimitives.GenericOne ?+? Nullable<_> LanguagePrimitives.GenericOne @@>, box 2un + + <@@ Nullable<_> 4y ?- 1y @@>, box 3y + <@@ Nullable<_> 4uy ?- 1uy @@>, box 3uy + <@@ Nullable<_> 4s ?- 1s @@>, box 3s + <@@ Nullable<_> 4us ?- 1us @@>, box 3us + <@@ Nullable<_> 4 ?- 1 @@>, box 3 + <@@ Nullable<_> 4u ?- 1u @@>, box 3u + <@@ Nullable<_> 4L ?- 1L @@>, box 3L + <@@ Nullable<_> 4uL ?- 1uL @@>, box 3uL + <@@ Nullable<_> 4.0f ?- 1.0f @@>, box 3f + <@@ Nullable<_> 4.0 ?- 1.0 @@>, box 3. + <@@ Nullable<_> 4m ?- 1m @@>, box 3m + <@@ Nullable<_> 4m ?- 1m @@>, box 3m + <@@ Nullable<_> 4I ?- 1I @@>, box 3I + <@@ Nullable<_> '4' ?- '\001' @@>, box '3' + <@@ Nullable<_> LanguagePrimitives.GenericOne ?- LanguagePrimitives.GenericOne @@>, box 0n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?- LanguagePrimitives.GenericOne @@>, box 0un + + <@@ 4y -? Nullable<_> 1y @@>, box 3y + <@@ 4uy -? Nullable<_> 1uy @@>, box 3uy + <@@ 4s -? Nullable<_> 1s @@>, box 3s + <@@ 4us -? Nullable<_> 1us @@>, box 3us + <@@ 4 -? Nullable<_> 1 @@>, box 3 + <@@ 4u -? Nullable<_> 1u @@>, box 3u + <@@ 4L -? Nullable<_> 1L @@>, box 3L + <@@ 4uL -? Nullable<_> 1uL @@>, box 3uL + <@@ 4.0f -? Nullable<_> 1.0f @@>, box 3f + <@@ 4.0 -? Nullable<_> 1.0 @@>, box 3. + <@@ 4m -? Nullable<_> 1m @@>, box 3m + <@@ 4m -? Nullable<_> 1m @@>, box 3m + <@@ 4I -? Nullable<_> 1I @@>, box 3I + <@@ '4' -? Nullable<_> '\001' @@>, box '3' + <@@ LanguagePrimitives.GenericOne -? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0n + <@@ LanguagePrimitives.GenericOne -? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0un + + <@@ Nullable<_> 4y ?-? Nullable<_> 1y @@>, box 3y + <@@ Nullable<_> 4uy ?-? Nullable<_> 1uy @@>, box 3uy + <@@ Nullable<_> 4s ?-? Nullable<_> 1s @@>, box 3s + <@@ Nullable<_> 4us ?-? Nullable<_> 1us @@>, box 3us + <@@ Nullable<_> 4 ?-? Nullable<_> 1 @@>, box 3 + <@@ Nullable<_> 4u ?-? Nullable<_> 1u @@>, box 3u + <@@ Nullable<_> 4L ?-? Nullable<_> 1L @@>, box 3L + <@@ Nullable<_> 4uL ?-? Nullable<_> 1uL @@>, box 3uL + <@@ Nullable<_> 4.0f ?-? Nullable<_> 1.0f @@>, box 3f + <@@ Nullable<_> 4.0 ?-? Nullable<_> 1.0 @@>, box 3. + <@@ Nullable<_> 4m ?-? Nullable<_> 1m @@>, box 3m + <@@ Nullable<_> 4m ?-? Nullable<_> 1m @@>, box 3m + <@@ Nullable<_> 4I ?-? Nullable<_> 1I @@>, box 3I + <@@ Nullable<_> '4' ?-? Nullable<_> '\001' @@>, box '3' + <@@ Nullable<_> LanguagePrimitives.GenericOne ?-? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?-? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0un + + <@@ Nullable<_> 2y ?* 4y @@>, box 8y + <@@ Nullable<_> 2uy ?* 4uy @@>, box 8uy + <@@ Nullable<_> 2s ?* 4s @@>, box 8s + <@@ Nullable<_> 2us ?* 4us @@>, box 8us + <@@ Nullable<_> 2 ?* 4 @@>, box 8 + <@@ Nullable<_> 2u ?* 4u @@>, box 8u + <@@ Nullable<_> 2L ?* 4L @@>, box 8L + <@@ Nullable<_> 2uL ?* 4uL @@>, box 8uL + <@@ Nullable<_> 2.0f ?* 4.0f @@>, box 8f + <@@ Nullable<_> 2.0 ?* 4.0 @@>, box 8. + <@@ Nullable<_> 2m ?* 4m @@>, box 8m + <@@ Nullable<_> 2m ?* 4m @@>, box 8m + <@@ Nullable<_> 2I ?* 4I @@>, box 8I + <@@ Nullable<_> LanguagePrimitives.GenericOne ?* LanguagePrimitives.GenericOne @@>, box 1n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?* LanguagePrimitives.GenericOne @@>, box 1un + + <@@ 2y *? Nullable<_> 4y @@>, box 8y + <@@ 2uy *? Nullable<_> 4uy @@>, box 8uy + <@@ 2s *? Nullable<_> 4s @@>, box 8s + <@@ 2us *? Nullable<_> 4us @@>, box 8us + <@@ 2 *? Nullable<_> 4 @@>, box 8 + <@@ 2u *? Nullable<_> 4u @@>, box 8u + <@@ 2L *? Nullable<_> 4L @@>, box 8L + <@@ 2uL *? Nullable<_> 4uL @@>, box 8uL + <@@ 2.0f *? Nullable<_> 4.0f @@>, box 8f + <@@ 2.0 *? Nullable<_> 4.0 @@>, box 8. + <@@ 2m *? Nullable<_> 4m @@>, box 8m + <@@ 2m *? Nullable<_> 4m @@>, box 8m + <@@ 2I *? Nullable<_> 4I @@>, box 8I + <@@ LanguagePrimitives.GenericOne *? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne *? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1un + + <@@ Nullable<_> 2y ?*? Nullable<_> 4y @@>, box 8y + <@@ Nullable<_> 2uy ?*? Nullable<_> 4uy @@>, box 8uy + <@@ Nullable<_> 2s ?*? Nullable<_> 4s @@>, box 8s + <@@ Nullable<_> 2us ?*? Nullable<_> 4us @@>, box 8us + <@@ Nullable<_> 2 ?*? Nullable<_> 4 @@>, box 8 + <@@ Nullable<_> 2u ?*? Nullable<_> 4u @@>, box 8u + <@@ Nullable<_> 2L ?*? Nullable<_> 4L @@>, box 8L + <@@ Nullable<_> 2uL ?*? Nullable<_> 4uL @@>, box 8uL + <@@ Nullable<_> 2.0f ?*? Nullable<_> 4.0f @@>, box 8f + <@@ Nullable<_> 2.0 ?*? Nullable<_> 4.0 @@>, box 8. + <@@ Nullable<_> 2m ?*? Nullable<_> 4m @@>, box 8m + <@@ Nullable<_> 2m ?*? Nullable<_> 4m @@>, box 8m + <@@ Nullable<_> 2I ?*? Nullable<_> 4I @@>, box 8I + <@@ Nullable<_> LanguagePrimitives.GenericOne ?*? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?*? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1un + + <@@ Nullable<_> 6y ?/ 3y @@>, box 2y + <@@ Nullable<_> 6uy ?/ 3uy @@>, box 2uy + <@@ Nullable<_> 6s ?/ 3s @@>, box 2s + <@@ Nullable<_> 6us ?/ 3us @@>, box 2us + <@@ Nullable<_> 6 ?/ 3 @@>, box 2 + <@@ Nullable<_> 6u ?/ 3u @@>, box 2u + <@@ Nullable<_> 6L ?/ 3L @@>, box 2L + <@@ Nullable<_> 6uL ?/ 3uL @@>, box 2uL + <@@ Nullable<_> 6.0f ?/ 3.0f @@>, box 2f + <@@ Nullable<_> 6.0 ?/ 3.0 @@>, box 2. + <@@ Nullable<_> 6m ?/ 3m @@>, box 2m + <@@ Nullable<_> 6m ?/ 3m @@>, box 2m + <@@ Nullable<_> 6I ?/ 3I @@>, box 2I + <@@ Nullable<_> LanguagePrimitives.GenericOne ?/ LanguagePrimitives.GenericOne @@>, box 1n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?/ LanguagePrimitives.GenericOne @@>, box 1un + + <@@ 6y /? Nullable<_> 3y @@>, box 2y + <@@ 6uy /? Nullable<_> 3uy @@>, box 2uy + <@@ 6s /? Nullable<_> 3s @@>, box 2s + <@@ 6us /? Nullable<_> 3us @@>, box 2us + <@@ 6 /? Nullable<_> 3 @@>, box 2 + <@@ 6u /? Nullable<_> 3u @@>, box 2u + <@@ 6L /? Nullable<_> 3L @@>, box 2L + <@@ 6uL /? Nullable<_> 3uL @@>, box 2uL + <@@ 6.0f /? Nullable<_> 3.0f @@>, box 2f + <@@ 6.0 /? Nullable<_> 3.0 @@>, box 2. + <@@ 6m /? Nullable<_> 3m @@>, box 2m + <@@ 6m /? Nullable<_> 3m @@>, box 2m + <@@ 6I /? Nullable<_> 3I @@>, box 2I + <@@ LanguagePrimitives.GenericOne /? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1n + <@@ LanguagePrimitives.GenericOne /? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1un + + <@@ Nullable<_> 6y ?/? Nullable<_> 3y @@>, box 2y + <@@ Nullable<_> 6uy ?/? Nullable<_> 3uy @@>, box 2uy + <@@ Nullable<_> 6s ?/? Nullable<_> 3s @@>, box 2s + <@@ Nullable<_> 6us ?/? Nullable<_> 3us @@>, box 2us + <@@ Nullable<_> 6 ?/? Nullable<_> 3 @@>, box 2 + <@@ Nullable<_> 6u ?/? Nullable<_> 3u @@>, box 2u + <@@ Nullable<_> 6L ?/? Nullable<_> 3L @@>, box 2L + <@@ Nullable<_> 6uL ?/? Nullable<_> 3uL @@>, box 2uL + <@@ Nullable<_> 6.0f ?/? Nullable<_> 3.0f @@>, box 2f + <@@ Nullable<_> 6.0 ?/? Nullable<_> 3.0 @@>, box 2. + <@@ Nullable<_> 6m ?/? Nullable<_> 3m @@>, box 2m + <@@ Nullable<_> 6m ?/? Nullable<_> 3m @@>, box 2m + <@@ Nullable<_> 6I ?/? Nullable<_> 3I @@>, box 2I + <@@ Nullable<_> LanguagePrimitives.GenericOne ?/? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?/? Nullable<_> LanguagePrimitives.GenericOne @@>, box 1un + + <@@ Nullable<_> 9y ?% 4y @@>, box 1y + <@@ Nullable<_> 9uy ?% 4uy @@>, box 1uy + <@@ Nullable<_> 9s ?% 4s @@>, box 1s + <@@ Nullable<_> 9us ?% 4us @@>, box 1us + <@@ Nullable<_> 9 ?% 4 @@>, box 1 + <@@ Nullable<_> 9u ?% 4u @@>, box 1u + <@@ Nullable<_> 9L ?% 4L @@>, box 1L + <@@ Nullable<_> 9uL ?% 4uL @@>, box 1uL + <@@ Nullable<_> 9.0f ?% 4.0f @@>, box 1f + <@@ Nullable<_> 9.0 ?% 4.0 @@>, box 1. + <@@ Nullable<_> 9m ?% 4m @@>, box 1m + <@@ Nullable<_> 9m ?% 4m @@>, box 1m + <@@ Nullable<_> 9I ?% 4I @@>, box 1I + <@@ Nullable<_> LanguagePrimitives.GenericOne ?% LanguagePrimitives.GenericOne @@>, box 0n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?% LanguagePrimitives.GenericOne @@>, box 0un + + <@@ 9y %? Nullable<_> 4y @@>, box 1y + <@@ 9uy %? Nullable<_> 4uy @@>, box 1uy + <@@ 9s %? Nullable<_> 4s @@>, box 1s + <@@ 9us %? Nullable<_> 4us @@>, box 1us + <@@ 9 %? Nullable<_> 4 @@>, box 1 + <@@ 9u %? Nullable<_> 4u @@>, box 1u + <@@ 9L %? Nullable<_> 4L @@>, box 1L + <@@ 9uL %? Nullable<_> 4uL @@>, box 1uL + <@@ 9.0f %? Nullable<_> 4.0f @@>, box 1f + <@@ 9.0 %? Nullable<_> 4.0 @@>, box 1. + <@@ 9m %? Nullable<_> 4m @@>, box 1m + <@@ 9m %? Nullable<_> 4m @@>, box 1m + <@@ 9I %? Nullable<_> 4I @@>, box 1I + <@@ LanguagePrimitives.GenericOne %? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0n + <@@ LanguagePrimitives.GenericOne %? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0un + + <@@ Nullable<_> 9y ?%? Nullable<_> 4y @@>, box 1y + <@@ Nullable<_> 9uy ?%? Nullable<_> 4uy @@>, box 1uy + <@@ Nullable<_> 9s ?%? Nullable<_> 4s @@>, box 1s + <@@ Nullable<_> 9us ?%? Nullable<_> 4us @@>, box 1us + <@@ Nullable<_> 9 ?%? Nullable<_> 4 @@>, box 1 + <@@ Nullable<_> 9u ?%? Nullable<_> 4u @@>, box 1u + <@@ Nullable<_> 9L ?%? Nullable<_> 4L @@>, box 1L + <@@ Nullable<_> 9uL ?%? Nullable<_> 4uL @@>, box 1uL + <@@ Nullable<_> 9.0f ?%? Nullable<_> 4.0f @@>, box 1f + <@@ Nullable<_> 9.0 ?%? Nullable<_> 4.0 @@>, box 1. + <@@ Nullable<_> 9m ?%? Nullable<_> 4m @@>, box 1m + <@@ Nullable<_> 9m ?%? Nullable<_> 4m @@>, box 1m + <@@ Nullable<_> 9I ?%? Nullable<_> 4I @@>, box 1I + <@@ Nullable<_> LanguagePrimitives.GenericOne ?%? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0n + <@@ Nullable<_> LanguagePrimitives.GenericOne ?%? Nullable<_> LanguagePrimitives.GenericOne @@>, box 0un + + <@@ NonStructuralComparison.(=) 3y 3y @@>, box true + <@@ NonStructuralComparison.(=) 3uy 3uy @@>, box true + <@@ NonStructuralComparison.(=) 3s 3s @@>, box true + <@@ NonStructuralComparison.(=) 3us 3us @@>, box true + <@@ NonStructuralComparison.(=) 3 3 @@>, box true + <@@ NonStructuralComparison.(=) 3u 3u @@>, box true + <@@ NonStructuralComparison.(=) 3L 3L @@>, box true + <@@ NonStructuralComparison.(=) 3UL 3UL @@>, box true + <@@ NonStructuralComparison.(=) '3' '3' @@>, box true + <@@ NonStructuralComparison.(=) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box true + <@@ NonStructuralComparison.(=) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box true + <@@ NonStructuralComparison.(=) 3f 3f @@>, box true + <@@ NonStructuralComparison.(=) 3. 3. @@>, box true + <@@ NonStructuralComparison.(=) 3m 3m @@>, box true + <@@ NonStructuralComparison.(=) 3m 3m @@>, box true + <@@ NonStructuralComparison.(=) 3I 3I @@>, box true + <@@ NonStructuralComparison.(=) "3" "3" @@>, box true + + <@@ NonStructuralComparison.(<>) 3y 3y @@>, box false + <@@ NonStructuralComparison.(<>) 3uy 3uy @@>, box false + <@@ NonStructuralComparison.(<>) 3s 3s @@>, box false + <@@ NonStructuralComparison.(<>) 3us 3us @@>, box false + <@@ NonStructuralComparison.(<>) 3 3 @@>, box false + <@@ NonStructuralComparison.(<>) 3u 3u @@>, box false + <@@ NonStructuralComparison.(<>) 3L 3L @@>, box false + <@@ NonStructuralComparison.(<>) 3UL 3UL @@>, box false + <@@ NonStructuralComparison.(<>) '3' '3' @@>, box false + <@@ NonStructuralComparison.(<>) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ NonStructuralComparison.(<>) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ NonStructuralComparison.(<>) 3f 3f @@>, box false + <@@ NonStructuralComparison.(<>) 3. 3. @@>, box false + <@@ NonStructuralComparison.(<>) 3m 3m @@>, box false + <@@ NonStructuralComparison.(<>) 3m 3m @@>, box false + <@@ NonStructuralComparison.(<>) 3I 3I @@>, box false + <@@ NonStructuralComparison.(<>) "3" "3" @@>, box false + + <@@ NonStructuralComparison.(<=) 3y 3y @@>, box true + <@@ NonStructuralComparison.(<=) 3uy 3uy @@>, box true + <@@ NonStructuralComparison.(<=) 3s 3s @@>, box true + <@@ NonStructuralComparison.(<=) 3us 3us @@>, box true + <@@ NonStructuralComparison.(<=) 3 3 @@>, box true + <@@ NonStructuralComparison.(<=) 3u 3u @@>, box true + <@@ NonStructuralComparison.(<=) 3L 3L @@>, box true + <@@ NonStructuralComparison.(<=) 3UL 3UL @@>, box true + <@@ NonStructuralComparison.(<=) '3' '3' @@>, box true + <@@ NonStructuralComparison.(<=) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box true + <@@ NonStructuralComparison.(<=) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box true + <@@ NonStructuralComparison.(<=) 3f 3f @@>, box true + <@@ NonStructuralComparison.(<=) 3. 3. @@>, box true + <@@ NonStructuralComparison.(<=) 3m 3m @@>, box true + <@@ NonStructuralComparison.(<=) 3m 3m @@>, box true + <@@ NonStructuralComparison.(<=) 3I 3I @@>, box true + <@@ NonStructuralComparison.(<=) "3" "3" @@>, box true + + <@@ NonStructuralComparison.(<) 3y 3y @@>, box false + <@@ NonStructuralComparison.(<) 3uy 3uy @@>, box false + <@@ NonStructuralComparison.(<) 3s 3s @@>, box false + <@@ NonStructuralComparison.(<) 3us 3us @@>, box false + <@@ NonStructuralComparison.(<) 3 3 @@>, box false + <@@ NonStructuralComparison.(<) 3u 3u @@>, box false + <@@ NonStructuralComparison.(<) 3L 3L @@>, box false + <@@ NonStructuralComparison.(<) 3UL 3UL @@>, box false + <@@ NonStructuralComparison.(<) '3' '3' @@>, box false + <@@ NonStructuralComparison.(<) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ NonStructuralComparison.(<) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ NonStructuralComparison.(<) 3f 3f @@>, box false + <@@ NonStructuralComparison.(<) 3. 3. @@>, box false + <@@ NonStructuralComparison.(<) 3m 3m @@>, box false + <@@ NonStructuralComparison.(<) 3m 3m @@>, box false + <@@ NonStructuralComparison.(<) 3I 3I @@>, box false + <@@ NonStructuralComparison.(<) "3" "3" @@>, box false + + <@@ NonStructuralComparison.(>=) 3y 3y @@>, box true + <@@ NonStructuralComparison.(>=) 3uy 3uy @@>, box true + <@@ NonStructuralComparison.(>=) 3s 3s @@>, box true + <@@ NonStructuralComparison.(>=) 3us 3us @@>, box true + <@@ NonStructuralComparison.(>=) 3 3 @@>, box true + <@@ NonStructuralComparison.(>=) 3u 3u @@>, box true + <@@ NonStructuralComparison.(>=) 3L 3L @@>, box true + <@@ NonStructuralComparison.(>=) 3UL 3UL @@>, box true + <@@ NonStructuralComparison.(>=) '3' '3' @@>, box true + <@@ NonStructuralComparison.(>=) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box true + <@@ NonStructuralComparison.(>=) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box true + <@@ NonStructuralComparison.(>=) 3f 3f @@>, box true + <@@ NonStructuralComparison.(>=) 3. 3. @@>, box true + <@@ NonStructuralComparison.(>=) 3m 3m @@>, box true + <@@ NonStructuralComparison.(>=) 3m 3m @@>, box true + <@@ NonStructuralComparison.(>=) 3I 3I @@>, box true + <@@ NonStructuralComparison.(>=) "3" "3" @@>, box true + + <@@ NonStructuralComparison.(>) 3y 3y @@>, box false + <@@ NonStructuralComparison.(>) 3uy 3uy @@>, box false + <@@ NonStructuralComparison.(>) 3s 3s @@>, box false + <@@ NonStructuralComparison.(>) 3us 3us @@>, box false + <@@ NonStructuralComparison.(>) 3 3 @@>, box false + <@@ NonStructuralComparison.(>) 3u 3u @@>, box false + <@@ NonStructuralComparison.(>) 3L 3L @@>, box false + <@@ NonStructuralComparison.(>) 3UL 3UL @@>, box false + <@@ NonStructuralComparison.(>) '3' '3' @@>, box false + <@@ NonStructuralComparison.(>) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ NonStructuralComparison.(>) LanguagePrimitives.GenericOne LanguagePrimitives.GenericOne @@>, box false + <@@ NonStructuralComparison.(>) 3f 3f @@>, box false + <@@ NonStructuralComparison.(>) 3. 3. @@>, box false + <@@ NonStructuralComparison.(>) 3m 3m @@>, box false + <@@ NonStructuralComparison.(>) 3m 3m @@>, box false + <@@ NonStructuralComparison.(>) 3I 3I @@>, box false + <@@ NonStructuralComparison.(>) "3" "3" @@>, box false |] tests |> Array.map (fun (test, eval) -> From 2e298543f64e9f66ae4f9442d78ba999f56d662d Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 14 Jul 2021 18:53:13 +0800 Subject: [PATCH 64/78] Uhhh... meow? --- src/fsharp/FSharp.Core/Linq.fs | 29 ++++++++++++++++------------- tests/fsharp/core/quotes/test.fsx | 10 ++++++---- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 75e9fbc4073..a1e9a172946 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -137,9 +137,12 @@ module LeafExpressionConverter = | TypeCode.UInt64 -> true | _ -> false // https://github.com/dotnet/runtime/blob/afaf666eff08435123eb649ac138419f4c9b9344/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1047 + /// Can LINQ Expressions' BinaryExpression's eqaulity operations provide built-in structural equality from the types in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsStructurallyEquatable typ = + isLinqExpressionsNumeric typ || typ = typeof || getNonNullableType(typ).IsEnum /// Can LINQ Expressions' BinaryExpression's eqaulity operations provide built-in equality from the types in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsEquatable typ = - isLinqExpressionsNumeric typ || typ = typeof || typ = typeof || getNonNullableType(typ).IsEnum + isLinqExpressionsStructurallyEquatable typ || typ = typeof let SpecificCallToMethodInfo (minfo: System.Reflection.MethodInfo) = let isg1 = minfo.IsGenericMethod @@ -437,12 +440,12 @@ module LeafExpressionConverter = | LessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThanOrEqual m | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env false x1 x2 false Expression.Equal (methodhandleof (fun x -> LanguagePrimitives.EqualityDynamic x)) - | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env false x1 x2 false Expression.NotEqual (methodhandleof (fun x -> LanguagePrimitives.InequalityDynamic x)) - | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.GreaterThan (methodhandleof (fun x -> LanguagePrimitives.GreaterThanDynamic x)) - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.GreaterThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.GreaterThanOrEqualDynamic x)) - | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.LessThan (methodhandleof (fun x -> LanguagePrimitives.LessThanDynamic x)) - | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env false x1 x2 false Expression.LessThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.LessThanOrEqualDynamic x)) + | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.Equal (methodhandleof (fun x -> LanguagePrimitives.EqualityDynamic x)) + | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.NotEqual (methodhandleof (fun x -> LanguagePrimitives.InequalityDynamic x)) + | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThan (methodhandleof (fun x -> LanguagePrimitives.GreaterThanDynamic x)) + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.GreaterThanOrEqualDynamic x)) + | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThan (methodhandleof (fun x -> LanguagePrimitives.LessThanDynamic x)) + | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.LessThanOrEqualDynamic x)) | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.Equal m | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.NotEqual m @@ -719,22 +722,22 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e1, e2, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) |> asExpr - // Boolean equality / comparison operators do not take witnesses and the referenced methods are callable directly + // The F# boolean structural equality / comparison operators do not take witnesses and the referenced methods are callable directly and transBoolOpNoWitness env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = 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 - try exprErasedConstructor(e1', e2', false, null) with _ -> - // LINQ Expressions cannot recognize boolean operators on F# types that are not defined on the types themselves. In this case, use the F# operator as the user-defined method. + if e1'.Type = e2'.Type && isLinqExpressionsStructurallyEquatable e1.Type then + // The false for (liftToNull: bool) indicates whether equality operators return a Nullable like in VB.NET (null when either argument is null) instead of bool like in C# (nulls equate to nulls). F# follows C# here. + exprErasedConstructor(e1', e2', false, null) + else exprErasedConstructor(e1, e2, false, method) |> asExpr // But the static boolean operators do take witnesses! - and transBoolOp linqExpressionsCondition inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) fallback = + and transBoolOp linqExpressionsCondition inp env x1 x2 (exprErasedConstructor: _ * _ * _ * _ -> _) fallback = 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 if e1.Type = e2.Type && linqExpressionsCondition e1.Type then // The false for (liftToNull: bool) indicates whether equality operators return a Nullable like in VB.NET (null when either argument is null) instead of bool like in C# (nulls equate to nulls). F# follows C# here. exprErasedConstructor(e1, e2, false, null) diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 7d77931d032..07d47a1914c 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -4980,9 +4980,10 @@ module WitnessTests = <@@ 3m = 3m @@>, box true <@@ 3I = 3I @@>, box true <@@ "3" = "3" @@>, box true - <@@ [3] = [3] @@>, box false // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. - <@@ [|3|] = [|3|] @@>, box false // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. + <@@ [3] = [3] @@>, box true + <@@ [|3|] = [|3|] @@>, box true <@@ seq { 3 } = seq { 3 } @@>, box false // Reference equality + <@@ obj() = obj() @@>, box false <@@ 3y <> 3y @@>, box false <@@ 3uy <> 3uy @@>, box false @@ -5001,9 +5002,10 @@ module WitnessTests = <@@ 3m <> 3m @@>, box false <@@ 3I <> 3I @@>, box false <@@ "3" <> "3" @@>, box false - <@@ [3] <> [3] @@>, box true // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. - <@@ [|3|] <> [|3|] @@>, box true // Unlike the F# structural operator, it translates to a reference equality check in Linq Expressions. Need to consider whether this is desirable. + <@@ [3] <> [3] @@>, box false + <@@ [|3|] <> [|3|] @@>, box false <@@ seq { 3 } <> seq { 3 } @@>, box true // Reference equality + <@@ obj() <> obj() @@>, box true <@@ 3y <= 3y @@>, box true <@@ 3uy <= 3uy @@>, box true From b37f075c38a5aa3401157a8bea1c37eb1732022e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Wed, 14 Jul 2021 21:05:00 +0800 Subject: [PATCH 65/78] Formatting --- src/fsharp/FSharp.Core/Linq.fs | 120 ++++++++++++++++---------------- src/fsharp/FSharp.Core/Linq.fsi | 2 +- src/fsharp/FSharp.Core/Query.fs | 39 ++++++----- 3 files changed, 81 insertions(+), 80 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index a1e9a172946..4f0a6fe511d 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -75,8 +75,6 @@ module LeafExpressionConverter = let NullableConstructor = typedefof>.GetConstructors().[0] - - let arrayOf3StringTypes = [|typeof; typeof; typeof|] let getNonNullableType typ = match Nullable.GetUnderlyingType typ with null -> typ | t -> t @@ -84,58 +82,62 @@ module LeafExpressionConverter = /// Can LINQ Expressions' (UnaryExpression/BinaryExpression)'s arithmetic operations construct a (SimpleBinaryExpression/UnaryExpression) from the types in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsArithmeticType typ = let typ = getNonNullableType typ - not typ.IsEnum && match Type.GetTypeCode typ with - | TypeCode.Int16 - | TypeCode.Int32 - | TypeCode.Int64 - | TypeCode.Double - | TypeCode.Single - | TypeCode.UInt16 - | TypeCode.UInt32 - | TypeCode.UInt64 -> true - | _ -> false + not typ.IsEnum && + match Type.GetTypeCode typ with + | TypeCode.Int16 + | TypeCode.Int32 + | TypeCode.Int64 + | TypeCode.Double + | TypeCode.Single + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> true + | _ -> false // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L132 /// Can LINQ Expressions' UnaryExpression.(Checked)Negate construct a UnaryExpression from the types in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsArithmeticTypeButNotUnsignedInt typ = isLinqExpressionsArithmeticType typ && let typ = getNonNullableType typ - not typ.IsEnum && match Type.GetTypeCode typ with - | TypeCode.UInt16 - | TypeCode.UInt32 - | TypeCode.UInt64 -> false - | _ -> true + not typ.IsEnum && + match Type.GetTypeCode typ with + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> false + | _ -> true // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L149 /// Can LINQ Expressions' UnaryExpression.Not construct a UnaryExpression from the types in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsIntegerOrBool typ = let typ = getNonNullableType typ - not typ.IsEnum && match Type.GetTypeCode typ with - | TypeCode.Int64 - | TypeCode.Int32 - | TypeCode.Int16 - | TypeCode.UInt64 - | TypeCode.UInt32 - | TypeCode.UInt16 - | TypeCode.Boolean - | TypeCode.SByte - | TypeCode.Byte -> true - | _ -> false + not typ.IsEnum && + match Type.GetTypeCode typ with + | TypeCode.Int64 + | TypeCode.Int32 + | TypeCode.Int16 + | TypeCode.UInt64 + | TypeCode.UInt32 + | TypeCode.UInt16 + | TypeCode.Boolean + | TypeCode.SByte + | TypeCode.Byte -> true + | _ -> false // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L47 /// Can LINQ Expressions' BinaryExpression's comparison operations construct a (SimpleBinaryExpression/LogicalBinaryExpression) from the types in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsNumeric typ = let typ = getNonNullableType typ - not typ.IsEnum && match Type.GetTypeCode typ with - | TypeCode.Char - | TypeCode.SByte - | TypeCode.Byte - | TypeCode.Int16 - | TypeCode.Int32 - | TypeCode.Int64 - | TypeCode.Double - | TypeCode.Single - | TypeCode.UInt16 - | TypeCode.UInt32 - | TypeCode.UInt64 -> true - | _ -> false + not typ.IsEnum && + match Type.GetTypeCode typ with + | TypeCode.Char + | TypeCode.SByte + | TypeCode.Byte + | TypeCode.Int16 + | TypeCode.Int32 + | TypeCode.Int64 + | TypeCode.Double + | TypeCode.Single + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> true + | _ -> false // https://github.com/dotnet/runtime/blob/afaf666eff08435123eb649ac138419f4c9b9344/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1047 /// Can LINQ Expressions' BinaryExpression's eqaulity operations provide built-in structural equality from the types in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsStructurallyEquatable typ = @@ -158,12 +160,10 @@ module LeafExpressionConverter = Some (obj, minfo2, args) | _ -> None) - let (|SpecificCallToMethod|_|) (mhandle: System.RuntimeMethodHandle) = + let (|SpecificCallToMethod|_|) (mhandle: RuntimeMethodHandle) = let minfo = (System.Reflection.MethodInfo.GetMethodFromHandle mhandle) :?> MethodInfo SpecificCallToMethodInfo minfo - - let (|SpecificCallToGenericMethod|_|) (mhandle: System.RuntimeMethodHandle) = - (|SpecificCallToMethod|_|) mhandle >> Option.map (fun (obj, minfo, args) -> obj, minfo.GetGenericArguments() |> Array.toList, args) + let (|GenericArgs|) (minfo: MethodInfo) = minfo.GetGenericArguments() let (|GenericEqualityQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.GenericEquality x y)) let (|EqualsQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> x = y)) @@ -283,8 +283,8 @@ module LeafExpressionConverter = let (|ConvNullableIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.nativeint x)) let (|ConvNullableUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Nullable.unativeint x)) - let (|UnboxGeneric|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.UnboxGeneric x)) - let (|TypeTestGeneric|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric x)) + let (|UnboxGeneric|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> LanguagePrimitives.IntrinsicFunctions.UnboxGeneric x)) + 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")) @@ -298,10 +298,10 @@ module LeafExpressionConverter = let (|CheckedConvUInt64Q|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.uint64 x)) let (|CheckedConvIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.nativeint x)) let (|CheckedConvUIntPtrQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> Checked.unativeint x)) - let (|ImplicitExpressionConversionHelperQ|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun x -> ImplicitExpressionConversionHelper x)) + let (|ImplicitExpressionConversionHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> ImplicitExpressionConversionHelper x)) let (|MemberInitializationHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> MemberInitializationHelper x)) let (|NewAnonymousObjectHelperQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun x -> NewAnonymousObjectHelper x)) - let (|ArrayLookupQ|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.IntrinsicFunctions.GetArray x y)) + let (|ArrayLookupQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.IntrinsicFunctions.GetArray x y)) //let (|ArrayAssignQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun -> LanguagePrimitives.IntrinsicFunctions.SetArray : int[] -> int -> int -> unit)) //let (|ArrayTypeQ|_|) (ty:System.Type) = if ty.IsArray && ty.GetArrayRank() = 1 then Some (ty.GetElementType()) else None @@ -359,7 +359,7 @@ module LeafExpressionConverter = | Patterns.Value(x, ty) -> Expression.Constant(x, ty) |> asExpr - | UnboxGeneric(_, [toTy], [x]) + | UnboxGeneric(_, GenericArgs [|toTy|], [x]) | Patterns.Coerce(x, toTy) -> let converted = ConvExprToLinqInContext env x @@ -371,7 +371,7 @@ module LeafExpressionConverter = | Patterns.TypeTest(x, toTy) -> Expression.TypeIs(ConvExprToLinqInContext env x, toTy) |> asExpr - | TypeTestGeneric(_, [toTy], [x]) -> + | TypeTestGeneric(_, GenericArgs [|toTy|], [x]) -> Expression.TypeIs(ConvExprToLinqInContext env x, toTy) |> asExpr // Expr.*Get @@ -428,7 +428,7 @@ module LeafExpressionConverter = Expression.New(ctor, argsR, [| for p in props -> (p :> MemberInfo) |]) |> asExpr // Do the same thing as C# compiler for string addition - | PlusQ (_, m, [x1; x2]) when m.GetGenericArguments() = arrayOf3StringTypes -> + | PlusQ (_, GenericArgs [|ty1; ty2; ty3|], [x1; x2]) when ty1 = typeof && ty2 = typeof && ty3 = typeof -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr | GenericEqualityQ (_, m, [x1; x2]) @@ -440,12 +440,12 @@ module LeafExpressionConverter = | LessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThanOrEqual m | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr - | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.Equal (methodhandleof (fun x -> LanguagePrimitives.EqualityDynamic x)) - | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.NotEqual (methodhandleof (fun x -> LanguagePrimitives.InequalityDynamic x)) - | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThan (methodhandleof (fun x -> LanguagePrimitives.GreaterThanDynamic x)) - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.GreaterThanOrEqualDynamic x)) - | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThan (methodhandleof (fun x -> LanguagePrimitives.LessThanDynamic x)) - | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThanOrEqual (methodhandleof (fun x -> LanguagePrimitives.LessThanOrEqualDynamic x)) + | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) + | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) + | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.Equal m | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.NotEqual m @@ -528,12 +528,12 @@ module LeafExpressionConverter = | CheckedConvUInt16Q (_, _, [x]) | CheckedConvUInt32Q (_, _, [x]) | CheckedConvUInt64Q (_, _, [x]) | CheckedConvIntPtrQ (_, _, [x]) -> transConv inp env true x | CheckedConvUIntPtrQ (_, _, [x]) -> transConv inp env true x - | ArrayLookupQ (_, [_; _; _], [x1; x2]) -> + | ArrayLookupQ (_, GenericArgs [|_; _; _|], [x1; x2]) -> Expression.ArrayIndex(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2) |> asExpr // 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 + | ImplicitExpressionConversionHelperQ (_, GenericArgs [|_|], [x1]) -> ConvExprToLinqInContext env x1 /// Use witnesses if they are available | CallWithWitnesses (objArgOpt, _, minfo2, witnessArgs, args) -> diff --git a/src/fsharp/FSharp.Core/Linq.fsi b/src/fsharp/FSharp.Core/Linq.fsi index 9c4cfa245ce..a2263431954 100644 --- a/src/fsharp/FSharp.Core/Linq.fsi +++ b/src/fsharp/FSharp.Core/Linq.fsi @@ -61,4 +61,4 @@ module LeafExpressionConverter = /// A runtime helper used to evaluate nested quotation literals. val SubstHelperRaw : Expr * Var[] * obj[] -> Expr - val internal (|SpecificCallToGenericMethod|_|) : System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option) + val internal (|SpecificCallToMethod|_|) : System.RuntimeMethodHandle -> (Expr -> (Expr option * Reflection.MethodInfo * Expr list) option) diff --git a/src/fsharp/FSharp.Core/Query.fs b/src/fsharp/FSharp.Core/Query.fs index 4aa1055db44..e58e9fa2abf 100644 --- a/src/fsharp/FSharp.Core/Query.fs +++ b/src/fsharp/FSharp.Core/Query.fs @@ -314,26 +314,27 @@ module Query = match prop.GetGetMethod true with | null -> None | v -> Some v + let (|GenericArgs|) (minfo: MethodInfo) = minfo.GetGenericArguments() |> Array.toList // Match 'f x' let (|SpecificCall1|_|) q = - let (|CallQ|_|) = (|SpecificCallToGenericMethod|_|) q + let (|CallQ|_|) = (|SpecificCallToMethod|_|) q function - | CallQ (Some builderObj, tyargs, [arg1]) -> Some(builderObj, tyargs, arg1) + | CallQ (Some builderObj, GenericArgs tyargs, [arg1]) -> Some(builderObj, tyargs, arg1) | _ -> None // Match 'f x y' or 'f (x, y)' let (|SpecificCall2|_|) q = - let (|CallQ|_|) = (|SpecificCallToGenericMethod|_|) q + let (|CallQ|_|) = (|SpecificCallToMethod|_|) q function - | CallQ (Some builderObj, tyargs, [arg1; arg2]) -> Some(builderObj, tyargs, arg1, arg2) + | CallQ (Some builderObj, GenericArgs tyargs, [arg1; arg2]) -> Some(builderObj, tyargs, arg1, arg2) | _ -> None // Match 'f x y z' or 'f (x, y, z)' let (|SpecificCall3|_|) q = - let (|CallQ|_|) = (|SpecificCallToGenericMethod|_|) q + let (|CallQ|_|) = (|SpecificCallToMethod|_|) q function - | CallQ (Some builderObj, tyargs, [arg1; arg2; arg3]) -> Some(builderObj, tyargs, arg1, arg2, arg3) + | CallQ (Some builderObj, GenericArgs tyargs, [arg1; arg2; arg3]) -> Some(builderObj, tyargs, arg1, arg2, arg3) | _ -> None /// (fun (x, y) -> z) is represented as 'fun p -> let x = p#0 let y = p#1' etc. @@ -1040,19 +1041,19 @@ module Query = | MacroReduction reduced -> Some (walk reduced) | _ -> None) - let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b :QueryBuilder, v) -> b.Run v)) + let (|CallQueryBuilderRunQueryable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b :QueryBuilder, v) -> b.Run v)) - let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr<'a>) -> b.Run v) : 'a) + let (|CallQueryBuilderRunValue|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr<'a>) -> b.Run v) : 'a) - let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr> ) -> b.Run v)) + let (|CallQueryBuilderRunEnumerable|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b : QueryBuilder, v: Expr> ) -> b.Run v)) - let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b:QueryBuilder, source: QuerySource, body) -> b.For(source, body))) + let (|CallQueryBuilderFor|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder, source: QuerySource, body) -> b.For(source, body))) let (|CallQueryBuilderYield|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value) -> b.Yield value)) - let (|CallQueryBuilderYieldFrom|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b:QueryBuilder, values) -> b.YieldFrom values)) + let (|CallQueryBuilderYieldFrom|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder, values) -> b.YieldFrom values)) - let (|CallQueryBuilderZero|_|) : Quotations.Expr -> _ = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (b:QueryBuilder) -> b.Zero())) + let (|CallQueryBuilderZero|_|) : Quotations.Expr -> _ = (|SpecificCallToMethod|_|) (methodhandleof (fun (b:QueryBuilder) -> b.Zero())) let (|CallQueryBuilderSourceIQueryable|_|) : Quotations.Expr -> _ = (|SpecificCall1|_|) (methodhandleof (fun (b:QueryBuilder, value: IQueryable<_>) -> b.Source value)) @@ -1118,11 +1119,11 @@ module Query = let (|CallSkipWhile|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2) -> query.SkipWhile(arg1, arg2))) - let (|CallJoin|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.Join(arg1, arg2, arg3, arg4, arg5))) + let (|CallJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.Join(arg1, arg2, arg3, arg4, arg5))) - let (|CallGroupJoin|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.GroupJoin(arg1, arg2, arg3, arg4, arg5))) + let (|CallGroupJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.GroupJoin(arg1, arg2, arg3, arg4, arg5))) - let (|CallLeftOuterJoin|_|) = (|SpecificCallToGenericMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.LeftOuterJoin(arg1, arg2, arg3, arg4, arg5))) + let (|CallLeftOuterJoin|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (query:QueryBuilder, arg1, arg2, arg3, arg4, arg5) -> query.LeftOuterJoin(arg1, arg2, arg3, arg4, arg5))) let (|CallAverageBy|_|) = (|SpecificCall2|_|) (methodhandleof (fun (query:QueryBuilder, arg1: QuerySource, arg2:(double->double)) -> query.AverageBy(arg1, arg2))) @@ -1286,7 +1287,7 @@ module Query = // rewrite has had the custom operator translation mechanism applied. In this case, the // body of the "for" will simply contain "yield". - | CallQueryBuilderFor (_, [_; qTy; immutResElemTy; _], [immutSource; Lambda(immutSelectorVar, immutSelector) ]) -> + | CallQueryBuilderFor (_, GenericArgs [_; qTy; immutResElemTy; _], [immutSource; Lambda(immutSelectorVar, immutSelector) ]) -> let mutSource, sourceConv = TransInner CanEliminate.Yes check immutSource @@ -1467,7 +1468,7 @@ module Query = | _ -> GroupingConv (immutKeySelector.Type, immutElementSelector.Type, selectorConv) TransInnerResult.Other(MakeGroupValBy(qTyIsIQueryable qTy, mutVar1.Type, mutKeySelector.Type, mutElementSelector.Type, mutSource, mutVar2, mutKeySelector, mutVar1, mutElementSelector)), conv - | CallJoin(_, [_; qTy; _; _; _], + | CallJoin(_, GenericArgs [_; qTy; _; _; _], [ immutOuterSource immutInnerSource Lambda(immutOuterKeyVar, immutOuterKeySelector) @@ -1491,7 +1492,7 @@ module Query = TransInnerResult.Other joinExpr, elementSelectorConv | CallGroupJoin - (_, [_; qTy; _; _; _], + (_, GenericArgs [_; qTy; _; _; _], [ immutOuterSource immutInnerSource Lambda(immutOuterKeyVar, immutOuterKeySelector) @@ -1517,7 +1518,7 @@ module Query = TransInnerResult.Other joinExpr, elementSelectorConv | CallLeftOuterJoin - (_, [ _; qTy; immutInnerSourceTy; _; _], + (_, GenericArgs [ _; qTy; immutInnerSourceTy; _; _], [ immutOuterSource immutInnerSource Lambda(immutOuterKeyVar, immutOuterKeySelector) From 8907c029bfcf4ba818d0c0fc3d63020c1add56cb Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Thu, 15 Jul 2021 00:50:55 +0800 Subject: [PATCH 66/78] Fix shifting --- src/fsharp/FSharp.Core/Linq.fs | 252 ++++++++++++++++++++++--------- src/fsharp/FSharp.Core/array.fs | 11 ++ src/fsharp/FSharp.Core/array.fsi | 20 +++ 3 files changed, 208 insertions(+), 75 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 4f0a6fe511d..95962ea6826 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -78,8 +78,27 @@ module LeafExpressionConverter = let getNonNullableType typ = match Nullable.GetUnderlyingType typ with null -> typ | t -> t + // https://github.com/dotnet/runtime/blob/fa779e8cb2b5868a0ac2fd4215f39ffb91f0dab0/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L72 + /// Can LINQ Expressions' BinaryExpression's (Left/Right)Shift construct a SimpleBinaryExpression from the type in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsInteger typ = + let typ = getNonNullableType typ + not typ.IsEnum && + match Type.GetTypeCode typ with + | TypeCode.Byte + | TypeCode.SByte + | TypeCode.Int16 + | TypeCode.Int32 + | TypeCode.Int64 + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 -> true + | _ -> false + // https://github.com/dotnet/runtime/blob/fa779e8cb2b5868a0ac2fd4215f39ffb91f0dab0/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L2226 + /// Can LINQ Expressions' BinaryExpression's (Left/Right)Shift construct a SimpleBinaryExpression from the type in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsSimpleShift left right = + isLinqExpressionsInteger left && getNonNullableType right = typeof // https://github.com/dotnet/runtime/blob/cf7e7a46f8a4a6225a8f1e059a846ccdebf0454c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L110 - /// Can LINQ Expressions' (UnaryExpression/BinaryExpression)'s arithmetic operations construct a (SimpleBinaryExpression/UnaryExpression) from the types in question? Otherwise, use the F# operator as the user-defined method. + /// Can LINQ Expressions' (UnaryExpression/BinaryExpression)'s arithmetic operations construct a (SimpleBinaryExpression/UnaryExpression) from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsArithmeticType typ = let typ = getNonNullableType typ not typ.IsEnum && @@ -94,7 +113,7 @@ module LeafExpressionConverter = | TypeCode.UInt64 -> true | _ -> false // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L132 - /// Can LINQ Expressions' UnaryExpression.(Checked)Negate construct a UnaryExpression from the types in question? Otherwise, use the F# operator as the user-defined method. + /// Can LINQ Expressions' UnaryExpression.(Checked)Negate construct a UnaryExpression from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsArithmeticTypeButNotUnsignedInt typ = isLinqExpressionsArithmeticType typ && let typ = getNonNullableType typ @@ -105,7 +124,7 @@ module LeafExpressionConverter = | TypeCode.UInt64 -> false | _ -> true // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L149 - /// Can LINQ Expressions' UnaryExpression.Not construct a UnaryExpression from the types in question? Otherwise, use the F# operator as the user-defined method. + /// Can LINQ Expressions' (UnaryExpression.Not/BinaryExpression.Binary(And/Or/ExclusiveOr)) construct a (UnaryExpression/SimpleBinaryExpression) from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsIntegerOrBool typ = let typ = getNonNullableType typ not typ.IsEnum && @@ -121,7 +140,7 @@ module LeafExpressionConverter = | TypeCode.Byte -> true | _ -> false // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L47 - /// Can LINQ Expressions' BinaryExpression's comparison operations construct a (SimpleBinaryExpression/LogicalBinaryExpression) from the types in question? Otherwise, use the F# operator as the user-defined method. + /// Can LINQ Expressions' BinaryExpression's comparison operations construct a (SimpleBinaryExpression/LogicalBinaryExpression) from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsNumeric typ = let typ = getNonNullableType typ not typ.IsEnum && @@ -139,13 +158,85 @@ module LeafExpressionConverter = | TypeCode.UInt64 -> true | _ -> false // https://github.com/dotnet/runtime/blob/afaf666eff08435123eb649ac138419f4c9b9344/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1047 - /// Can LINQ Expressions' BinaryExpression's eqaulity operations provide built-in structural equality from the types in question? Otherwise, use the F# operator as the user-defined method. + /// Can LINQ Expressions' BinaryExpression's equality operations provide built-in structural equality from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsStructurallyEquatable typ = isLinqExpressionsNumeric typ || typ = typeof || getNonNullableType(typ).IsEnum - /// Can LINQ Expressions' BinaryExpression's eqaulity operations provide built-in equality from the types in question? Otherwise, use the F# operator as the user-defined method. + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1221 + /// Can LINQ Expressions' BinaryExpression's comparison operations provide built-in comparison from the type in question? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsComparable = isLinqExpressionsNumeric + /// Can LINQ Expressions' BinaryExpression's equality operations provide built-in equality from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsEquatable typ = isLinqExpressionsStructurallyEquatable typ || typ = typeof - + /// Can LINQ Expressions' BinaryExpression's conversion operations provide built-in conversion from source to dest? Otherwise, use the F# operator as the user-defined method. + let isLinqExpressionsConvertible source dest = + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/UnaryExpression.cs#L757 + // expression.Type.HasIdentityPrimitiveOrNullableConversionTo(type) || expression.Type.HasReferenceConversionTo(type)) + // In other words, source.HasIdentityPrimitiveOrNullableConversionTo dest || source.HasReferenceConversionTo dest + + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L532 + let isConvertible typ = + let typ = getNonNullableType typ + typ.IsEnum || + match Type.GetTypeCode typ with + | TypeCode.Boolean + | TypeCode.Byte + | TypeCode.SByte + | TypeCode.Int16 + | TypeCode.Int32 + | TypeCode.Int64 + | TypeCode.UInt16 + | TypeCode.UInt32 + | TypeCode.UInt64 + | TypeCode.Single + | TypeCode.Double + | TypeCode.Char -> true + | _ -> false + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L229 + // HasIdentityPrimitiveOrNullableConversionTo + getNonNullableType(source).IsEquivalentTo dest + || dest.IsEquivalentTo(getNonNullableType source) + || isConvertible source && isConvertible dest + && (getNonNullableType dest <> typeof || source.IsEnum && source.GetEnumUnderlyingType() = typeof) + + || + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L260 + // HasReferenceConversionTo + let rec hasReferenceConversionTo source dest = + + // { if (source == typeof(void) || dest == typeof(void)) return false; } invalidates an identity conversion. This is handled by the IsEquivalentTo check above. + let nnSourceType, nnDestType = getNonNullableType source, getNonNullableType dest + + // Down conversion + nnSourceType.IsAssignableFrom nnDestType + // Up conversion + || nnDestType.IsAssignableFrom nnSourceType + + // Interface conversion + || source.IsInterface || dest.IsInterface + + // Variant delegate conversion + || // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L458 + // IsLegalExplicitVariantDelegateConversion + let isDelegate (t: Type) = t.IsSubclassOf typeof + isDelegate source && isDelegate dest && source.IsGenericType && dest.IsGenericType + && + let genericDelegate = source.GetGenericTypeDefinition() + dest.GetGenericTypeDefinition() = genericDelegate + && + (source.GetGenericArguments(), dest.GetGenericArguments(), genericDelegate.GetGenericArguments()) + |||> Array.forall3 (fun sourceArgument destArgument genericParameter -> + // If the arguments are identical then this one is automatically good, so skip it. + sourceArgument.IsEquivalentTo destArgument + || + match genericParameter.GenericParameterAttributes &&& GenericParameterAttributes.VarianceMask with + | GenericParameterAttributes.None -> false + | GenericParameterAttributes.Covariant -> hasReferenceConversionTo sourceArgument destArgument + | GenericParameterAttributes.Contravariant -> not (sourceArgument.IsValueType || destArgument.IsValueType) + | x -> failwith $"Unexpected GenericParameterAttributes variance: {x}" + ) + // TODO: Is expanding this worth it? + // || (source.IsArray || dest.IsArray) && StrictHasReferenceConversionTo(source, dest, true) + hasReferenceConversionTo source dest let SpecificCallToMethodInfo (minfo: System.Reflection.MethodInfo) = let isg1 = minfo.IsGenericMethod let gmd = if isg1 then minfo.GetGenericMethodDefinition() else null @@ -432,84 +523,84 @@ module LeafExpressionConverter = Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr | GenericEqualityQ (_, m, [x1; x2]) - | EqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.Equal m - | NotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.NotEqual m - | GreaterQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThan m - | GreaterEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThanOrEqual m - | LessQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThan m - | LessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThanOrEqual m + | EqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 false Expression.Equal m + | NotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 false Expression.NotEqual m + | GreaterQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.GreaterThan m + | GreaterEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.GreaterThanOrEqual m + | LessQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.LessThan m + | LessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.LessThanOrEqual m | NotQ (_, _, [x1]) -> Expression.Not(ConvExprToLinqInContext env x1) |> asExpr | StaticEqualsQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.Equal (methodhandleof (fun (x, y) -> LanguagePrimitives.EqualityDynamic x y)) | StaticNotEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsEquatable inp env x1 x2 Expression.NotEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.InequalityDynamic x y)) - | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) - | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) - | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) - | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsNumeric inp env x1 x2 Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) - - | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.Equal m - | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.NotEqual m - | NullableGreaterQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.GreaterThan m - | NullableGreaterEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.GreaterThanOrEqual m - | NullableLessQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.LessThan m - | NullableLessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 true Expression.LessThanOrEqual m - - | EqualsNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.Equal m - | NotEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.NotEqual m - | GreaterNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.GreaterThan m - | GreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.GreaterThanOrEqual m - | LessNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.LessThan m - | LessEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env true x1 x2 false Expression.LessThanOrEqual m - - | NullableEqualsNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.Equal m - | NullableNotEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.NotEqual m - | NullableGreaterNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThan m - | NullableGreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.GreaterThanOrEqual m - | NullableLessNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThan m - | NullableLessEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness env false x1 x2 false Expression.LessThanOrEqual m + | StaticGreaterQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsComparable inp env x1 x2 Expression.GreaterThan (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanDynamic x y)) + | StaticGreaterEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsComparable inp env x1 x2 Expression.GreaterThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.GreaterThanOrEqualDynamic x y)) + | StaticLessQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsComparable inp env x1 x2 Expression.LessThan (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanDynamic x y)) + | StaticLessEqQ (_, _, [x1; x2]) -> transBoolOp isLinqExpressionsComparable inp env x1 x2 Expression.LessThanOrEqual (methodhandleof (fun (x, y) -> LanguagePrimitives.LessThanOrEqualDynamic x y)) + + | NullableEqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 true Expression.Equal m + | NullableNotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 true Expression.NotEqual m + | NullableGreaterQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 true Expression.GreaterThan m + | NullableGreaterEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 true Expression.GreaterThanOrEqual m + | NullableLessQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 true Expression.LessThan m + | NullableLessEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 true Expression.LessThanOrEqual m + + | EqualsNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env true x1 x2 false Expression.Equal m + | NotEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env true x1 x2 false Expression.NotEqual m + | GreaterNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env true x1 x2 false Expression.GreaterThan m + | GreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env true x1 x2 false Expression.GreaterThanOrEqual m + | LessNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env true x1 x2 false Expression.LessThan m + | LessEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env true x1 x2 false Expression.LessThanOrEqual m + + | NullableEqualsNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 false Expression.Equal m + | NullableNotEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 false Expression.NotEqual m + | NullableGreaterNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.GreaterThan m + | NullableGreaterEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.GreaterThanOrEqual m + | NullableLessNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.LessThan m + | NullableLessEqNullableQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsComparable env false x1 x2 false Expression.LessThanOrEqual m // 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 (_, _, [x]) -> transUnaryOp isLinqExpressionsArithmeticTypeButNotUnsignedInt inp env x Expression.Negate (methodhandleof (fun x -> LanguagePrimitives.UnaryNegationDynamic x)) - | PlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | MinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | MultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | DivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | ModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - - | ShiftLeftQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.LeftShift (methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y)) - | ShiftRightQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.RightShift (methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y)) - | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.And (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y)) - | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Or (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y)) - | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y)) + | PlusQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | MinusQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | MultiplyQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | DivideQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | ModuloQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + + | ShiftLeftQ (_, _, [x1; x2]) -> transShiftOp inp env false x1 x2 false Expression.LeftShift (methodhandleof (fun (x, y) -> LanguagePrimitives.LeftShiftDynamic x y)) + | ShiftRightQ (_, _, [x1; x2]) -> transShiftOp inp env false x1 x2 false Expression.RightShift (methodhandleof (fun (x, y) -> LanguagePrimitives.RightShiftDynamic x y)) + | BitwiseAndQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsIntegerOrBool inp env false x1 x2 false Expression.And (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseAndDynamic x y)) + | BitwiseOrQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsIntegerOrBool inp env false x1 x2 false Expression.Or (methodhandleof (fun (x, y) -> LanguagePrimitives.BitwiseOrDynamic x y)) + | BitwiseXorQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsIntegerOrBool inp env false x1 x2 false Expression.ExclusiveOr (methodhandleof (fun (x, y) -> LanguagePrimitives.ExclusiveOrDynamic x y)) | BitwiseNotQ (_, _, [x]) -> transUnaryOp isLinqExpressionsIntegerOrBool inp env x Expression.Not (methodhandleof (fun x -> LanguagePrimitives.LogicalNotDynamic x)) | CheckedNeg (_, _, [x]) -> transUnaryOp isLinqExpressionsArithmeticTypeButNotUnsignedInt inp env x Expression.NegateChecked (methodhandleof (fun x -> LanguagePrimitives.CheckedUnaryNegationDynamic x)) - | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.AddChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y)) - | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.SubtractChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y)) - | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y)) + | CheckedPlusQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.AddChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedAdditionDynamic x y)) + | CheckedMinusQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.SubtractChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedSubtractionDynamic x y)) + | CheckedMultiplyQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.MultiplyChecked (methodhandleof (fun (x, y) -> LanguagePrimitives.CheckedMultiplyDynamic x y)) - | NullablePlusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | PlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | NullablePlusQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 true Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | PlusNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env true x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) + | NullablePlusNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Add (methodhandleof (fun (x, y) -> LanguagePrimitives.AdditionDynamic x y)) - | NullableMinusQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | MinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | NullableMinusQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 true Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | MinusNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env true x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) + | NullableMinusNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Subtract (methodhandleof (fun (x, y) -> LanguagePrimitives.SubtractionDynamic x y)) - | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | NullableMultiplyQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 true Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | MultiplyNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env true x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) + | NullableMultiplyNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Multiply (methodhandleof (fun (x, y) -> LanguagePrimitives.MultiplyDynamic x y)) - | NullableDivideQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | DivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | NullableDivideQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 true Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | DivideNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env true x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) + | NullableDivideNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Divide (methodhandleof (fun (x, y) -> LanguagePrimitives.DivisionDynamic x y)) - | NullableModuloQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 true Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env true x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) - | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | NullableModuloQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 true Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | ModuloNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env true x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) + | NullableModuloNullableQ (_, _, [x1; x2]) -> transBinOp isLinqExpressionsArithmeticType inp env false x1 x2 false Expression.Modulo (methodhandleof (fun (x, y) -> LanguagePrimitives.ModulusDynamic x y)) | ConvNullableCharQ (_, _, [x]) | ConvNullableDecimalQ (_, _, [x]) | ConvNullableFloatQ (_, _, [x]) | ConvNullableDoubleQ (_, _, [x]) -> transConv inp env false x | ConvNullableFloat32Q (_, _, [x]) | ConvNullableSingleQ (_, _, [x]) | ConvNullableSByteQ (_, _, [x]) | ConvNullableInt8Q (_, _, [x]) -> transConv inp env false x @@ -711,24 +802,35 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e, method.MakeGenericMethod [| getNonNullableType x.Type; getNonNullableType inp.Type |]) |> asExpr - and transBinOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = + and transShiftOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = + 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 + if e1.Type = e2.Type && isLinqExpressionsSimpleShift e1.Type e2.Type then + exprErasedConstructor(e1, e2, null) + else + let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo + exprErasedConstructor(e1, e2, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) + |> asExpr + and transBinOp linqExpressionsCondition inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = 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 - if e1.Type = e2.Type && isLinqExpressionsArithmeticType e1.Type then + if e1.Type = e2.Type && linqExpressionsCondition e1.Type then exprErasedConstructor(e1, e2, null) else let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e1, e2, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) |> asExpr // The F# boolean structural equality / comparison operators do not take witnesses and the referenced methods are callable directly - and transBoolOpNoWitness env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = + and transBoolOpNoWitness linqExpressionsCondition env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = 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 - if e1'.Type = e2'.Type && isLinqExpressionsStructurallyEquatable e1.Type then + if e1'.Type = e2'.Type && linqExpressionsCondition e1.Type then // The false for (liftToNull: bool) indicates whether equality operators return a Nullable like in VB.NET (null when either argument is null) instead of bool like in C# (nulls equate to nulls). F# follows C# here. exprErasedConstructor(e1', e2', false, null) else @@ -748,12 +850,12 @@ module LeafExpressionConverter = and transConv (inp: Expr) env isChecked x = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert - try exprErasedConstructor(e, inp.Type, null) with _ -> - // LINQ Expressions' arithmetic operators do not handle byte, sbyte and char. In this case, use the F# operator as the user-defined method. - let nullableUnderlyingType (exp: Expr) = match Nullable.GetUnderlyingType exp.Type with null -> exp.Type | t -> t + if isLinqExpressionsConvertible e.Type inp.Type then + exprErasedConstructor(e, inp.Type, null) + else // The dynamic implementations of checked conversion operators refer to LanguagePrimitives.ExplicitDynamic which is unchecked! This is a bug and should definitely be fixed. let method = Reflection.MethodInfo.GetMethodFromHandle (methodhandleof (fun x -> LanguagePrimitives.ExplicitDynamic x)) :?> Reflection.MethodInfo - exprErasedConstructor(e, inp.Type, method.MakeGenericMethod [| nullableUnderlyingType x; nullableUnderlyingType inp |]) + exprErasedConstructor(e, inp.Type, method.MakeGenericMethod [| getNonNullableType x.Type; getNonNullableType inp.Type |]) |> asExpr and ConvObjArg env objOpt coerceTo : Expression = diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs index d66792beec3..3f3e0d8567f 100644 --- a/src/fsharp/FSharp.Core/array.fs +++ b/src/fsharp/FSharp.Core/array.fs @@ -404,6 +404,17 @@ namespace Microsoft.FSharp.Collections if len1 <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length let rec loop i = i >= len1 || (f.Invoke(array1.[i], array2.[i]) && loop (i+1)) loop 0 + + [] + let internal forall3 predicate (array1: _[]) (array2: _[]) (array3: _[]) = + if isNull array1 then nullArg (nameof array1) + if isNull array2 then nullArg (nameof array2) + if isNull array3 then nullArg (nameof array3) + let f = OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt(predicate) + let len1 = array1.Length + if len1 <> array2.Length || len1 <> array3.Length then invalidArg3ArraysDifferent "array1" "array2" "array3" array1.Length array2.Length array3.Length + let rec loop i = i >= len1 || (f.Invoke(array1.[i], array2.[i], array3.[i]) && loop (i+1)) + loop 0 let inline groupByImpl (comparer: IEqualityComparer<'SafeKey>) (keyf: 'T->'SafeKey) (getKey: 'SafeKey->'Key) (array: 'T[]) = let length = array.Length diff --git a/src/fsharp/FSharp.Core/array.fsi b/src/fsharp/FSharp.Core/array.fsi index e14b973b8b5..d5eb3765208 100644 --- a/src/fsharp/FSharp.Core/array.fsi +++ b/src/fsharp/FSharp.Core/array.fsi @@ -459,6 +459,26 @@ namespace Microsoft.FSharp.Collections [] val forall2: predicate:('T1 -> 'T2 -> bool) -> array1:'T1[] -> array2:'T2[] -> bool + /// Tests if all corresponding elements of three arrays satisfy the given predicate pairwise. + /// + /// The predicate is applied to matching elements in the three collections up to the lesser of the + /// three lengths of the collections. If any application returns false then the overall result is + /// false and no further elements are tested. Otherwise, if one collection is longer + /// than the others then the ArgumentException exception is raised. + /// Otherwise, true is returned. + /// + /// The function to test the input elements. + /// The first input array. + /// The second input array. + /// The third input array. + /// + /// Thrown when any of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// True if all of the array elements satisfy the predicate. + [] + val internal forall3: predicate:('T1 -> 'T2 -> 'T3 -> bool) -> array1:'T1[] -> array2:'T2[] -> array3:'T3[] -> bool + /// Applies a function to each element of the collection, threading an accumulator argument /// through the computation. If the input function is f and the elements are i0...iN then computes /// f (... (f s i0)...) iN From 3c62992a83ef071cad21c12372d1f0019f756c77 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 13 Aug 2021 18:27:27 +0800 Subject: [PATCH 67/78] Fix build error --- src/fsharp/FSharp.Core/Linq.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 95962ea6826..612200f1f72 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -232,7 +232,7 @@ module LeafExpressionConverter = | GenericParameterAttributes.None -> false | GenericParameterAttributes.Covariant -> hasReferenceConversionTo sourceArgument destArgument | GenericParameterAttributes.Contravariant -> not (sourceArgument.IsValueType || destArgument.IsValueType) - | x -> failwith $"Unexpected GenericParameterAttributes variance: {x}" + | x -> Printf.failwithf "Unexpected GenericParameterAttributes variance: %O" x ) // TODO: Is expanding this worth it? // || (source.IsArray || dest.IsArray) && StrictHasReferenceConversionTo(source, dest, true) From 24081cf956fddd2de93bb303fd03f85cd8667a85 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 14 Aug 2021 18:08:00 +0800 Subject: [PATCH 68/78] Fix bug --- src/fsharp/FSharp.Core/Linq.fs | 4 +--- src/fsharp/FSharp.Core/prim-types.fs | 23 +++++++++++++++---- .../FSharp.Core/PrimTypes.fs | 23 +++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 612200f1f72..e91b5c39fc2 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -899,6 +899,4 @@ module LeafExpressionConverter = d.DynamicInvoke [| box () |] with :? System.Reflection.TargetInvocationException as exn -> raise exn.InnerException -#endif - - +#endif \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 596b05918a4..320f9b14f88 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2536,9 +2536,17 @@ namespace Microsoft.FSharp.Core type System.Type with member inline this.GetSingleStaticMethodByTypes(name: string, parameterTypes: Type[]) = - let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic - this.GetMethod(name, staticBindingFlags, null, parameterTypes, null ) - + let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic + this.GetMethod(name, staticBindingFlags, null, parameterTypes, null ) + // Logic based on https://github.com/dotnet/runtime/blob/f66b142980b2b0df738158457458e003944dc7f6/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L662 + member inline this.GetSingleStaticConversionOperatorByTypes(fromType : Type, toType : Type) = + let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic + let mutable ret = null + for mi in this.GetMethods staticBindingFlags do + if (System.String.Equals(mi.Name, "op_Implicit") || System.String.Equals(mi.Name, "op_Explicit")) && + (let p = mi.GetParameters() in p.Length = 1 && (get p 0).ParameterType.IsEquivalentTo fromType) && mi.ReturnType.IsEquivalentTo toType then + ret <- mi + ret let UnaryDynamicImpl nm : ('T -> 'U) = let aty = typeof<'T> let minfo = aty.GetSingleStaticMethodByTypes(nm, [| aty |]) @@ -2560,7 +2568,14 @@ namespace Microsoft.FSharp.Core match meth with | null -> - let ameth = aty.GetSingleStaticMethodByTypes(opName, [| aty |]) + let ameth = + if System.String.Equals(opName, "op_Explicit") then + let aty2 = typeof<'U> + match aty.GetSingleStaticConversionOperatorByTypes(aty, aty2) with + | null -> aty2.GetSingleStaticConversionOperatorByTypes(aty, aty2) + | ameth -> ameth + else + aty.GetSingleStaticMethodByTypes(opName, [| aty |]) match ameth with | null -> raise (NotSupportedException (SR.GetString(SR.dyInvOpAddCoerce))) | res -> diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs index 81429996a05..bf7960a4d31 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs @@ -917,3 +917,26 @@ type NonStructuralComparisonTests() = let y = 32 |> float32 let comparison = compare x y Assert.AreEqual(0, comparison) + +module DynamicConversionTests = + type A = A + type B() = class end + type [] C = + static member op_Explicit(_: A) = C() // Explicit from another type + static member op_Explicit(_: C) = B() // Explicit to another type + static member op_Implicit(_: D) = C() // Duplicated implicit conversion + static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion + and D = { D : int } with + static member op_Implicit(_: A) = { D = 0 } // Implicit from another type + static member op_Implicit(_: D) = B() // Implicit to another type + static member op_Implicit(_: D) = C() // Duplicated implicit conversion + static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion + let [] ExplicitDynamicTests() = + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) // Explicit from another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : B) // Explicit to another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : D) // Duplicated explicit conversion + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : D) // Implicit from another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : B) // Implicit to another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : D) // Duplicated explicit conversion \ No newline at end of file From 0aa574be85746ddda86f2c907cdc9a572deaa0c4 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 15 Aug 2021 15:40:00 +0800 Subject: [PATCH 69/78] Fix warning --- tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs index bf7960a4d31..7153bfbfa7b 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs @@ -918,6 +918,7 @@ type NonStructuralComparisonTests() = let comparison = compare x y Assert.AreEqual(0, comparison) +#nowarn "1204" // CompilerMessage: This function is for use by dynamic invocations of F# code and should not be used directly module DynamicConversionTests = type A = A type B() = class end From c53e9139d35be9e3c3f07f01f016e42401ba8d44 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 15 Aug 2021 18:32:46 +0800 Subject: [PATCH 70/78] Fix last bug --- src/fsharp/FSharp.Core/prim-types.fs | 2 +- tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 320f9b14f88..1a321218f7c 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3203,7 +3203,7 @@ namespace Microsoft.FSharp.Core elif type2eq<'T1, 'T2, char> && typeeq<'U, bool> then convPrim<_,'U> (not (# "ceq" (convPrim<_,char> x) (convPrim<_,char> y) : bool #)) elif type2eq<'T1, 'T2, decimal> && typeeq<'U, bool> then convPrim<_,'U> (Decimal.op_Inequality (convPrim<_,decimal> x, convPrim<_,decimal> y)) elif type2eq<'T1, 'T2, string> && typeeq<'U, bool> then convPrim<_,'U> (not (String.Equals (convPrim<_,string> x, convPrim<_,string> y))) - else BinaryOpDynamicImplTable.Invoke "op_Inequality" x y + else BinaryOpDynamicImplTable.Invoke "op_Inequality" x y type DivideByIntInfo = class end let DivideByIntDynamic<'T> (x: 'T) (n: int) : 'T = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs index 7153bfbfa7b..50f2a157b6e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs @@ -921,8 +921,12 @@ type NonStructuralComparisonTests() = #nowarn "1204" // CompilerMessage: This function is for use by dynamic invocations of F# code and should not be used directly module DynamicConversionTests = type A = A - type B() = class end + type B() = + static member op_Equality(_: B, _: B) = false + static member op_Inequality(_: B, _: B) = true type [] C = + static member op_Equality(_: C, _: C) = true + static member op_Inequality(_: C, _: C) = true static member op_Explicit(_: A) = C() // Explicit from another type static member op_Explicit(_: C) = B() // Explicit to another type static member op_Implicit(_: D) = C() // Duplicated implicit conversion @@ -933,6 +937,11 @@ module DynamicConversionTests = static member op_Implicit(_: D) = C() // Duplicated implicit conversion static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion let [] ExplicitDynamicTests() = + Assert.False(LanguagePrimitives.EqualityDynamic(B())(B()) : bool) + Assert.True(LanguagePrimitives.InequalityDynamic(B())(B()) : bool) + Assert.True(LanguagePrimitives.EqualityDynamic(C())(C()) : bool) + Assert.True(LanguagePrimitives.InequalityDynamic(C())(C()) : bool) + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) // Explicit from another type Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : B) // Explicit to another type Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion From 70987503f821d0b7545b4b4d36c4ffd9e7e74797 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 16 Aug 2021 02:01:16 +0800 Subject: [PATCH 71/78] Tests yay --- src/fsharp/FSharp.Core/Linq.fs | 3 +- .../FSharp.Core/fslib-extra-pervasives.fs | 3 +- src/fsharp/FSharp.Core/prim-types.fs | 281 +++++- src/fsharp/FSharp.Core/prim-types.fsi | 4 + .../Expressions/Type-relatedExpressions.fs | 3 +- .../FSharp.Core.UnitTests.fsproj | 1 + .../FSharp.Core/OperatorsModule1.fs | 19 +- .../FSharp.Core/OperatorsModuleChecked.fs | 2 +- .../FSharp.Core/OperatorsModuleDynamic.fs | 936 ++++++++++++++++++ .../FSharp.Core/PrimTypes.fs | 33 - tests/FSharp.Core.UnitTests/SurfaceArea.fs | 1 + 11 files changed, 1220 insertions(+), 66 deletions(-) create mode 100644 tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index e91b5c39fc2..a6c5cf4785b 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -853,8 +853,7 @@ module LeafExpressionConverter = if isLinqExpressionsConvertible e.Type inp.Type then exprErasedConstructor(e, inp.Type, null) else - // The dynamic implementations of checked conversion operators refer to LanguagePrimitives.ExplicitDynamic which is unchecked! This is a bug and should definitely be fixed. - let method = Reflection.MethodInfo.GetMethodFromHandle (methodhandleof (fun x -> LanguagePrimitives.ExplicitDynamic x)) :?> Reflection.MethodInfo + let method = Reflection.MethodInfo.GetMethodFromHandle (if isChecked then methodhandleof (fun x -> LanguagePrimitives.CheckedExplicitDynamic x) else methodhandleof (fun x -> LanguagePrimitives.ExplicitDynamic x)) :?> Reflection.MethodInfo exprErasedConstructor(e, inp.Type, method.MakeGenericMethod [| getNonNullableType x.Type; getNonNullableType inp.Type |]) |> asExpr diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index 5fd4e32b29e..98994db6e11 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -374,5 +374,4 @@ namespace Microsoft.FSharp.Core.CompilerServices type ITypeProvider2 = abstract GetStaticParametersForMethod : methodWithoutArguments:MethodBase -> ParameterInfo[] - abstract ApplyStaticArgumentsForMethod : methodWithoutArguments:MethodBase * methodNameWithArguments:string * staticArguments:obj[] -> MethodBase - + abstract ApplyStaticArgumentsForMethod : methodWithoutArguments:MethodBase * methodNameWithArguments:string * staticArguments:obj[] -> MethodBase \ No newline at end of file diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 1a321218f7c..2d875c72e59 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2861,7 +2861,7 @@ namespace Microsoft.FSharp.Core let ExplicitDynamic<'T, 'U> (value: 'T) : 'U = if typeeq<'U, byte> then if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.u1" (convPrim<_,sbyte> value) : byte #) - elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u1" (convPrim<_,byte> value) : byte #) + elif typeeq<'T, byte> then convPrim<_,'U> value elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u1" (convPrim<_,int16> value) : byte #) elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u1" (convPrim<_,uint16> value) : byte #) elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u1" (convPrim<_,int32> value) : byte #) @@ -2876,7 +2876,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, string> then convPrim<_,'U> (ParseByte (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, sbyte> then - if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i1" (convPrim<_,sbyte> value) : sbyte #) + if typeeq<'T, sbyte> then convPrim<_,'U> value elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.i1" (convPrim<_,byte> value) : sbyte #) elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i1" (convPrim<_,int16> value) : sbyte #) elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i1" (convPrim<_,uint16> value) : sbyte #) @@ -2895,7 +2895,7 @@ namespace Microsoft.FSharp.Core if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.u2" (convPrim<_,sbyte> value) : uint16 #) elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.u2" (convPrim<_,byte> value) : uint16 #) elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int16> value) : uint16 #) - elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint16> value) : uint16 #) + elif typeeq<'T, uint16> then convPrim<_,'U> value elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int32> value) : uint16 #) elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,uint32> value) : uint16 #) elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.u2" (convPrim<_,int64> value) : uint16 #) @@ -2910,7 +2910,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'U, int16> then if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.i2" (convPrim<_,sbyte> value) : int16 #) elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.i2" (convPrim<_,byte> value) : int16 #) - elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i2" (convPrim<_,int16> value) : int16 #) + elif typeeq<'T, int16> then convPrim<_,'U> value elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i2" (convPrim<_,uint16> value) : int16 #) elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i2" (convPrim<_,int32> value) : int16 #) elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.i2" (convPrim<_,uint32> value) : int16 #) @@ -2929,7 +2929,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.u4" (convPrim<_,int16> value) : uint32 #) elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u4" (convPrim<_,uint16> value) : uint32 #) elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.u4" (convPrim<_,int32> value) : uint32 #) - elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u4" (convPrim<_,uint32> value) : uint32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> value elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.u4" (convPrim<_,int64> value) : uint32 #) elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u4" (convPrim<_,uint64> value) : uint32 #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.u4" (convPrim<_,nativeint> value) : uint32 #) @@ -2944,7 +2944,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.i4" (convPrim<_,byte> value) : int32 #) elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int16> value) : int32 #) elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint16> value) : int32 #) - elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int32> value) : int32 #) + elif typeeq<'T, int32> then convPrim<_,'U> value elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint32> value) : int32 #) elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int64> value) : int32 #) elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint64> value) : int32 #) @@ -2963,7 +2963,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i8" (convPrim<_,int32> value) : uint64 #) elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint32> value) : uint64 #) elif typeeq<'T, int64> then convPrim<_,'U> (# "" (convPrim<_,int64> value) : uint64 #) - elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i8" (convPrim<_,uint64> value) : uint64 #) + elif typeeq<'T, uint64> then convPrim<_,'U> value elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i8" (convPrim<_,nativeint> value) : uint64 #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u8" (convPrim<_,unativeint> value) : uint64 #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float> value) : uint64 #) @@ -2978,7 +2978,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint16> value) : int64 #) elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.i8" (convPrim<_,int32> value) : int64 #) elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,uint32> value) : int64 #) - elif typeeq<'T, int64> then convPrim<_,'U> (convPrim<_,int64> value) + elif typeeq<'T, int64> then convPrim<_,'U> value elif typeeq<'T, uint64> then convPrim<_,'U> (# "" (convPrim<_,uint64> value) : int64 #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i8" (convPrim<_,nativeint> value) : int64 #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u8" (convPrim<_,unativeint> value) : int64 #) @@ -2999,7 +2999,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r4" (convPrim<_,nativeint> value) : float32 #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,unativeint> value) : float32 #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float> value) : float32 #) - elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float32> value) : float32 #) + elif typeeq<'T, float32> then convPrim<_,'U> value elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,char> value) : float32 #) elif typeeq<'T, string> then convPrim<_,'U> (ParseSingle (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value @@ -3014,7 +3014,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint64> value) : float #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r8" (convPrim<_,nativeint> value) : float #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,unativeint> value) : float #) - elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float> value) : float #) + elif typeeq<'T, float> then convPrim<_,'U> value elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float32> value) : float #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,char> value) : float #) elif typeeq<'T, decimal> then convPrim<_,'U> (Convert.ToDouble(convPrim<_,decimal> value)) @@ -3030,7 +3030,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i" (convPrim<_,int64> value) : unativeint #) elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint64> value) : unativeint #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "" (convPrim<_,nativeint> value) : unativeint #) - elif typeeq<'T, unativeint> then convPrim<_,'U> (# "" (convPrim<_,unativeint> value) : unativeint #) + elif typeeq<'T, unativeint> then convPrim<_,'U> value elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u" (convPrim<_,float> value) : unativeint #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u" (convPrim<_,float32> value) : unativeint #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u" (convPrim<_,char> value) : unativeint #) @@ -3046,7 +3046,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint32> value) : nativeint #) elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i" (convPrim<_,int64> value) : nativeint #) elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.u" (convPrim<_,uint64> value) : nativeint #) - elif typeeq<'T, nativeint> then convPrim<_,'U> (# "" (convPrim<_,nativeint> value) : nativeint #) + elif typeeq<'T, nativeint> then convPrim<_,'U> value elif typeeq<'T, unativeint> then convPrim<_,'U> (# "" (convPrim<_,unativeint> value) : nativeint #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i" (convPrim<_,float> value) : nativeint #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i" (convPrim<_,float32> value) : nativeint #) @@ -3067,7 +3067,240 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u2" (convPrim<_,unativeint> value) : char #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float> value) : char #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float32> value) : char #) - elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u2" (convPrim<_,char> value) : char #) + elif typeeq<'T, char> then convPrim<_,'U> value + elif typeeq<'T, decimal> then convPrim<_,'U> (Decimal.op_Explicit (convPrim<_,decimal> value) : char) + elif typeeq<'T, string> then convPrim<_,'U> (System.Char.Parse (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, decimal> then + if typeeq<'T, sbyte> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,sbyte> value)) + elif typeeq<'T, byte> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,byte> value)) + elif typeeq<'T, int16> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,int16> value)) + elif typeeq<'T, uint16> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,uint16> value)) + elif typeeq<'T, int32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,int32> value)) + elif typeeq<'T, uint32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,uint32> value)) + elif typeeq<'T, int64> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,int64> value)) + elif typeeq<'T, uint64> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,uint64> value)) + elif typeeq<'T, nativeint> then convPrim<_,'U> (Convert.ToDecimal (# "conv.i8" (convPrim<_,nativeint> value) : int64 #)) + elif typeeq<'T, unativeint> then convPrim<_,'U> (Convert.ToDecimal (# "conv.u8" (convPrim<_,unativeint> value) : uint64 #)) + elif typeeq<'T, float> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float> value)) + elif typeeq<'T, float32> then convPrim<_,'U> (Convert.ToDecimal (convPrim<_,float32> value)) + elif typeeq<'T, char> then convPrim<_,'U> (Convert.ToDecimal (# "" (convPrim<_,char> value) : uint16 #)) + elif typeeq<'T, decimal> then convPrim<_,'U> value + elif typeeq<'T, string> then convPrim<_,'U> (Decimal.Parse(convPrim<_,string> value, NumberStyles.Float,CultureInfo.InvariantCulture)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + else + UnaryOpDynamicImplTable.Invoke "op_Explicit" value + + let CheckedExplicitDynamic<'T, 'U> (value: 'T) : 'U = + if typeeq<'U, byte> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,sbyte> value) : byte #) + elif typeeq<'T, byte> then convPrim<_,'U> value + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,int16> value) : byte #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.u1.un" (convPrim<_,uint16> value) : byte #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,int32> value) : byte #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.u1.un" (convPrim<_,uint32> value) : byte #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,int64> value) : byte #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.u1.un" (convPrim<_,uint64> value) : byte #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,nativeint> value) : byte #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.u1.un" (convPrim<_,unativeint> value) : byte #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,float> value) : byte #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u1" (convPrim<_,float32> value) : byte #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.u1.un" (convPrim<_,char> value) : byte #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseByte (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, sbyte> then + if typeeq<'T, sbyte> then convPrim<_,'U> value + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.i1.un" (convPrim<_,byte> value) : sbyte #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.i1" (convPrim<_,int16> value) : sbyte #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.i1.un" (convPrim<_,uint16> value) : sbyte #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.i1" (convPrim<_,int32> value) : sbyte #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.i1.un" (convPrim<_,uint32> value) : sbyte #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.i1" (convPrim<_,int64> value) : sbyte #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.i1.un" (convPrim<_,uint64> value) : sbyte #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.i1" (convPrim<_,nativeint> value) : sbyte #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.i1.un" (convPrim<_,unativeint> value) : sbyte #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.i1" (convPrim<_,float> value) : sbyte #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.i1" (convPrim<_,float32> value) : sbyte #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.i1.un" (convPrim<_,char> value) : sbyte #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseSByte (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, uint16> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,sbyte> value) : uint16 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,byte> value) : uint16 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int16> value) : uint16 #) + elif typeeq<'T, uint16> then convPrim<_,'U> value + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int32> value) : uint16 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint32> value) : uint16 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int64> value) : uint16 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint64> value) : uint16 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,nativeint> value) : uint16 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,unativeint> value) : uint16 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,float> value) : uint16 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,float32> value) : uint16 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,char> value) : uint16 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt16 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, int16> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.i2" (convPrim<_,sbyte> value) : int16 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.i2.un" (convPrim<_,byte> value) : int16 #) + elif typeeq<'T, int16> then convPrim<_,'U> value + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.i2.un" (convPrim<_,uint16> value) : int16 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.i2" (convPrim<_,int32> value) : int16 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.i2.un" (convPrim<_,uint32> value) : int16 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.i2" (convPrim<_,int64> value) : int16 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.i2.un" (convPrim<_,uint64> value) : int16 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.i2" (convPrim<_,nativeint> value) : int16 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.i2.un" (convPrim<_,unativeint> value) : int16 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.i2" (convPrim<_,float> value) : int16 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.i2" (convPrim<_,float32> value) : int16 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.i2.un" (convPrim<_,char> value) : int16 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseInt16 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, uint32> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,sbyte> value) : uint32 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.u4.un" (convPrim<_,byte> value) : uint32 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,int16> value) : uint32 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.u4.un" (convPrim<_,uint16> value) : uint32 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,int32> value) : uint32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> value + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,int64> value) : uint32 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.u4.un" (convPrim<_,uint64> value) : uint32 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,nativeint> value) : uint32 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.u4.un" (convPrim<_,unativeint> value) : uint32 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,float> value) : uint32 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u4" (convPrim<_,float32> value) : uint32 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.u4.un" (convPrim<_,char> value) : uint32 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt32 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, int32> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.i4" (convPrim<_,sbyte> value) : int32 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.i4.un" (convPrim<_,byte> value) : int32 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.i4" (convPrim<_,int16> value) : int32 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.i4.un" (convPrim<_,uint16> value) : int32 #) + elif typeeq<'T, int32> then convPrim<_,'U> value + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.i4.un" (convPrim<_,uint32> value) : int32 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.i4" (convPrim<_,int64> value) : int32 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.i4.un" (convPrim<_,uint64> value) : int32 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.i4" (convPrim<_,nativeint> value) : int32 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.i4.un" (convPrim<_,unativeint> value) : int32 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.i4" (convPrim<_,float> value) : int32 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.i4" (convPrim<_,float32> value) : int32 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.i4.un" (convPrim<_,char> value) : int32 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseInt32 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, uint64> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,sbyte> value) : uint64 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.u8.un" (convPrim<_,byte> value) : uint64 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,int16> value) : uint64 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.u8.un" (convPrim<_,uint16> value) : uint64 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,int32> value) : uint64 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.u8.un" (convPrim<_,uint32> value) : uint64 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,int64> value) : uint64 #) + elif typeeq<'T, uint64> then convPrim<_,'U> value + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,nativeint> value) : uint64 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.u8.un" (convPrim<_,unativeint> value) : uint64 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,float> value) : uint64 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u8" (convPrim<_,float32> value) : uint64 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.u8.un" (convPrim<_,char> value) : uint64 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt64 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, int64> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.i8" (convPrim<_,sbyte> value) : int64 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.i8.un" (convPrim<_,byte> value) : int64 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.i8" (convPrim<_,int16> value) : int64 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.i8.un" (convPrim<_,uint16> value) : int64 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.i8" (convPrim<_,int32> value) : int64 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.i8.un" (convPrim<_,uint32> value) : int64 #) + elif typeeq<'T, int64> then convPrim<_,'U> value + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.i8.un" (convPrim<_,uint64> value) : int64 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.i8" (convPrim<_,nativeint> value) : int64 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.i8.un" (convPrim<_,unativeint> value) : int64 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.i8" (convPrim<_,float> value) : int64 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.i8" (convPrim<_,float32> value) : int64 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.i8.un" (convPrim<_,char> value) : int64 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseInt64 (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, float32> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.r4" (convPrim<_,sbyte> value) : float32 #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,byte> value) : float32 #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.r4" (convPrim<_,int16> value) : float32 #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,uint16> value) : float32 #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.r4" (convPrim<_,int32> value) : float32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,uint32> value) : float32 #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.r4" (convPrim<_,int64> value) : float32 #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,uint64> value) : float32 #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r4" (convPrim<_,nativeint> value) : float32 #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,unativeint> value) : float32 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float> value) : float32 #) + elif typeeq<'T, float32> then convPrim<_,'U> value + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,char> value) : float32 #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseSingle (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, float> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.r8" (convPrim<_,sbyte> value) : float #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,byte> value) : float #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.r8" (convPrim<_,int16> value) : float #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint16> value) : float #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.r8" (convPrim<_,int32> value) : float #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint32> value) : float #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.r8" (convPrim<_,int64> value) : float #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint64> value) : float #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r8" (convPrim<_,nativeint> value) : float #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,unativeint> value) : float #) + elif typeeq<'T, float> then convPrim<_,'U> value + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float32> value) : float #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,char> value) : float #) + elif typeeq<'T, decimal> then convPrim<_,'U> (Convert.ToDouble(convPrim<_,decimal> value)) + elif typeeq<'T, string> then convPrim<_,'U> (ParseDouble (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, unativeint> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,sbyte> value) : unativeint #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.u.un" (convPrim<_,byte> value) : unativeint #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,int16> value) : unativeint #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.u.un" (convPrim<_,uint16> value) : unativeint #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,int32> value) : unativeint #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.u.un" (convPrim<_,uint32> value) : unativeint #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,int64> value) : unativeint #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.u.un" (convPrim<_,uint64> value) : unativeint #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,nativeint> value) : unativeint #) + elif typeeq<'T, unativeint> then convPrim<_,'U> value + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,float> value) : unativeint #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u" (convPrim<_,float32> value) : unativeint #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.u.un" (convPrim<_,char> value) : unativeint #) + elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.ovf.u" (Decimal.op_Explicit (convPrim<_,decimal> value) : uint64) : unativeint #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseUIntPtr (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, nativeint> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.i" (convPrim<_,sbyte> value) : nativeint #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.i.un" (convPrim<_,byte> value) : nativeint #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.i" (convPrim<_,int16> value) : nativeint #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.i.un" (convPrim<_,uint16> value) : nativeint #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.i" (convPrim<_,int32> value) : nativeint #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.i.un" (convPrim<_,uint32> value) : nativeint #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.i" (convPrim<_,int64> value) : nativeint #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.i.un" (convPrim<_,uint64> value) : nativeint #) + elif typeeq<'T, nativeint> then convPrim<_,'U> value + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.i.un" (convPrim<_,unativeint> value) : nativeint #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.i" (convPrim<_,float> value) : nativeint #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.i" (convPrim<_,float32> value) : nativeint #) + elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.i.un" (convPrim<_,char> value) : nativeint #) + elif typeeq<'T, decimal> then convPrim<_,'U> (# "conv.ovf.i" (Decimal.op_Explicit (convPrim<_,decimal> value) : int64) : nativeint #) + elif typeeq<'T, string> then convPrim<_,'U> (ParseIntPtr (convPrim<_,string> value)) + else UnaryOpDynamicImplTable.Invoke "op_Explicit" value + elif typeeq<'U, char> then + if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,sbyte> value) : char #) + elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,byte> value) : char #) + elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int16> value) : char #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint16> value) : char #) + elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int32> value) : char #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint32> value) : char #) + elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int64> value) : char #) + elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint64> value) : char #) + elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,nativeint> value) : char #) + elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,unativeint> value) : char #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,float> value) : char #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,float32> value) : char #) + elif typeeq<'T, char> then convPrim<_,'U> value elif typeeq<'T, decimal> then convPrim<_,'U> (Decimal.op_Explicit (convPrim<_,decimal> value) : char) elif typeeq<'T, string> then convPrim<_,'U> (System.Char.Parse (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value @@ -4969,7 +5202,7 @@ namespace Microsoft.FSharp.Core [] [] let inline byte (value: ^T) = - ExplicitDynamic<(^T),byte> value + CheckedExplicitDynamic<(^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 #) @@ -4989,7 +5222,7 @@ namespace Microsoft.FSharp.Core [] [] let inline sbyte (value: ^T) = - ExplicitDynamic<(^T),sbyte> value + CheckedExplicitDynamic<(^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 #) @@ -5009,7 +5242,7 @@ namespace Microsoft.FSharp.Core [] [] let inline uint16 (value: ^T) = - ExplicitDynamic<(^T),uint16> value + CheckedExplicitDynamic<(^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 #) @@ -5029,7 +5262,7 @@ namespace Microsoft.FSharp.Core [] [] let inline char (value: ^T) = - ExplicitDynamic<(^T), char> value + CheckedExplicitDynamic<(^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 #) @@ -5049,7 +5282,7 @@ namespace Microsoft.FSharp.Core [] [] let inline int16 (value: ^T) = - ExplicitDynamic<(^T), int16> value + CheckedExplicitDynamic<(^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 #) @@ -5069,7 +5302,7 @@ namespace Microsoft.FSharp.Core [] [] let inline uint32 (value: ^T) = - ExplicitDynamic<(^T), uint32> value + CheckedExplicitDynamic<(^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 #) @@ -5089,7 +5322,7 @@ namespace Microsoft.FSharp.Core [] [] let inline int32 (value: ^T) = - ExplicitDynamic<(^T), int32> value + CheckedExplicitDynamic<(^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 #) @@ -5112,7 +5345,7 @@ namespace Microsoft.FSharp.Core [] [] let inline uint64 (value: ^T) = - ExplicitDynamic<(^T), uint64> value + CheckedExplicitDynamic<(^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 #) @@ -5132,7 +5365,7 @@ namespace Microsoft.FSharp.Core [] [] let inline int64 (value: ^T) = - ExplicitDynamic<(^T), int64> value + CheckedExplicitDynamic<(^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 #) @@ -5152,7 +5385,7 @@ namespace Microsoft.FSharp.Core [] [] let inline unativeint (value: ^T) = - ExplicitDynamic<(^T), unativeint> value + CheckedExplicitDynamic<(^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 #) @@ -5173,7 +5406,7 @@ namespace Microsoft.FSharp.Core [] [] let inline nativeint (value: ^T) = - ExplicitDynamic<(^T), nativeint> value + CheckedExplicitDynamic<(^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 #) diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index baa9a5127b2..76e5972b79c 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -1560,6 +1560,10 @@ namespace Microsoft.FSharp.Core [] val ExplicitDynamic : value:'T -> 'U + /// A compiler intrinsic that implements dynamic invocations related to checked conversion operators. + [] + val CheckedExplicitDynamic : value:'T -> 'U + /// A compiler intrinsic that implements dynamic invocations related to the '<' operator. [] val LessThanDynamic : x:'T1 -> y:'T2 -> 'U diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs index 374e6b49797..43e059a4f12 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/Type-relatedExpressions.fs @@ -15,5 +15,4 @@ module TyperelatedExpressions = |> asFsx |> typecheck |> shouldSucceed - |> ignore - + |> ignore \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj index aa39265d2a0..5d940937684 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj @@ -41,6 +41,7 @@ + diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 62db48e2ec9..66101cf80f7 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -311,8 +311,19 @@ type OperatorsModule1() = [] member _.char() = // int type - let intchar = Operators.char 48 - Assert.AreEqual('0', intchar) + Assert.AreEqual('0', Operators.char 48) + Assert.AreEqual('0', Operators.char 48u) + Assert.AreEqual('0', Operators.char 48s) + Assert.AreEqual('0', Operators.char 48us) + Assert.AreEqual('0', Operators.char 48y) + Assert.AreEqual('0', Operators.char 48uy) + Assert.AreEqual('0', Operators.char 48L) + Assert.AreEqual('0', Operators.char 48uL) + Assert.AreEqual('0', Operators.char 48n) + Assert.AreEqual('0', Operators.char 48un) + Assert.AreEqual('0', Operators.char 48f) + Assert.AreEqual('0', Operators.char 48.) + Assert.AreEqual('0', Operators.char 48m) // string type let stringchar = Operators.char " " @@ -368,6 +379,10 @@ type OperatorsModule1() = // int value let mindecimal = Operators.decimal (1) Assert.AreEqual(1M, mindecimal) + + // char value + let mindecimal = Operators.decimal '\001' + Assert.AreEqual(1M, mindecimal) // float value let maxdecimal = Operators.decimal (1.0) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs index bcd16f54e27..482335e8b13 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs @@ -21,7 +21,7 @@ type OperatorsModuleChecked() = let charByte = Operators.Checked.byte '0' Assert.AreEqual(48uy, charByte) - // boundary value + // boundary value let boundByte = Operators.Checked.byte 255.0 Assert.AreEqual(255uy, boundByte) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs new file mode 100644 index 00000000000..d741c584131 --- /dev/null +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs @@ -0,0 +1,936 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Sync test content with OperatorsModule1.fs, OperatorsModule2.fs, and OperatorsModuleDynamic.fs + +namespace FSharp.Core.UnitTests.Operators + +open System +open FSharp.Core.UnitTests.LibraryTestFx +open Xunit +open Microsoft.FSharp.Core.Operators.Checked + +#nowarn "1204" // CompilerMessage: This function is for use by dynamic invocations of F# code and should not be used directly +module OperatorsModuleDynamic = + module Operators = + let byte<'T> = LanguagePrimitives.ExplicitDynamic<'T, byte> + let char<'T> = LanguagePrimitives.ExplicitDynamic<'T, char> + let double<'T> = LanguagePrimitives.ExplicitDynamic<'T, double> + let decimal<'T> = LanguagePrimitives.ExplicitDynamic<'T, decimal> + let float<'T> = LanguagePrimitives.ExplicitDynamic<'T, float> + let float32<'T> = LanguagePrimitives.ExplicitDynamic<'T, float32> + let int<'T> = LanguagePrimitives.ExplicitDynamic<'T, int> + let int8<'T> = LanguagePrimitives.ExplicitDynamic<'T, int8> + let int16<'T> = LanguagePrimitives.ExplicitDynamic<'T, int16> + let int32<'T> = LanguagePrimitives.ExplicitDynamic<'T, int32> + let int64<'T> = LanguagePrimitives.ExplicitDynamic<'T, int64> + let sbyte<'T> = LanguagePrimitives.ExplicitDynamic<'T, sbyte> + let single<'T> = LanguagePrimitives.ExplicitDynamic<'T, single> + let uint<'T> = LanguagePrimitives.ExplicitDynamic<'T, uint> + let uint8<'T> = LanguagePrimitives.ExplicitDynamic<'T, uint8> + let uint16<'T> = LanguagePrimitives.ExplicitDynamic<'T, uint16> + let uint32<'T> = LanguagePrimitives.ExplicitDynamic<'T, uint32> + let uint64<'T> = LanguagePrimitives.ExplicitDynamic<'T, uint64> + let unativeint<'T> = LanguagePrimitives.ExplicitDynamic<'T, unativeint> + module Checked = + let byte<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, byte> + let char<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, char> + let double<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, double> + let decimal<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, decimal> + let float<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, float> + let float32<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, float32> + let int<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int> + let int8<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int8> + let int16<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int16> + let int32<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int32> + let int64<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int64> + let sbyte<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, sbyte> + let single<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, single> + let uint<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, uint> + let uint8<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, uint8> + let uint16<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, uint16> + let uint32<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, uint32> + let uint64<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, uint64> + let unativeint<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, unativeint> + + [] + let byte() = + // int type + let intByte = Operators.byte 100 + Assert.AreEqual(100uy, intByte) + + // char type + let charByte = Operators.byte '0' + Assert.AreEqual(48uy, charByte) + + // boundary value + let boundByte = Operators.byte 255.0 + Assert.AreEqual(255uy, boundByte) + + // Overflow + let result = Operators.byte Int64.MaxValue + Assert.AreEqual(Byte.MaxValue, result) + + // Overflow + let result = Operators.byte Int64.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Double.MaxValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte (Int64.MaxValue * 8L) + Assert.AreEqual(248uy, result) // bit-complement + + // Overflow + let result = 255uy + 5uy + Assert.AreEqual(4uy, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.byte Decimal.MinValue |> ignore) + + [] + let char() = + // int type + Assert.AreEqual('0', Operators.char 48) + Assert.AreEqual('0', Operators.char 48u) + Assert.AreEqual('0', Operators.char 48s) + Assert.AreEqual('0', Operators.char 48us) + Assert.AreEqual('0', Operators.char 48y) + Assert.AreEqual('0', Operators.char 48uy) + Assert.AreEqual('0', Operators.char 48L) + Assert.AreEqual('0', Operators.char 48uL) + Assert.AreEqual('0', Operators.char 48n) + Assert.AreEqual('0', Operators.char 48un) + Assert.AreEqual('0', Operators.char 48f) + Assert.AreEqual('0', Operators.char 48.) + Assert.AreEqual('0', Operators.char 48m) + + // string type + let stringchar = Operators.char " " + Assert.AreEqual(' ', stringchar) + + + [] + let decimal () = + + // int value + let mindecimal = Operators.decimal (1) + Assert.AreEqual(1M, mindecimal) + + // char value + let mindecimal = Operators.decimal '\001' + Assert.AreEqual(1M, mindecimal) + + // float value + let maxdecimal = Operators.decimal (1.0) + Assert.AreEqual(1M, maxdecimal) + + [] + let double() = + // int type + let intdouble = Operators.float 100 + Assert.AreEqual(100.0, intdouble) + + // char type + let chardouble = Operators.float '0' + Assert.AreEqual(48.0, chardouble) + + + [] + let float() = + // int type + let intfloat = Operators.float 100 + Assert.AreEqual((float)100, intfloat) + + // char type + let charfloat = Operators.float '0' + Assert.AreEqual((float)48, charfloat) + + [] + let float32() = + // int type + let intfloat32 = Operators.float32 100 + Assert.AreEqual((float32)100, intfloat32) + + // char type + let charfloat32 = Operators.float32 '0' + Assert.AreEqual((float32)48, charfloat32) + + + [] + let int() = + // int + let result = Operators.int 10 + Assert.AreEqual(10, result) + + // string + let result = Operators.int "10" + Assert.AreEqual(10, result) + + // double + let result = Operators.int 10.0 + Assert.AreEqual(10, result) + + // negative + let result = Operators.int -10 + Assert.AreEqual(-10, result) + + // zero + let result = Operators.int 0 + Assert.AreEqual(0, result) + + // Overflow + let result = Operators.int Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 1 + Assert.AreEqual(Int32.MinValue, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int Decimal.MinValue |> ignore) + + [] + let int16() = + // int + let result = Operators.int16 10 + Assert.AreEqual(10s, result) + + // double + let result = Operators.int16 10.0 + Assert.AreEqual(10s, result) + + // negative + let result = Operators.int16 -10 + Assert.AreEqual(-10s, result) + + // zero + let result = Operators.int16 0 + Assert.AreEqual(0s, result) + + // string + let result = Operators.int16 "10" + Assert.AreEqual(10s, result) + + // Overflow + let result = Operators.int16 Double.MaxValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Operators.int16 Double.MinValue + Assert.AreEqual(0s, result) + + let result = Operators.int16 Int64.MaxValue + Assert.AreEqual(-1s, result) + + // Overflow + let result = Operators.int16 Int64.MinValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Int16.MaxValue + 1s + Assert.AreEqual(Int16.MinValue, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int16 Decimal.MinValue |> ignore) + + [] + let int32() = + // int + let result = Operators.int32 10 + Assert.AreEqual(10, result) + + // double + let result = Operators.int32 10.0 + Assert.AreEqual(10, result) + + // negative + let result = Operators.int32 -10 + Assert.AreEqual(-10, result) + + // zero + let result = Operators.int32 0 + Assert.AreEqual(0, result) + + // string + let result = Operators.int32 "10" + Assert.AreEqual(10, result) + + // Overflow + let result = Operators.int32 Double.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Double.MinValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Int64.MaxValue + Assert.AreEqual(-1, result) + + // Overflow + let result = Operators.int32 Int64.MinValue + Assert.AreEqual(0, result) + + // Overflow + let result = Int32.MaxValue + 5 + Assert.AreEqual(Int32.MinValue + 4, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int32 Decimal.MinValue |> ignore) + + [] + let int64() = + // int + let result = Operators.int64 10 + Assert.AreEqual(10L, result) + + // double + let result = Operators.int64 10.0 + Assert.AreEqual(10L, result) + + // negative + let result = Operators.int64 -10 + Assert.AreEqual(-10L, result) + + // zero + let result = Operators.int64 0 + Assert.AreEqual(0L, result) + + // string + let result = Operators.int64 "10" + Assert.AreEqual(10L, result) + + // Overflow. + let result = Operators.int64 Double.MaxValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 Double.MinValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 UInt64.MaxValue + Assert.AreEqual(-1L, result) + + // max and min value as literals (this breaks compilation if the lexer fails) + Assert.AreEqual(-9223372036854775808L, Int64.MinValue) + Assert.AreEqual(9223372036854775807L, Int64.MaxValue) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.int64 Decimal.MinValue |> ignore) + + + [] + let nativeint() = + // int + let result = Operators.nativeint 10 + Assert.AreEqual(10n, result) + + // double + let result = Operators.nativeint 10.0 + Assert.AreEqual(10n, result) + + // int64 + let result = Operators.nativeint 10L + Assert.AreEqual(10n, result) + + // negative + let result = Operators.nativeint -10 + Assert.AreEqual(-10n, result) + + // zero + let result = Operators.nativeint 0 + Assert.AreEqual(0n, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.nativeint Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + if Info.isX86Runtime then + let result = nativeint Int32.MaxValue + 5n + Assert.AreEqual(-2147483644n, result) + else + let result = nativeint Int64.MaxValue + 5n + Assert.AreEqual(-9223372036854775804n, result) + + + // Overflow (depends on pointer size) + let result = Operators.nativeint System.Double.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) + + let result = Operators.nativeint System.Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot express this as a literal, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual("-9223372036854775808", string result) + + // Max and min value as literals (this breaks compilation if the lexer fails). + // The following tests ensure that the proper value is parsed, which is similar to `nativeint Int64.MaxValue` etc. + if Info.isX86Runtime then + Assert.AreEqual("0", string -9223372036854775808n) // same as int32 -9223372036854775808L + Assert.AreEqual("-1", string 9223372036854775807n) // same as int32 9223372036854775807L + else + Assert.AreEqual("-9223372036854775808", string -9223372036854775808n) + Assert.AreEqual("9223372036854775807", string 9223372036854775807n) + + + [] + let sbyte() = + // int + let result = Operators.sbyte 10 + Assert.AreEqual(10y, result) + + // double + let result = Operators.sbyte 10.0 + Assert.AreEqual(10y, result) + + // negative + let result = Operators.sbyte -10 + Assert.AreEqual(-10y, result) + + // zero + let result = Operators.sbyte 0 + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Int64.MaxValue + Assert.AreEqual(-1y, result) + + // Overflow + let result = Operators.sbyte Int64.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Double.MaxValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte (Int64.MaxValue * 8L) + Assert.AreEqual(-8y, result) // bit-complement + + // Overflow + let result = 127y + 1y + Assert.AreEqual(-128y, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.sbyte Decimal.MinValue |> ignore) + + [] + let single() = + // int + let result = Operators.float32 10 + Assert.AreEqual(10f, result) + + // double + let result = Operators.float32 10.0 + Assert.AreEqual(10f, result) + + // string + let result = Operators.float32 "10" + Assert.AreEqual(10f, result) + + + [] + let uint16() = + // int + let result = Operators.uint16 100 + Assert.AreEqual(100us, result) + + // double + let result = Operators.uint16 (100.0:double) + Assert.AreEqual(100us, result) + + // decimal + let result = Operators.uint16 100M + Assert.AreEqual(100us, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint16 Decimal.MinValue |> ignore) + + [] + let uint32() = + // int + let result = Operators.uint32 100 + Assert.AreEqual(100u, result) + + // double + let result = Operators.uint32 (100.0:double) + Assert.AreEqual(100u, result) + + // decimal + let result = Operators.uint32 100M + Assert.AreEqual(100u, result) + + // Overflow + let result = Operators.uint32 Double.MaxValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Double.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Int64.MaxValue + Assert.AreEqual(UInt32.MaxValue, result) + + // Overflow + let result = Operators.uint32 Int64.MinValue + Assert.AreEqual(0u, result) + + // Overflow + let result = UInt32.MaxValue + 5u + Assert.AreEqual(4u, result) + + // both 'u' and 'ul' are valid numeric suffixes for UInt32 + let result = 42u + 42ul + Assert.AreEqual(84u, result) + Assert.AreEqual(84ul, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint32 Decimal.MinValue |> ignore) + + [] + let uint64() = + // int + let result = Operators.uint64 100 + Assert.AreEqual(100UL, result) + + // double + let result = Operators.uint64 100.0 + Assert.AreEqual(100UL, result) + + // decimal + let result = Operators.uint64 100M + Assert.AreEqual(100UL, result) + + // Overflow + let result = Operators.uint64 Double.MaxValue + Assert.AreEqual(0UL, result) + + // Overflow + let result = Operators.uint64 Double.MinValue + Assert.AreEqual(9223372036854775808UL, result) // surprising, but true, 2^63 + 1 + + // Overflow + let result = Operators.uint64 Int64.MinValue + Assert.AreEqual(9223372036854775808UL, result) + + // Overflow + let result = Operators.uint64 SByte.MinValue + Assert.AreEqual(UInt64.MaxValue - 127UL, result) + + // Overflow + let result = UInt64.MaxValue + 5UL + Assert.AreEqual(4UL, result) + + // OverflowException, from decimal is always checked + CheckThrowsOverflowException(fun() -> Operators.uint64 Decimal.MinValue |> ignore) + + [] + let unativeint() = + // int + let result = Operators.unativeint 100 + let x: unativeint = 12un + Assert.AreEqual(100un, result) + + // double + let result = Operators.unativeint 100.0 + Assert.AreEqual(100un, result) + + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.unativeint Double.MaxValue + Assert.AreEqual(0un, result) + + // Overflow (depends on pointer size) + let result = Operators.unativeint Double.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) // surprising, but true, 2^63 + 1 + + // Overflow (depends on pointer size) + let result = Operators.unativeint Int64.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) + + // Overflow (depends on pointer size) + let result = 0un - 1un + if Info.isX86Runtime then + Assert.AreEqual(4294967295un, result) + else + Assert.AreEqual(18446744073709551615un, result) + + open Operators + + [] + let Checkedbyte() = + // int type + let intByte = Operators.Checked.byte 100 + Assert.AreEqual(100uy, intByte) + + // char type + let charByte = Operators.Checked.byte '0' + Assert.AreEqual(48uy, charByte) + + // boundary value + let boundByte = Operators.Checked.byte 255.0 + Assert.AreEqual(255uy, boundByte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 255uy + 1uy |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> 0uy - 1uy |> ignore) + + [] + let Checkedchar() = + + // number + let numberChar = Operators.Checked.char 48 + Assert.AreEqual('0', numberChar) + + // letter + let letterChar = Operators.Checked.char 65 + Assert.AreEqual('A', letterChar) + + // boundary value + let boundchar = Operators.Checked.char 126 + Assert.AreEqual('~', boundchar) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.char (int64 Char.MaxValue + 1L) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> '\uFFFF' + '\u0001' |> ignore) + + + [] + let CheckedInt() = + + // char + let charInt = Operators.Checked.int '0' + Assert.AreEqual(48, charInt) + + // float + let floatInt = Operators.Checked.int 10.0 + Assert.AreEqual(10, floatInt) + + // boundary value + let boundInt = Operators.Checked.int 32767.0 + Assert.AreEqual(32767, boundInt) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + let CheckedInt16() = + + // char + let charInt16 = Operators.Checked.int16 '0' + Assert.AreEqual(48s, charInt16) + + // float + let floatInt16 = Operators.Checked.int16 10.0 + Assert.AreEqual(10s, floatInt16) + + // boundary value + let boundInt16 = Operators.Checked.int16 32767.0 + Assert.AreEqual(32767s, boundInt16) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 32768.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MaxValue + 1s |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int16.MinValue - 1s |> ignore) + + [] + let CheckedInt32() = + + // char + let charInt32 = Operators.Checked.int32 '0' + Assert.AreEqual(48, charInt32) + + // float + let floatInt32 = Operators.Checked.int32 10.0 + Assert.AreEqual(10, floatInt32) + + // boundary value + let boundInt32 = Operators.Checked.int32 2147483647.0 + Assert.AreEqual(2147483647, boundInt32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 2147483648.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int32.MinValue - 1 |> ignore) + + [] + let CheckedInt64() = + + // char + let charInt64 = Operators.Checked.int64 '0' + Assert.AreEqual(48L, charInt64) + + // float + let floatInt64 = Operators.Checked.int64 10.0 + Assert.AreEqual(10L, floatInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 9223372036854775807I + let _ = 9223372036854775807L + Assert.AreEqual(9223372036854775807L, boundInt64) + + // boundary value + let boundInt64 = Operators.Checked.int64 -9223372036854775808I + let _ = -9223372036854775808L + Assert.AreEqual(-9223372036854775808L, boundInt64) + + // overflow exception + CheckThrowsOverflowException(fun() -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MaxValue + 1L |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> Int64.MinValue - 1L |> ignore) + + [] + let CheckedNativeint() = + + // char + let charnativeint = Operators.Checked.nativeint '0' + Assert.AreEqual(48n, charnativeint) + + // float + let floatnativeint = Operators.Checked.nativeint 10.0 + Assert.AreEqual(10n, floatnativeint) + + // boundary value + let boundnativeint = Operators.Checked.nativeint 32767.0 + Assert.AreEqual(32767n, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun() -> + if Info.isX86Runtime then + Operators.Checked.nativeint 2147483648.0 |> ignore + else + Operators.Checked.nativeint 9223372036854775808.0 |> ignore) + + + [] + let Checkedsbyte() = + + // char + let charsbyte = Operators.Checked.sbyte '0' + Assert.AreEqual(48y, charsbyte) + + // float + let floatsbyte = Operators.Checked.sbyte -10.0 + Assert.AreEqual(-10y, floatsbyte) + + // boundary value + let boundsbyte = Operators.Checked.sbyte -127.0 + Assert.AreEqual(-127y, boundsbyte) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte -256 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MaxValue + 1y |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> SByte.MinValue - 1y |> ignore) + + [] + let Checkeduint16() = + + // char + let charuint16 = Operators.Checked.uint16 '0' + Assert.AreEqual(48us, charuint16) + + // float + let floatuint16 = Operators.Checked.uint16 10.0 + Assert.AreEqual(10us, floatuint16) + + // boundary value + let bounduint16 = Operators.Checked.uint16 65535.0 + Assert.AreEqual(65535us, bounduint16) + + CheckThrowsOverflowException(fun() -> Operators.Checked.uint16 65536.0 |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MaxValue + 1us |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt16.MinValue - 1us |> ignore) + + [] + let Checkeduint32() = + + // char + let charuint32 = Operators.Checked.uint32 '0' + Assert.AreEqual(48u, charuint32) + + // float + let floatuint32 = Operators.Checked.uint32 10.0 + Assert.AreEqual(10u, floatuint32) + + // boundary value + let bounduint32 = Operators.Checked.uint32 429496729.0 + Assert.AreEqual(429496729u, bounduint32) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32(float UInt32.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MaxValue + 1u |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt32.MinValue - 1u |> ignore) + + [] + let Checkeduint64() = + + // char + let charuint64 = Operators.Checked.uint64 '0' + Assert.AreEqual(48UL, charuint64) + + // float + let floatuint64 = Operators.Checked.uint64 10.0 + Assert.AreEqual(10UL, floatuint64) + + // boundary value + let bounduint64 = Operators.Checked.uint64 429496729.0 + Assert.AreEqual(429496729UL, bounduint64) + + // overflow exception + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 (float System.UInt64.MaxValue + 1.0) |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MaxValue + 1UL |> ignore) + + // overflow exception + CheckThrowsOverflowException(fun () -> UInt64.MinValue - 1UL |> ignore) + + [] + let Checkedunativeint() = + + // char + let charunativeint = Operators.Checked.unativeint '0' + Assert.AreEqual(48un, charunativeint) + + // float + let floatunativeint = Operators.Checked.unativeint 10.0 + Assert.AreEqual(10un, floatunativeint) + + // boundary value (dependent on pointer size) + if Info.isX86Runtime then + let boundunativeint = Operators.Checked.unativeint 4294967295.0 + Assert.AreEqual(4294967295un, boundunativeint) + else + let boundnativeint = Operators.Checked.unativeint 1.84467440737095505E+19 // 64 bit max value cannot be expressed exactly as double + Assert.AreEqual(18446744073709549568un, boundnativeint) + + // overflow exception (depends on pointer size) + CheckThrowsOverflowException(fun () -> + if Info.isX86Runtime then + Operators.Checked.unativeint (float UInt32.MaxValue + 1.0) |> ignore + else + Operators.Checked.unativeint (float UInt64.MaxValue + 1.0) |> ignore + ) + + type A = A + type B() = + static member op_Equality(_: B, _: B) = false + static member op_Inequality(_: B, _: B) = true + type [] C = + static member op_Equality(_: C, _: C) = true + static member op_Inequality(_: C, _: C) = true + static member op_Explicit(_: A) = C() // Explicit from another type + static member op_Explicit(_: C) = B() // Explicit to another type + static member op_Implicit(_: D) = C() // Duplicated implicit conversion + static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion + and D = { D : int } with + static member op_Implicit(_: A) = { D = 0 } // Implicit from another type + static member op_Implicit(_: D) = B() // Implicit to another type + static member op_Implicit(_: D) = C() // Duplicated implicit conversion + static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion + let [] Equality_ExplicitDynamicTests() = + Assert.False(LanguagePrimitives.EqualityDynamic(B())(B()) : bool) + Assert.True(LanguagePrimitives.InequalityDynamic(B())(B()) : bool) + Assert.True(LanguagePrimitives.EqualityDynamic(C())(C()) : bool) + Assert.True(LanguagePrimitives.InequalityDynamic(C())(C()) : bool) + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) // Explicit from another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : B) // Explicit to another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : D) // Duplicated explicit conversion + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : D) // Implicit from another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : B) // Implicit to another type + Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion + Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : D) // Duplicated explicit conversion \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs index 50f2a157b6e..81429996a05 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/PrimTypes.fs @@ -917,36 +917,3 @@ type NonStructuralComparisonTests() = let y = 32 |> float32 let comparison = compare x y Assert.AreEqual(0, comparison) - -#nowarn "1204" // CompilerMessage: This function is for use by dynamic invocations of F# code and should not be used directly -module DynamicConversionTests = - type A = A - type B() = - static member op_Equality(_: B, _: B) = false - static member op_Inequality(_: B, _: B) = true - type [] C = - static member op_Equality(_: C, _: C) = true - static member op_Inequality(_: C, _: C) = true - static member op_Explicit(_: A) = C() // Explicit from another type - static member op_Explicit(_: C) = B() // Explicit to another type - static member op_Implicit(_: D) = C() // Duplicated implicit conversion - static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion - and D = { D : int } with - static member op_Implicit(_: A) = { D = 0 } // Implicit from another type - static member op_Implicit(_: D) = B() // Implicit to another type - static member op_Implicit(_: D) = C() // Duplicated implicit conversion - static member op_Explicit(_: C) = { D = 0 } // Duplicated explicit conversion - let [] ExplicitDynamicTests() = - Assert.False(LanguagePrimitives.EqualityDynamic(B())(B()) : bool) - Assert.True(LanguagePrimitives.InequalityDynamic(B())(B()) : bool) - Assert.True(LanguagePrimitives.EqualityDynamic(C())(C()) : bool) - Assert.True(LanguagePrimitives.InequalityDynamic(C())(C()) : bool) - Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) - Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : C) // Explicit from another type - Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : B) // Explicit to another type - Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion - Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : D) // Duplicated explicit conversion - Assert.NotNull(LanguagePrimitives.ExplicitDynamic(A) : D) // Implicit from another type - Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : B) // Implicit to another type - Assert.NotNull(LanguagePrimitives.ExplicitDynamic({ D = 0 }) : C) // Duplicated implicit conversion - Assert.NotNull(LanguagePrimitives.ExplicitDynamic(C()) : D) // Duplicated explicit conversion \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.fs index 6ef1b853317..2be2d5bede8 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.fs @@ -1462,6 +1462,7 @@ Microsoft.FSharp.Core.LanguagePrimitives: TResult AdditionDynamic[T1,T2,TResult] Microsoft.FSharp.Core.LanguagePrimitives: TResult BitwiseAndDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult BitwiseOrDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedAdditionDynamic[T1,T2,TResult](T1, T2) +Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedExplicitDynamic[T,TResult](T) Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedMultiplyDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedSubtractionDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult CheckedUnaryNegationDynamic[T,TResult](T) From 60bb94a7d5dde047c59cecd9fca5e0d729d03331 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Mon, 16 Aug 2021 23:42:31 +0800 Subject: [PATCH 72/78] Address comments --- src/fsharp/FSharp.Core/Linq.fs | 55 +++-- src/fsharp/FSharp.Core/array.fs | 11 - src/fsharp/FSharp.Core/array.fsi | 20 -- src/fsharp/FSharp.Core/prim-types.fs | 40 ++-- src/fsharp/TcGlobals.fs | 2 +- .../FSharp.Core/OperatorsModule1.fs | 83 +++++-- .../FSharp.Core/OperatorsModule2.fs | 119 +++++++++- .../FSharp.Core/OperatorsModuleChecked.fs | 32 ++- .../FSharp.Core/OperatorsModuleDynamic.fs | 223 +++++++++++++++--- 9 files changed, 453 insertions(+), 132 deletions(-) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index a6c5cf4785b..466c3c4175f 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -93,10 +93,12 @@ module LeafExpressionConverter = | TypeCode.UInt32 | TypeCode.UInt64 -> true | _ -> false + // https://github.com/dotnet/runtime/blob/fa779e8cb2b5868a0ac2fd4215f39ffb91f0dab0/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L2226 /// Can LINQ Expressions' BinaryExpression's (Left/Right)Shift construct a SimpleBinaryExpression from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsSimpleShift left right = isLinqExpressionsInteger left && getNonNullableType right = typeof + // https://github.com/dotnet/runtime/blob/cf7e7a46f8a4a6225a8f1e059a846ccdebf0454c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L110 /// Can LINQ Expressions' (UnaryExpression/BinaryExpression)'s arithmetic operations construct a (SimpleBinaryExpression/UnaryExpression) from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsArithmeticType typ = @@ -112,6 +114,7 @@ module LeafExpressionConverter = | TypeCode.UInt32 | TypeCode.UInt64 -> true | _ -> false + // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L132 /// Can LINQ Expressions' UnaryExpression.(Checked)Negate construct a UnaryExpression from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsArithmeticTypeButNotUnsignedInt typ = @@ -123,6 +126,7 @@ module LeafExpressionConverter = | TypeCode.UInt32 | TypeCode.UInt64 -> false | _ -> true + // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L149 /// Can LINQ Expressions' (UnaryExpression.Not/BinaryExpression.Binary(And/Or/ExclusiveOr)) construct a (UnaryExpression/SimpleBinaryExpression) from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsIntegerOrBool typ = @@ -139,6 +143,7 @@ module LeafExpressionConverter = | TypeCode.SByte | TypeCode.Byte -> true | _ -> false + // https://github.com/dotnet/runtime/blob/7bd472498e690e9421df86d5a9d728faa939742c/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L47 /// Can LINQ Expressions' BinaryExpression's comparison operations construct a (SimpleBinaryExpression/LogicalBinaryExpression) from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsNumeric typ = @@ -157,16 +162,20 @@ module LeafExpressionConverter = | TypeCode.UInt32 | TypeCode.UInt64 -> true | _ -> false + // https://github.com/dotnet/runtime/blob/afaf666eff08435123eb649ac138419f4c9b9344/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1047 /// Can LINQ Expressions' BinaryExpression's equality operations provide built-in structural equality from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsStructurallyEquatable typ = isLinqExpressionsNumeric typ || typ = typeof || getNonNullableType(typ).IsEnum + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/BinaryExpression.cs#L1221 /// Can LINQ Expressions' BinaryExpression's comparison operations provide built-in comparison from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsComparable = isLinqExpressionsNumeric + /// Can LINQ Expressions' BinaryExpression's equality operations provide built-in equality from the type in question? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsEquatable typ = isLinqExpressionsStructurallyEquatable typ || typ = typeof + /// Can LINQ Expressions' BinaryExpression's conversion operations provide built-in conversion from source to dest? Otherwise, use the F# operator as the user-defined method. let isLinqExpressionsConvertible source dest = // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/UnaryExpression.cs#L757 @@ -199,6 +208,8 @@ module LeafExpressionConverter = && (getNonNullableType dest <> typeof || source.IsEnum && source.GetEnumUnderlyingType() = typeof) || + // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L458 + // IsLegalExplicitVariantDelegateConversion // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L260 // HasReferenceConversionTo let rec hasReferenceConversionTo source dest = @@ -214,28 +225,19 @@ module LeafExpressionConverter = // Interface conversion || source.IsInterface || dest.IsInterface + // The following part shouldn't be needed for our usage of isLinqExpressionsConvertible here because we only use this for potentially nullable built-in numeric types +(* // Variant delegate conversion - || // https://github.com/dotnet/runtime/blob/4c92aef2b08f9c4374c520e7e664a44f1ad8ce56/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L458 - // IsLegalExplicitVariantDelegateConversion - let isDelegate (t: Type) = t.IsSubclassOf typeof - isDelegate source && isDelegate dest && source.IsGenericType && dest.IsGenericType - && - let genericDelegate = source.GetGenericTypeDefinition() - dest.GetGenericTypeDefinition() = genericDelegate - && - (source.GetGenericArguments(), dest.GetGenericArguments(), genericDelegate.GetGenericArguments()) - |||> Array.forall3 (fun sourceArgument destArgument genericParameter -> - // If the arguments are identical then this one is automatically good, so skip it. - sourceArgument.IsEquivalentTo destArgument - || - match genericParameter.GenericParameterAttributes &&& GenericParameterAttributes.VarianceMask with - | GenericParameterAttributes.None -> false - | GenericParameterAttributes.Covariant -> hasReferenceConversionTo sourceArgument destArgument - | GenericParameterAttributes.Contravariant -> not (sourceArgument.IsValueType || destArgument.IsValueType) - | x -> Printf.failwithf "Unexpected GenericParameterAttributes variance: %O" x - ) - // TODO: Is expanding this worth it? - // || (source.IsArray || dest.IsArray) && StrictHasReferenceConversionTo(source, dest, true) + if (IsLegalExplicitVariantDelegateConversion(source, dest)) + { + return true; + } + + // Object conversion handled by assignable above. + Debug.Assert(source != typeof(object) && dest != typeof(object)); + + return (source.IsArray || dest.IsArray) && StrictHasReferenceConversionTo(source, dest, true); +*) hasReferenceConversionTo source dest let SpecificCallToMethodInfo (minfo: System.Reflection.MethodInfo) = let isg1 = minfo.IsGenericMethod @@ -794,6 +796,7 @@ module LeafExpressionConverter = and failConvert inp = raise (new NotSupportedException(Printf.sprintf "Could not convert the following F# Quotation to a LINQ Expression Tree\n--------\n%A\n-------------\n" inp)) + /// Translate a unary operator and transUnaryOp linqExpressionsCondition inp env x (exprErasedConstructor: _ * _ -> _) fallback = let e = ConvExprToLinqInContext env x if linqExpressionsCondition e.Type then @@ -802,6 +805,8 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e, method.MakeGenericMethod [| getNonNullableType x.Type; getNonNullableType inp.Type |]) |> asExpr + + /// Translate a shift operator and transShiftOp inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = let e1 = ConvExprToLinqInContext env x1 let e2 = ConvExprToLinqInContext env x2 @@ -813,6 +818,8 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e1, e2, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) |> asExpr + + /// Translate a non-shift binary operator that does not return a boolean and transBinOp linqExpressionsCondition inp env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ -> _) fallback = let e1 = ConvExprToLinqInContext env x1 let e2 = ConvExprToLinqInContext env x2 @@ -824,7 +831,9 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e1, e2, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) |> asExpr + // The F# boolean structural equality / comparison operators do not take witnesses and the referenced methods are callable directly + /// Translate a non-shift binary operator without witnesses that does not return a boolean and transBoolOpNoWitness linqExpressionsCondition env addConvertLeft x1 x2 addConvertRight (exprErasedConstructor: _ * _ * _ * _ -> _) method = let e1 = ConvExprToLinqInContext env x1 let e2 = ConvExprToLinqInContext env x2 @@ -836,7 +845,9 @@ module LeafExpressionConverter = else exprErasedConstructor(e1, e2, false, method) |> asExpr + // But the static boolean operators do take witnesses! + /// Translate a non-shift binary operator that returns a boolean and transBoolOp linqExpressionsCondition inp env x1 x2 (exprErasedConstructor: _ * _ * _ * _ -> _) fallback = let e1 = ConvExprToLinqInContext env x1 let e2 = ConvExprToLinqInContext env x2 @@ -847,6 +858,8 @@ module LeafExpressionConverter = let method = Reflection.MethodInfo.GetMethodFromHandle fallback :?> Reflection.MethodInfo exprErasedConstructor(e1, e2, false, method.MakeGenericMethod [| getNonNullableType x1.Type; getNonNullableType x2.Type; getNonNullableType inp.Type |]) |> asExpr + + /// Translate a conversion operator and transConv (inp: Expr) env isChecked x = let e = ConvExprToLinqInContext env x let exprErasedConstructor: _ * _ * _ -> _ = if isChecked then Expression.ConvertChecked else Expression.Convert diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs index 5ae6f682259..407ac4aff78 100644 --- a/src/fsharp/FSharp.Core/array.fs +++ b/src/fsharp/FSharp.Core/array.fs @@ -404,17 +404,6 @@ namespace Microsoft.FSharp.Collections if len1 <> array2.Length then invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length let rec loop i = i >= len1 || (f.Invoke(array1.[i], array2.[i]) && loop (i+1)) loop 0 - - [] - let internal forall3 predicate (array1: _[]) (array2: _[]) (array3: _[]) = - if isNull array1 then nullArg (nameof array1) - if isNull array2 then nullArg (nameof array2) - if isNull array3 then nullArg (nameof array3) - let f = OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt(predicate) - let len1 = array1.Length - if len1 <> array2.Length || len1 <> array3.Length then invalidArg3ArraysDifferent "array1" "array2" "array3" array1.Length array2.Length array3.Length - let rec loop i = i >= len1 || (f.Invoke(array1.[i], array2.[i], array3.[i]) && loop (i+1)) - loop 0 let inline groupByImpl (comparer: IEqualityComparer<'SafeKey>) (keyf: 'T->'SafeKey) (getKey: 'SafeKey->'Key) (array: 'T[]) = let length = array.Length diff --git a/src/fsharp/FSharp.Core/array.fsi b/src/fsharp/FSharp.Core/array.fsi index d5eb3765208..e14b973b8b5 100644 --- a/src/fsharp/FSharp.Core/array.fsi +++ b/src/fsharp/FSharp.Core/array.fsi @@ -459,26 +459,6 @@ namespace Microsoft.FSharp.Collections [] val forall2: predicate:('T1 -> 'T2 -> bool) -> array1:'T1[] -> array2:'T2[] -> bool - /// Tests if all corresponding elements of three arrays satisfy the given predicate pairwise. - /// - /// The predicate is applied to matching elements in the three collections up to the lesser of the - /// three lengths of the collections. If any application returns false then the overall result is - /// false and no further elements are tested. Otherwise, if one collection is longer - /// than the others then the ArgumentException exception is raised. - /// Otherwise, true is returned. - /// - /// The function to test the input elements. - /// The first input array. - /// The second input array. - /// The third input array. - /// - /// Thrown when any of the input arrays is null. - /// Thrown when the input arrays differ in length. - /// - /// True if all of the array elements satisfy the predicate. - [] - val internal forall3: predicate:('T1 -> 'T2 -> 'T3 -> bool) -> array1:'T1[] -> array2:'T2[] -> array3:'T3[] -> bool - /// Applies a function to each element of the collection, threading an accumulator argument /// through the computation. If the input function is f and the elements are i0...iN then computes /// f (... (f s i0)...) iN diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 2d875c72e59..16d87f5d240 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2511,7 +2511,6 @@ namespace Microsoft.FSharp.Core // this condition is used whenever ^T is resolved to a nominal type when ^T : ^T = (^T : (static member Zero : ^T) ()) - let inline GenericOne< ^T when ^T : (static member One : ^T) > : ^T = GenericOneDynamic<(^T)>() when ^T : int32 = 1 @@ -2534,11 +2533,13 @@ namespace Microsoft.FSharp.Core when ^T : ^T = (^T : (static member One : ^T) ()) type System.Type with - + /// Gets a single static non-conversion operator or method by types member inline this.GetSingleStaticMethodByTypes(name: string, parameterTypes: Type[]) = let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic this.GetMethod(name, staticBindingFlags, null, parameterTypes, null ) + // Logic based on https://github.com/dotnet/runtime/blob/f66b142980b2b0df738158457458e003944dc7f6/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L662 + /// Gets a single static conversion operator by types member inline this.GetSingleStaticConversionOperatorByTypes(fromType : Type, toType : Type) = let staticBindingFlags = (# "" 0b111000 : BindingFlags #) // BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic let mutable ret = null @@ -2547,6 +2548,7 @@ namespace Microsoft.FSharp.Core (let p = mi.GetParameters() in p.Length = 1 && (get p 0).ParameterType.IsEquivalentTo fromType) && mi.ReturnType.IsEquivalentTo toType then ret <- mi ret + let UnaryDynamicImpl nm : ('T -> 'U) = let aty = typeof<'T> let minfo = aty.GetSingleStaticMethodByTypes(nm, [| aty |]) @@ -2904,7 +2906,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u2" (convPrim<_,unativeint> value) : uint16 #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float> value) : uint16 #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u2" (convPrim<_,float32> value) : uint16 #) - elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u2" (convPrim<_,char> value) : uint16 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "" (convPrim<_,char> value) : uint16 #) elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt16 (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, int16> then @@ -2945,7 +2947,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int16> value) : int32 #) elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint16> value) : int32 #) elif typeeq<'T, int32> then convPrim<_,'U> value - elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint32> value) : int32 #) + elif typeeq<'T, uint32> then convPrim<_,'U> (# "" (convPrim<_,uint32> value) : int32 #) elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.i4" (convPrim<_,int64> value) : int32 #) elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.i4" (convPrim<_,uint64> value) : int32 #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i4" (convPrim<_,nativeint> value) : int32 #) @@ -2982,8 +2984,8 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, uint64> then convPrim<_,'U> (# "" (convPrim<_,uint64> value) : int64 #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.i8" (convPrim<_,nativeint> value) : int64 #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.u8" (convPrim<_,unativeint> value) : int64 #) - elif typeeq<'T, float> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float> value) : int64 #) - elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.u8" (convPrim<_,float32> value) : int64 #) + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.i8" (convPrim<_,float> value) : int64 #) + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.i8" (convPrim<_,float32> value) : int64 #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.u8" (convPrim<_,char> value) : int64 #) elif typeeq<'T, string> then convPrim<_,'U> (ParseInt64 (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value @@ -2999,7 +3001,8 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r4" (convPrim<_,nativeint> value) : float32 #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,unativeint> value) : float32 #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float> value) : float32 #) - elif typeeq<'T, float32> then convPrim<_,'U> value + // 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. + elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r4" (convPrim<_,float32> value) : float32 #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r4" (convPrim<_,char> value) : float32 #) elif typeeq<'T, string> then convPrim<_,'U> (ParseSingle (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value @@ -3014,7 +3017,8 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, uint64> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,uint64> value) : float #) elif typeeq<'T, nativeint> then convPrim<_,'U> (# "conv.r8" (convPrim<_,nativeint> value) : float #) elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,unativeint> value) : float #) - elif typeeq<'T, float> then convPrim<_,'U> 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. + elif typeeq<'T, float> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float> value) : float #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.r8" (convPrim<_,float32> value) : float #) elif typeeq<'T, char> then convPrim<_,'U> (# "conv.r.un conv.r8" (convPrim<_,char> value) : float #) elif typeeq<'T, decimal> then convPrim<_,'U> (Convert.ToDouble(convPrim<_,decimal> value)) @@ -4468,7 +4472,7 @@ namespace Microsoft.FSharp.Core when ^T : uint16 = (# "conv.u1" value : byte #) when ^T : char = (# "conv.u1" value : byte #) when ^T : unativeint = (# "conv.u1" value : byte #) - when ^T : byte = (# "conv.u1" value : byte #) + when ^T : byte = (# "" 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)) @@ -4484,7 +4488,7 @@ namespace Microsoft.FSharp.Core when ^T : int32 = (# "conv.i1" value : sbyte #) when ^T : int16 = (# "conv.i1" value : sbyte #) when ^T : nativeint = (# "conv.i1" value : sbyte #) - when ^T : sbyte = (# "conv.i1" value : sbyte #) + when ^T : sbyte = (# "" value : sbyte #) when ^T : uint64 = (# "conv.i1" value : sbyte #) when ^T : uint32 = (# "conv.i1" value : sbyte #) when ^T : uint16 = (# "conv.i1" value : sbyte #) @@ -4509,8 +4513,8 @@ namespace Microsoft.FSharp.Core when ^T : sbyte = (# "conv.u2" value : uint16 #) when ^T : uint64 = (# "conv.u2" value : uint16 #) when ^T : uint32 = (# "conv.u2" value : uint16 #) - when ^T : uint16 = (# "conv.u2" value : uint16 #) - when ^T : char = (# "conv.u2" value : uint16 #) + when ^T : uint16 = (# "" value : uint16 #) + when ^T : char = (# "" 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, @@ -4526,7 +4530,7 @@ namespace Microsoft.FSharp.Core when ^T : float32 = (# "conv.i2" value : int16 #) when ^T : int64 = (# "conv.i2" value : int16 #) when ^T : int32 = (# "conv.i2" value : int16 #) - when ^T : int16 = (# "conv.i2" value : int16 #) + when ^T : int16 = (# "" value : int16 #) when ^T : nativeint = (# "conv.i2" value : int16 #) when ^T : sbyte = (# "conv.i2" value : int16 #) when ^T : uint64 = (# "conv.i2" value : int16 #) @@ -4554,7 +4558,7 @@ namespace Microsoft.FSharp.Core 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 : uint32 = (# "" value : uint32 #) when ^T : uint16 = (# "conv.u4" value : uint32 #) when ^T : char = (# "conv.u4" value : uint32 #) when ^T : unativeint = (# "conv.u4" value : uint32 #) @@ -4638,7 +4642,7 @@ namespace Microsoft.FSharp.Core when ^T : string = ParseInt64 (castToString value) when ^T : float = (# "conv.i8" value : int64 #) when ^T : float32 = (# "conv.i8" value : int64 #) - when ^T : int64 = (# "conv.i8" value : int64 #) + when ^T : int64 = (# "" value : int64 #) when ^T : int32 = (# "conv.i8" value : int64 #) when ^T : int16 = (# "conv.i8" value : int64 #) when ^T : nativeint = (# "conv.i8" value : int64 #) @@ -4753,7 +4757,7 @@ namespace Microsoft.FSharp.Core 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 : nativeint = (# "" 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). @@ -4839,8 +4843,8 @@ namespace Microsoft.FSharp.Core when ^T : sbyte = (# "conv.u2" value : char #) when ^T : uint64 = (# "conv.u2" value : char #) when ^T : uint32 = (# "conv.u2" value : char #) - when ^T : uint16 = (# "conv.u2" value : char #) - when ^T : char = (# "conv.u2" value : char #) + when ^T : uint16 = (# "" value : char #) + when ^T : char = (# "" value : char #) when ^T : unativeint = (# "conv.u2" value : char #) when ^T : byte = (# "conv.u2" value : char #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> char) (value)) diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index efe5a934635..1f8a39bfca1 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -1610,7 +1610,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d [ arg0Ty; arg1Ty ], Some retTy -> [vara; varb; varc], [ varaTy; varbTy ], varcTy, [ arg0Ty; arg1Ty; retTy ] - | ("UnaryNegationDynamic" | "CheckedUnaryNegationDynamic" | "LogicalNotDynamic" | "ExplicitDynamic"), + | ("UnaryNegationDynamic" | "CheckedUnaryNegationDynamic" | "LogicalNotDynamic" | "ExplicitDynamic" | "CheckedExplicitDynamic"), [ arg0Ty ], Some retTy -> [vara; varb ], [ varaTy ], varbTy, [ arg0Ty; retTy ] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs index 66101cf80f7..a7672d9925f 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule1.fs @@ -246,10 +246,10 @@ type OperatorsModule1() = Assert.AreEqual(1, intbox) // string value - let stringlbox = Operators.box "string" - Assert.AreEqual("string", stringlbox) + let stringbox = Operators.box "string" + Assert.AreEqual("string", stringbox) - // null value + // null value let nullbox = Operators.box null CheckThrowsNullRefException(fun () -> nullbox.ToString() |> ignore) @@ -275,6 +275,14 @@ type OperatorsModule1() = let result = Operators.byte Int64.MinValue Assert.AreEqual(0uy, result) + // Overflow + let result = Operators.byte Single.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Single.MaxValue + Assert.AreEqual(0uy, result) + // Overflow let result = Operators.byte Double.MinValue Assert.AreEqual(0uy, result) @@ -292,7 +300,7 @@ type OperatorsModule1() = Assert.AreEqual(4uy, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.byte Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.byte Decimal.MinValue |> ignore) [] member _.ceil() = @@ -301,13 +309,21 @@ type OperatorsModule1() = Assert.AreEqual(1.0, minceil) // normal value - let normalceil = Operators.ceil 100.0 - Assert.AreEqual(100.0, normalceil) + let normalceil = Operators.ceil 100.1 + Assert.AreEqual(101.0, normalceil) // max value let maxceil = Operators.ceil 1.7E+308 Assert.AreEqual(1.7E+308, maxceil) + // float32 value + let float32ceil = Operators.ceil 100.1f + Assert.AreEqual(101f, float32ceil) + + // decimal value + let decimalceil = Operators.ceil 100.1m + Assert.AreEqual(101m, decimalceil) + [] member _.char() = // int type @@ -324,6 +340,13 @@ type OperatorsModule1() = Assert.AreEqual('0', Operators.char 48f) Assert.AreEqual('0', Operators.char 48.) Assert.AreEqual('0', Operators.char 48m) + + // Overflow + Assert.AreEqual('\000', Operators.char Single.MinValue) + Assert.AreEqual('\000', Operators.char Double.MinValue) + Assert.AreEqual('\000', Operators.char Single.MaxValue) + Assert.AreEqual('\000', Operators.char Double.MaxValue) + CheckThrowsOverflowException(fun () -> Operators.char Decimal.MinValue |> ignore) // string type let stringchar = Operators.char " " @@ -377,16 +400,24 @@ type OperatorsModule1() = member _.decimal () = // int value - let mindecimal = Operators.decimal (1) - Assert.AreEqual(1M, mindecimal) + let intdecimal = Operators.decimal (1) + Assert.AreEqual(1M, intdecimal) + + // nativeint value + let nativeintdecimal = Operators.decimal 1n + Assert.AreEqual(1M, nativeintdecimal) + + // unativeint value + let unativeintdecimal = Operators.decimal 1un + Assert.AreEqual(1M, unativeintdecimal) // char value - let mindecimal = Operators.decimal '\001' - Assert.AreEqual(1M, mindecimal) + let chardecimal = Operators.decimal '\001' + Assert.AreEqual(1M, chardecimal) - // float value - let maxdecimal = Operators.decimal (1.0) - Assert.AreEqual(1M, maxdecimal) + // float value + let floatdecimal = Operators.decimal (1.0) + Assert.AreEqual(1M, floatdecimal) [] member _.decr() = @@ -431,6 +462,10 @@ type OperatorsModule1() = // char type let chardouble = Operators.float '0' Assert.AreEqual(48.0, chardouble) + + // decimal type + let decimaldouble = Operators.float 100m + Assert.AreEqual(100.0, decimaldouble) [] member _.enum() = @@ -439,7 +474,7 @@ type OperatorsModule1() = let intenum = Operators.enum intarg Assert.AreEqual(System.ConsoleColor.Black, intenum) - // big number + // big number let bigarg : int32 = 15 let charenum = Operators.enum bigarg Assert.AreEqual(System.ConsoleColor.White, charenum) @@ -503,6 +538,10 @@ type OperatorsModule1() = let charfloat = Operators.float '0' Assert.AreEqual((float)48, charfloat) + // decimal type + let intfloat = Operators.float 100m + Assert.AreEqual((float)100, intfloat) + [] member _.float32() = // int type @@ -512,16 +551,24 @@ type OperatorsModule1() = // char type let charfloat32 = Operators.float32 '0' Assert.AreEqual((float32)48, charfloat32) + + // decimal type + let intfloat32 = Operators.float32 100m + Assert.AreEqual((float32)100, intfloat32) [] member _.floor() = // float type - let intfloor = Operators.floor 100.9 - Assert.AreEqual(100.0, intfloor) + let floatfloor = Operators.floor 100.9 + Assert.AreEqual(100.0, floatfloor) // float32 type - let charfloor = Operators.floor ((float32)100.9) - Assert.AreEqual(100.0f, charfloor) + let float32floor = Operators.floor 100.9f + Assert.AreEqual(100.0f, float32floor) + + // decimal type + let decimalfloor = Operators.floor 100.9m + Assert.AreEqual(100m, decimalfloor) [] member _.fst() = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index 5e30b9aada9..1a281fd465a 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -50,6 +50,14 @@ type OperatorsModule2() = let result = Operators.int 0 Assert.AreEqual(0, result) + // Overflow. + let result = Operators.int Single.MaxValue + Assert.AreEqual(0, result) + + // Overflow + let result = Operators.int Single.MinValue + Assert.AreEqual(0, result) + // Overflow let result = Operators.int Double.MaxValue Assert.AreEqual(Int32.MinValue, result) @@ -71,7 +79,7 @@ type OperatorsModule2() = Assert.AreEqual(Int32.MinValue, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int Decimal.MinValue |> ignore) [] member _.int16() = @@ -95,6 +103,14 @@ type OperatorsModule2() = let result = Operators.int16 "10" Assert.AreEqual(10s, result) + // Overflow. + let result = Operators.int16 Single.MaxValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Operators.int16 Single.MinValue + Assert.AreEqual(0s, result) + // Overflow let result = Operators.int16 Double.MaxValue Assert.AreEqual(0s, result) @@ -115,7 +131,7 @@ type OperatorsModule2() = Assert.AreEqual(Int16.MinValue, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int16 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int16 Decimal.MinValue |> ignore) [] member _.int32() = @@ -139,6 +155,14 @@ type OperatorsModule2() = let result = Operators.int32 "10" Assert.AreEqual(10, result) + // Overflow. + let result = Operators.int32 Single.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Single.MinValue + Assert.AreEqual(Int32.MinValue, result) + // Overflow let result = Operators.int32 Double.MaxValue Assert.AreEqual(Int32.MinValue, result) @@ -160,7 +184,7 @@ type OperatorsModule2() = Assert.AreEqual(Int32.MinValue + 4, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int32 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int32 Decimal.MinValue |> ignore) [] member _.int64() = @@ -184,6 +208,14 @@ type OperatorsModule2() = let result = Operators.int64 "10" Assert.AreEqual(10L, result) + // Overflow. + let result = Operators.int64 Single.MaxValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 Single.MinValue + Assert.AreEqual(Int64.MinValue, result) + // Overflow. let result = Operators.int64 Double.MaxValue Assert.AreEqual(Int64.MinValue, result) @@ -201,11 +233,11 @@ type OperatorsModule2() = Assert.AreEqual(9223372036854775807L, Int64.MaxValue) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int64 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int64 Decimal.MinValue |> ignore) [] member _.invalidArg() = - CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore ) + CheckThrowsArgumentException(fun () -> Operators.invalidArg "A" "B" |>ignore ) [] @@ -327,6 +359,22 @@ type OperatorsModule2() = let result = Operators.nativeint 0 Assert.AreEqual(0n, result) + // Overflow Single.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.nativeint Single.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Single.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes let result = Operators.nativeint Double.MaxValue if Info.isX86Runtime then @@ -395,7 +443,7 @@ type OperatorsModule2() = [] member _.nullArg() = - CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore) + CheckThrowsArgumentNullException(fun () -> Operators.nullArg "A" |> ignore) [] @@ -428,11 +476,11 @@ type OperatorsModule2() = let result = Operators.pown System.Double.MaxValue System.Int32.MaxValue Assert.AreEqual(Double.PositiveInfinity, result) - CheckThrowsOverflowException(fun() -> Operators.pown System.Int32.MaxValue System.Int32.MaxValue |>ignore) + CheckThrowsOverflowException(fun () -> Operators.pown System.Int32.MaxValue System.Int32.MaxValue |>ignore) [] member _.raise() = - CheckThrowsArgumentException(fun()-> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore) + CheckThrowsArgumentException(fun () -> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore) [] @@ -558,7 +606,7 @@ type OperatorsModule2() = Assert.AreEqual(-128y, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.sbyte Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.sbyte Decimal.MinValue |> ignore) [] member _.sign() = @@ -693,6 +741,10 @@ type OperatorsModule2() = let result = Operators.sizeof Assert.AreEqual(8, result) + // custom struct + let result = Operators.sizeof + Assert.AreEqual(12, result) + // reference type should have the same size as the IntPtr let result = Operators.sizeof Assert.AreEqual(IntPtr.Size, result) @@ -898,9 +950,25 @@ type OperatorsModule2() = // decimal let result = Operators.uint16 100M Assert.AreEqual(100us, result) + + // Overflow + let result = Operators.uint16 Single.MaxValue + Assert.AreEqual(0us, result) + + // Overflow + let result = Operators.uint16 Single.MinValue + Assert.AreEqual(0us, result) + + // Overflow + let result = Operators.uint16 Double.MaxValue + Assert.AreEqual(0us, result) + + // Overflow + let result = Operators.uint16 Double.MinValue + Assert.AreEqual(0us, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.uint16 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.uint16 Decimal.MinValue |> ignore) [] member _.uint32() = @@ -916,6 +984,14 @@ type OperatorsModule2() = let result = Operators.uint32 100M Assert.AreEqual(100u, result) + // Overflow + let result = Operators.uint32 Single.MaxValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Single.MinValue + Assert.AreEqual(0u, result) + // Overflow let result = Operators.uint32 Double.MaxValue Assert.AreEqual(0u, result) @@ -942,7 +1018,7 @@ type OperatorsModule2() = Assert.AreEqual(84ul, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.uint32 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.uint32 Decimal.MinValue |> ignore) [] member _.uint64() = @@ -958,6 +1034,14 @@ type OperatorsModule2() = let result = Operators.uint64 100M Assert.AreEqual(100UL, result) + // Overflow + let result = Operators.uint64 Single.MaxValue + Assert.AreEqual(0UL, result) + + // Overflow + let result = Operators.uint64 Single.MinValue + Assert.AreEqual(9223372036854775808UL, result) // surprising, but true, 2^63 + 1 + // Overflow let result = Operators.uint64 Double.MaxValue Assert.AreEqual(0UL, result) @@ -979,7 +1063,7 @@ type OperatorsModule2() = Assert.AreEqual(4UL, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.uint64 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.uint64 Decimal.MinValue |> ignore) [] member _.unativeint() = @@ -992,6 +1076,17 @@ type OperatorsModule2() = let result = Operators.unativeint 100.0 Assert.AreEqual(100un, result) + // Overflow Single.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.unativeint Single.MaxValue + Assert.AreEqual(0un, result) + + // Overflow (depends on pointer size) + let result = Operators.unativeint Single.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) // surprising, but true, 2^63 + 1 + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes let result = Operators.unativeint Double.MaxValue Assert.AreEqual(0un, result) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs index 482335e8b13..54da228aca6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleChecked.fs @@ -27,6 +27,8 @@ type OperatorsModuleChecked() = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256f |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256. |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> 255uy + 1uy |> ignore) @@ -51,6 +53,8 @@ type OperatorsModuleChecked() = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.char (int64 Char.MaxValue + 1L) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.char Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.char Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> '\uFFFF' + '\u0001' |> ignore) @@ -72,7 +76,9 @@ type OperatorsModuleChecked() = Assert.AreEqual(32767, boundInt) // overflow exception - CheckThrowsOverflowException(fun() -> Operators.Checked.int 2147483648.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int 2147483648.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) @@ -97,6 +103,8 @@ type OperatorsModuleChecked() = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.int16 32768.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int16.MaxValue + 1s |> ignore) @@ -121,6 +129,8 @@ type OperatorsModuleChecked() = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.int32 2147483648.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) @@ -150,7 +160,9 @@ type OperatorsModuleChecked() = Assert.AreEqual(-9223372036854775808L, boundInt64) // overflow exception - CheckThrowsOverflowException(fun() -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int64 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int64 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int64.MaxValue + 1L |> ignore) @@ -179,6 +191,8 @@ type OperatorsModuleChecked() = Operators.Checked.nativeint 2147483648.0 |> ignore else Operators.Checked.nativeint 9223372036854775808.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.nativeint Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.nativeint Double.MaxValue |> ignore) [] @@ -198,6 +212,8 @@ type OperatorsModuleChecked() = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte -256 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> SByte.MaxValue + 1y |> ignore) @@ -220,7 +236,9 @@ type OperatorsModuleChecked() = let bounduint16 = Operators.Checked.uint16 65535.0 Assert.AreEqual(65535us, bounduint16) - CheckThrowsOverflowException(fun() -> Operators.Checked.uint16 65536.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint16 65536.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint16 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint16 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> UInt16.MaxValue + 1us |> ignore) @@ -244,7 +262,9 @@ type OperatorsModuleChecked() = Assert.AreEqual(429496729u, bounduint32) // overflow exception - CheckThrowsOverflowException(fun () -> Operators.Checked.uint32(float UInt32.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32 (float UInt32.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> UInt32.MaxValue + 1u |> ignore) @@ -269,6 +289,8 @@ type OperatorsModuleChecked() = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 (float System.UInt64.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> UInt64.MaxValue + 1UL |> ignore) @@ -302,5 +324,7 @@ type OperatorsModuleChecked() = else Operators.Checked.unativeint (float UInt64.MaxValue + 1.0) |> ignore ) + CheckThrowsOverflowException(fun () -> Operators.Checked.unativeint Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.unativeint Double.MaxValue |> ignore) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs index d741c584131..9af581dca52 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModuleDynamic.fs @@ -5,12 +5,24 @@ namespace FSharp.Core.UnitTests.Operators open System -open FSharp.Core.UnitTests.LibraryTestFx open Xunit -open Microsoft.FSharp.Core.Operators.Checked #nowarn "1204" // CompilerMessage: This function is for use by dynamic invocations of F# code and should not be used directly module OperatorsModuleDynamic = + + /// Check that the lambda throws an exception of the given type. Otherwise + /// calls Assert.Fail() + // Sync implementation with FSharp.Core.UnitTests.LibraryTestFx.CheckThrowsExn + let CheckThrowsExn<'a when 'a :> exn> (f : unit -> unit) = + try + let _ = f () + sprintf "Expected %O exception, got no exception" typeof<'a> |> Assert.Fail + with + | :? 'a -> () + | :? Reflection.TargetInvocationException as r when (r.InnerException :? 'a) -> () + | e -> sprintf "Expected %O or TargetInvocationException containing it, got: %O" typeof<'a> e |> Assert.Fail + let CheckThrowsOverflowException = CheckThrowsExn + module Operators = let byte<'T> = LanguagePrimitives.ExplicitDynamic<'T, byte> let char<'T> = LanguagePrimitives.ExplicitDynamic<'T, char> @@ -18,6 +30,7 @@ module OperatorsModuleDynamic = let decimal<'T> = LanguagePrimitives.ExplicitDynamic<'T, decimal> let float<'T> = LanguagePrimitives.ExplicitDynamic<'T, float> let float32<'T> = LanguagePrimitives.ExplicitDynamic<'T, float32> + let nativeint<'T> = LanguagePrimitives.ExplicitDynamic<'T, nativeint> let int<'T> = LanguagePrimitives.ExplicitDynamic<'T, int> let int8<'T> = LanguagePrimitives.ExplicitDynamic<'T, int8> let int16<'T> = LanguagePrimitives.ExplicitDynamic<'T, int16> @@ -38,6 +51,7 @@ module OperatorsModuleDynamic = let decimal<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, decimal> let float<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, float> let float32<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, float32> + let nativeint<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, nativeint> let int<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int> let int8<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int8> let int16<'T> = LanguagePrimitives.CheckedExplicitDynamic<'T, int16> @@ -74,6 +88,14 @@ module OperatorsModuleDynamic = let result = Operators.byte Int64.MinValue Assert.AreEqual(0uy, result) + // Overflow + let result = Operators.byte Single.MinValue + Assert.AreEqual(0uy, result) + + // Overflow + let result = Operators.byte Single.MaxValue + Assert.AreEqual(0uy, result) + // Overflow let result = Operators.byte Double.MinValue Assert.AreEqual(0uy, result) @@ -91,7 +113,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(4uy, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.byte Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.byte Decimal.MinValue |> ignore) [] let char() = @@ -109,6 +131,13 @@ module OperatorsModuleDynamic = Assert.AreEqual('0', Operators.char 48f) Assert.AreEqual('0', Operators.char 48.) Assert.AreEqual('0', Operators.char 48m) + + // Overflow + Assert.AreEqual('\000', Operators.char Single.MinValue) + Assert.AreEqual('\000', Operators.char Double.MinValue) + Assert.AreEqual('\000', Operators.char Single.MaxValue) + Assert.AreEqual('\000', Operators.char Double.MaxValue) + CheckThrowsOverflowException(fun () -> Operators.char Decimal.MinValue |> ignore) // string type let stringchar = Operators.char " " @@ -119,16 +148,24 @@ module OperatorsModuleDynamic = let decimal () = // int value - let mindecimal = Operators.decimal (1) - Assert.AreEqual(1M, mindecimal) + let intdecimal = Operators.decimal (1) + Assert.AreEqual(1M, intdecimal) + + // nativeint value + let nativeintdecimal = Operators.decimal 1n + Assert.AreEqual(1M, nativeintdecimal) + + // unativeint value + let unativeintdecimal = Operators.decimal 1un + Assert.AreEqual(1M, unativeintdecimal) // char value - let mindecimal = Operators.decimal '\001' - Assert.AreEqual(1M, mindecimal) + let chardecimal = Operators.decimal '\001' + Assert.AreEqual(1M, chardecimal) - // float value - let maxdecimal = Operators.decimal (1.0) - Assert.AreEqual(1M, maxdecimal) + // float value + let floatdecimal = Operators.decimal (1.0) + Assert.AreEqual(1M, floatdecimal) [] let double() = @@ -139,8 +176,11 @@ module OperatorsModuleDynamic = // char type let chardouble = Operators.float '0' Assert.AreEqual(48.0, chardouble) + + // decimal type + let decimaldouble = Operators.float 100m + Assert.AreEqual(100.0, decimaldouble) - [] let float() = // int type @@ -151,6 +191,10 @@ module OperatorsModuleDynamic = let charfloat = Operators.float '0' Assert.AreEqual((float)48, charfloat) + // decimal type + let intfloat = Operators.float 100m + Assert.AreEqual((float)100, intfloat) + [] let float32() = // int type @@ -160,8 +204,11 @@ module OperatorsModuleDynamic = // char type let charfloat32 = Operators.float32 '0' Assert.AreEqual((float32)48, charfloat32) + + // decimal type + let intfloat32 = Operators.float32 100m + Assert.AreEqual((float32)100, intfloat32) - [] let int() = // int @@ -184,6 +231,14 @@ module OperatorsModuleDynamic = let result = Operators.int 0 Assert.AreEqual(0, result) + // Overflow + let result = Operators.int Single.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int Single.MinValue + Assert.AreEqual(Int32.MinValue, result) + // Overflow let result = Operators.int Double.MaxValue Assert.AreEqual(Int32.MinValue, result) @@ -205,7 +260,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(Int32.MinValue, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int Decimal.MinValue |> ignore) [] let int16() = @@ -229,6 +284,14 @@ module OperatorsModuleDynamic = let result = Operators.int16 "10" Assert.AreEqual(10s, result) + // Overflow + let result = Operators.int16 Single.MaxValue + Assert.AreEqual(0s, result) + + // Overflow + let result = Operators.int16 Single.MinValue + Assert.AreEqual(0s, result) + // Overflow let result = Operators.int16 Double.MaxValue Assert.AreEqual(0s, result) @@ -249,7 +312,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(Int16.MinValue, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int16 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int16 Decimal.MinValue |> ignore) [] let int32() = @@ -273,6 +336,14 @@ module OperatorsModuleDynamic = let result = Operators.int32 "10" Assert.AreEqual(10, result) + // Overflow + let result = Operators.int32 Single.MaxValue + Assert.AreEqual(Int32.MinValue, result) + + // Overflow + let result = Operators.int32 Single.MinValue + Assert.AreEqual(Int32.MinValue, result) + // Overflow let result = Operators.int32 Double.MaxValue Assert.AreEqual(Int32.MinValue, result) @@ -294,7 +365,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(Int32.MinValue + 4, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int32 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int32 Decimal.MinValue |> ignore) [] let int64() = @@ -318,6 +389,14 @@ module OperatorsModuleDynamic = let result = Operators.int64 "10" Assert.AreEqual(10L, result) + // Overflow. + let result = Operators.int64 Single.MaxValue + Assert.AreEqual(Int64.MinValue, result) + + // Overflow + let result = Operators.int64 Single.MinValue + Assert.AreEqual(Int64.MinValue, result) + // Overflow. let result = Operators.int64 Double.MaxValue Assert.AreEqual(Int64.MinValue, result) @@ -335,7 +414,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(9223372036854775807L, Int64.MaxValue) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.int64 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.int64 Decimal.MinValue |> ignore) [] @@ -360,6 +439,22 @@ module OperatorsModuleDynamic = let result = Operators.nativeint 0 Assert.AreEqual(0n, result) + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.nativeint Single.MaxValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + + // Overflow (depends on pointer size) + let result = Operators.nativeint Single.MinValue + if Info.isX86Runtime then + Assert.AreEqual(-2147483648n, result) + else + // Cannot use -9223372036854775808, compiler doesn't allow it, see https://github.com/dotnet/fsharp/issues/9524 + Assert.AreEqual(-9223372036854775807n - 1n, result) + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes let result = Operators.nativeint Double.MaxValue if Info.isX86Runtime then @@ -392,7 +487,6 @@ module OperatorsModuleDynamic = let result = nativeint Int64.MaxValue + 5n Assert.AreEqual(-9223372036854775804n, result) - // Overflow (depends on pointer size) let result = Operators.nativeint System.Double.MaxValue if Info.isX86Runtime then @@ -444,6 +538,14 @@ module OperatorsModuleDynamic = let result = Operators.sbyte Int64.MinValue Assert.AreEqual(0y, result) + // Overflow + let result = Operators.sbyte Single.MinValue + Assert.AreEqual(0y, result) + + // Overflow + let result = Operators.sbyte Single.MaxValue + Assert.AreEqual(0y, result) + // Overflow let result = Operators.sbyte Double.MinValue Assert.AreEqual(0y, result) @@ -461,7 +563,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(-128y, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.sbyte Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.sbyte Decimal.MinValue |> ignore) [] let single() = @@ -491,9 +593,25 @@ module OperatorsModuleDynamic = // decimal let result = Operators.uint16 100M Assert.AreEqual(100us, result) + + // Overflow + let result = Operators.uint16 Single.MaxValue + Assert.AreEqual(0us, result) + + // Overflow + let result = Operators.uint16 Single.MinValue + Assert.AreEqual(0us, result) + + // Overflow + let result = Operators.uint16 Double.MaxValue + Assert.AreEqual(0us, result) + + // Overflow + let result = Operators.uint16 Double.MinValue + Assert.AreEqual(0us, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.uint16 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.uint16 Decimal.MinValue |> ignore) [] let uint32() = @@ -509,6 +627,14 @@ module OperatorsModuleDynamic = let result = Operators.uint32 100M Assert.AreEqual(100u, result) + // Overflow + let result = Operators.uint32 Single.MaxValue + Assert.AreEqual(0u, result) + + // Overflow + let result = Operators.uint32 Single.MinValue + Assert.AreEqual(0u, result) + // Overflow let result = Operators.uint32 Double.MaxValue Assert.AreEqual(0u, result) @@ -535,7 +661,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(84ul, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.uint32 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.uint32 Decimal.MinValue |> ignore) [] let uint64() = @@ -551,6 +677,14 @@ module OperatorsModuleDynamic = let result = Operators.uint64 100M Assert.AreEqual(100UL, result) + // Overflow + let result = Operators.uint64 Single.MaxValue + Assert.AreEqual(0UL, result) + + // Overflow + let result = Operators.uint64 Single.MinValue + Assert.AreEqual(9223372036854775808UL, result) // surprising, but true, 2^63 + 1 + // Overflow let result = Operators.uint64 Double.MaxValue Assert.AreEqual(0UL, result) @@ -572,7 +706,7 @@ module OperatorsModuleDynamic = Assert.AreEqual(4UL, result) // OverflowException, from decimal is always checked - CheckThrowsOverflowException(fun() -> Operators.uint64 Decimal.MinValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.uint64 Decimal.MinValue |> ignore) [] let unativeint() = @@ -585,6 +719,17 @@ module OperatorsModuleDynamic = let result = Operators.unativeint 100.0 Assert.AreEqual(100un, result) + // Overflow Single.MaxValue is equal on 32 bits and 64 bits runtimes + let result = Operators.unativeint Single.MaxValue + Assert.AreEqual(0un, result) + + // Overflow (depends on pointer size) + let result = Operators.unativeint Single.MinValue + if Info.isX86Runtime then + Assert.AreEqual(0un, result) + else + Assert.AreEqual(9223372036854775808un, result) // surprising, but true, 2^63 + 1 + // Overflow Double.MaxValue is equal on 32 bits and 64 bits runtimes let result = Operators.unativeint Double.MaxValue Assert.AreEqual(0un, result) @@ -610,7 +755,7 @@ module OperatorsModuleDynamic = else Assert.AreEqual(18446744073709551615un, result) - open Operators + open Operators.Checked [] let Checkedbyte() = @@ -628,6 +773,8 @@ module OperatorsModuleDynamic = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256f |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.byte 256. |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> 255uy + 1uy |> ignore) @@ -652,6 +799,8 @@ module OperatorsModuleDynamic = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.char (int64 Char.MaxValue + 1L) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.char Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.char Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> '\uFFFF' + '\u0001' |> ignore) @@ -673,7 +822,9 @@ module OperatorsModuleDynamic = Assert.AreEqual(32767, boundInt) // overflow exception - CheckThrowsOverflowException(fun() -> Operators.Checked.int 2147483648.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int 2147483648.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) @@ -698,6 +849,8 @@ module OperatorsModuleDynamic = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.int16 32768.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int16 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int16.MaxValue + 1s |> ignore) @@ -722,6 +875,8 @@ module OperatorsModuleDynamic = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.int32 2147483648.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int32 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int32.MaxValue + 1 |> ignore) @@ -751,7 +906,9 @@ module OperatorsModuleDynamic = Assert.AreEqual(-9223372036854775808L, boundInt64) // overflow exception - CheckThrowsOverflowException(fun() -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int64 (float Int64.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int64 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.int64 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> Int64.MaxValue + 1L |> ignore) @@ -775,11 +932,13 @@ module OperatorsModuleDynamic = Assert.AreEqual(32767n, boundnativeint) // overflow exception (depends on pointer size) - CheckThrowsOverflowException(fun() -> + CheckThrowsOverflowException(fun () -> if Info.isX86Runtime then Operators.Checked.nativeint 2147483648.0 |> ignore else Operators.Checked.nativeint 9223372036854775808.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.nativeint Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.nativeint Double.MaxValue |> ignore) [] @@ -799,6 +958,8 @@ module OperatorsModuleDynamic = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte -256 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.sbyte Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> SByte.MaxValue + 1y |> ignore) @@ -821,7 +982,9 @@ module OperatorsModuleDynamic = let bounduint16 = Operators.Checked.uint16 65535.0 Assert.AreEqual(65535us, bounduint16) - CheckThrowsOverflowException(fun() -> Operators.Checked.uint16 65536.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint16 65536.0 |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint16 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint16 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> UInt16.MaxValue + 1us |> ignore) @@ -845,7 +1008,9 @@ module OperatorsModuleDynamic = Assert.AreEqual(429496729u, bounduint32) // overflow exception - CheckThrowsOverflowException(fun () -> Operators.Checked.uint32(float UInt32.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32 (float UInt32.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint32 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> UInt32.MaxValue + 1u |> ignore) @@ -870,6 +1035,8 @@ module OperatorsModuleDynamic = // overflow exception CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 (float System.UInt64.MaxValue + 1.0) |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.uint64 Double.MaxValue |> ignore) // overflow exception CheckThrowsOverflowException(fun () -> UInt64.MaxValue + 1UL |> ignore) @@ -903,6 +1070,8 @@ module OperatorsModuleDynamic = else Operators.Checked.unativeint (float UInt64.MaxValue + 1.0) |> ignore ) + CheckThrowsOverflowException(fun () -> Operators.Checked.unativeint Single.MaxValue |> ignore) + CheckThrowsOverflowException(fun () -> Operators.Checked.unativeint Double.MaxValue |> ignore) type A = A type B() = From ae77615a3d1c777e9d3e3b9563c26e70968a8c01 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 20 Aug 2021 02:25:08 +0800 Subject: [PATCH 73/78] Try to fix tests --- src/fsharp/FSharp.Core/prim-types.fs | 162 +++++++++++++-------------- tests/service/ExprTests.fs | 44 ++++---- 2 files changed, 104 insertions(+), 102 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 16d87f5d240..8036d52e1d4 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3141,7 +3141,7 @@ namespace Microsoft.FSharp.Core elif typeeq<'T, unativeint> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,unativeint> value) : uint16 #) elif typeeq<'T, float> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,float> value) : uint16 #) elif typeeq<'T, float32> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,float32> value) : uint16 #) - elif typeeq<'T, char> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,char> value) : uint16 #) + elif typeeq<'T, char> then convPrim<_,'U> (# "" (convPrim<_,char> value) : uint16 #) elif typeeq<'T, string> then convPrim<_,'U> (ParseUInt16 (convPrim<_,string> value)) else UnaryOpDynamicImplTable.Invoke "op_Explicit" value elif typeeq<'U, int16> then @@ -3295,7 +3295,7 @@ namespace Microsoft.FSharp.Core if typeeq<'T, sbyte> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,sbyte> value) : char #) elif typeeq<'T, byte> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,byte> value) : char #) elif typeeq<'T, int16> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int16> value) : char #) - elif typeeq<'T, uint16> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint16> value) : char #) + elif typeeq<'T, uint16> then convPrim<_,'U> (# "" (convPrim<_,uint16> value) : char #) elif typeeq<'T, int32> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int32> value) : char #) elif typeeq<'T, uint32> then convPrim<_,'U> (# "conv.ovf.u2.un" (convPrim<_,uint32> value) : char #) elif typeeq<'T, int64> then convPrim<_,'U> (# "conv.ovf.u2" (convPrim<_,int64> value) : char #) @@ -5208,19 +5208,19 @@ namespace Microsoft.FSharp.Core let inline byte (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int32 = (# "conv.ovf.u1" value : byte #) - when ^T : int16 = (# "conv.ovf.u1" value : byte #) - when ^T : nativeint = (# "conv.ovf.u1" value : byte #) - when ^T : sbyte = (# "conv.ovf.u1" value : byte #) + when ^T : float = (# "conv.ovf.u1" value : byte #) + when ^T : float32 = (# "conv.ovf.u1" value : byte #) + when ^T : int64 = (# "conv.ovf.u1" value : byte #) + when ^T : int32 = (# "conv.ovf.u1" value : byte #) + when ^T : int16 = (# "conv.ovf.u1" value : byte #) + when ^T : nativeint = (# "conv.ovf.u1" value : byte #) + when ^T : sbyte = (# "conv.ovf.u1" value : byte #) when ^T : uint64 = (# "conv.ovf.u1.un" value : byte #) when ^T : uint32 = (# "conv.ovf.u1.un" value : byte #) when ^T : uint16 = (# "conv.ovf.u1.un" value : byte #) 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 #) + when ^T : byte = (# "" value : byte #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> byte) (value)) [] @@ -5228,19 +5228,19 @@ namespace Microsoft.FSharp.Core let inline sbyte (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.i1" value : sbyte #) - when ^T : int32 = (# "conv.ovf.i1" value : sbyte #) - when ^T : int16 = (# "conv.ovf.i1" value : sbyte #) - when ^T : nativeint = (# "conv.ovf.i1" value : sbyte #) - when ^T : sbyte = (# "conv.ovf.i1" value : sbyte #) + when ^T : float = (# "conv.ovf.i1" value : sbyte #) + when ^T : float32 = (# "conv.ovf.i1" value : sbyte #) + when ^T : int64 = (# "conv.ovf.i1" value : sbyte #) + when ^T : int32 = (# "conv.ovf.i1" value : sbyte #) + when ^T : int16 = (# "conv.ovf.i1" value : sbyte #) + when ^T : nativeint = (# "conv.ovf.i1" value : sbyte #) + when ^T : sbyte = (# "" value : sbyte #) when ^T : uint64 = (# "conv.ovf.i1.un" value : sbyte #) when ^T : uint32 = (# "conv.ovf.i1.un" value : sbyte #) when ^T : uint16 = (# "conv.ovf.i1.un" value : sbyte #) 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 #) + when ^T : byte = (# "conv.ovf.i1.un" value : sbyte #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> sbyte) (value)) [] @@ -5257,8 +5257,8 @@ namespace Microsoft.FSharp.Core when ^T : sbyte = (# "conv.ovf.u2" value : uint16 #) when ^T : uint64 = (# "conv.ovf.u2.un" value : uint16 #) when ^T : uint32 = (# "conv.ovf.u2.un" value : uint16 #) - when ^T : uint16 = (# "conv.ovf.u2.un" value : uint16 #) - when ^T : char = (# "conv.ovf.u2.un" value : uint16 #) + when ^T : uint16 = (# "" value : uint16 #) + when ^T : char = (# "" value : uint16 #) when ^T : unativeint = (# "conv.ovf.u2.un" value : uint16 #) when ^T : byte = (# "conv.ovf.u2.un" value : uint16 #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint16) (value)) @@ -5277,8 +5277,8 @@ namespace Microsoft.FSharp.Core when ^T : sbyte = (# "conv.ovf.u2" value : char #) when ^T : uint64 = (# "conv.ovf.u2.un" value : char #) when ^T : uint32 = (# "conv.ovf.u2.un" value : char #) - when ^T : uint16 = (# "conv.ovf.u2.un" value : char #) - when ^T : char = (# "conv.ovf.u2.un" value : char #) + when ^T : uint16 = (# "" value : char #) + when ^T : char = (# "" value : char #) when ^T : unativeint = (# "conv.ovf.u2.un" value : char #) when ^T : byte = (# "conv.ovf.u2.un" value : char #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> char) (value)) @@ -5288,19 +5288,19 @@ namespace Microsoft.FSharp.Core let inline int16 (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.i2" value : int16 #) - when ^T : int32 = (# "conv.ovf.i2" value : int16 #) - when ^T : int16 = (# "conv.ovf.i2" value : int16 #) - when ^T : nativeint = (# "conv.ovf.i2" value : int16 #) - when ^T : sbyte = (# "conv.ovf.i2" value : int16 #) + when ^T : float = (# "conv.ovf.i2" value : int16 #) + when ^T : float32 = (# "conv.ovf.i2" value : int16 #) + when ^T : int64 = (# "conv.ovf.i2" value : int16 #) + when ^T : int32 = (# "conv.ovf.i2" value : int16 #) + when ^T : int16 = (# "" value : int16 #) + when ^T : nativeint = (# "conv.ovf.i2" value : int16 #) + when ^T : sbyte = (# "conv.ovf.i2" value : int16 #) when ^T : uint64 = (# "conv.ovf.i2.un" value : int16 #) when ^T : uint32 = (# "conv.ovf.i2.un" value : int16 #) when ^T : uint16 = (# "conv.ovf.i2.un" value : int16 #) 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 #) + when ^T : byte = (# "conv.ovf.i2.un" value : int16 #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> int16) (value)) [] @@ -5308,19 +5308,19 @@ namespace Microsoft.FSharp.Core let inline uint32 (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.u4" value : uint32 #) - when ^T : int32 = (# "conv.ovf.u4" value : uint32 #) - when ^T : int16 = (# "conv.ovf.u4" value : uint32 #) - when ^T : nativeint = (# "conv.ovf.u4" value : uint32 #) - when ^T : sbyte = (# "conv.ovf.u4" value : uint32 #) + when ^T : float = (# "conv.ovf.u4" value : uint32 #) + when ^T : float32 = (# "conv.ovf.u4" value : uint32 #) + when ^T : int64 = (# "conv.ovf.u4" value : uint32 #) + when ^T : int32 = (# "conv.ovf.u4" value : uint32 #) + when ^T : int16 = (# "conv.ovf.u4" value : uint32 #) + when ^T : nativeint = (# "conv.ovf.u4" value : uint32 #) + when ^T : sbyte = (# "conv.ovf.u4" value : uint32 #) when ^T : uint64 = (# "conv.ovf.u4.un" value : uint32 #) - when ^T : uint32 = (# "conv.ovf.u4.un" value : uint32 #) + when ^T : uint32 = (# "" value : uint32 #) when ^T : uint16 = (# "conv.ovf.u4.un" value : uint32 #) 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 #) + when ^T : byte = (# "conv.ovf.u4.un" value : uint32 #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint32) (value)) [] @@ -5328,19 +5328,19 @@ namespace Microsoft.FSharp.Core let inline int32 (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.i4" value : int32 #) - when ^T : int32 = (# "conv.ovf.i4" value : int32 #) - when ^T : int16 = (# "conv.ovf.i4" value : int32 #) - when ^T : nativeint = (# "conv.ovf.i4" value : int32 #) - when ^T : sbyte = (# "conv.ovf.i4" value : int32 #) + when ^T : float = (# "conv.ovf.i4" value : int32 #) + when ^T : float32 = (# "conv.ovf.i4" value : int32 #) + when ^T : int64 = (# "conv.ovf.i4" value : int32 #) + when ^T : int32 = (# "" value : int32 #) + when ^T : int16 = (# "conv.ovf.i4" value : int32 #) + when ^T : nativeint = (# "conv.ovf.i4" value : int32 #) + when ^T : sbyte = (# "conv.ovf.i4" value : int32 #) when ^T : uint64 = (# "conv.ovf.i4.un" value : int32 #) when ^T : uint32 = (# "conv.ovf.i4.un" value : int32 #) when ^T : uint16 = (# "conv.ovf.i4.un" value : int32 #) 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 #) + when ^T : byte = (# "conv.ovf.i4.un" value : int32 #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> int32) (value)) [] @@ -5351,19 +5351,19 @@ namespace Microsoft.FSharp.Core let inline uint64 (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.u8" value : uint64 #) - when ^T : int32 = (# "conv.ovf.u8" value : uint64 #) - when ^T : int16 = (# "conv.ovf.u8" value : uint64 #) - when ^T : nativeint = (# "conv.ovf.u8" value : uint64 #) - when ^T : sbyte = (# "conv.ovf.u8" value : uint64 #) - when ^T : uint64 = (# "conv.ovf.u8.un" value : uint64 #) + when ^T : float = (# "conv.ovf.u8" value : uint64 #) + when ^T : float32 = (# "conv.ovf.u8" value : uint64 #) + when ^T : int64 = (# "conv.ovf.u8" value : uint64 #) + when ^T : int32 = (# "conv.ovf.u8" value : uint64 #) + when ^T : int16 = (# "conv.ovf.u8" value : uint64 #) + when ^T : nativeint = (# "conv.ovf.u8" value : uint64 #) + when ^T : sbyte = (# "conv.ovf.u8" value : uint64 #) + when ^T : uint64 = (# "" value : uint64 #) when ^T : uint32 = (# "conv.ovf.u8.un" value : uint64 #) when ^T : uint16 = (# "conv.ovf.u8.un" value : uint64 #) 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 #) + when ^T : byte = (# "conv.ovf.u8.un" value : uint64 #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> uint64) (value)) [] @@ -5371,19 +5371,19 @@ namespace Microsoft.FSharp.Core let inline int64 (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.i8" value : int64 #) - when ^T : int32 = (# "conv.ovf.i8" value : int64 #) - when ^T : int16 = (# "conv.ovf.i8" value : int64 #) - when ^T : nativeint = (# "conv.ovf.i8" value : int64 #) - when ^T : sbyte = (# "conv.ovf.i8" value : int64 #) + when ^T : float = (# "conv.ovf.i8" value : int64 #) + when ^T : float32 = (# "conv.ovf.i8" value : int64 #) + when ^T : int64 = (# "" value : int64 #) + when ^T : int32 = (# "conv.ovf.i8" value : int64 #) + when ^T : int16 = (# "conv.ovf.i8" value : int64 #) + when ^T : nativeint = (# "conv.ovf.i8" value : int64 #) + when ^T : sbyte = (# "conv.ovf.i8" value : int64 #) when ^T : uint64 = (# "conv.ovf.i8.un" value : int64 #) when ^T : uint32 = (# "conv.ovf.i8.un" value : int64 #) when ^T : uint16 = (# "conv.ovf.i8.un" value : int64 #) 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 #) + when ^T : byte = (# "conv.ovf.i8.un" value : int64 #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> int64) (value)) [] @@ -5391,19 +5391,19 @@ namespace Microsoft.FSharp.Core let inline unativeint (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.u" value : unativeint #) - when ^T : int32 = (# "conv.ovf.u" value : unativeint #) - when ^T : int16 = (# "conv.ovf.u" value : unativeint #) - when ^T : nativeint = (# "conv.ovf.u" value : unativeint #) - when ^T : sbyte = (# "conv.ovf.u" value : unativeint #) + when ^T : float = (# "conv.ovf.u" value : unativeint #) + when ^T : float32 = (# "conv.ovf.u" value : unativeint #) + when ^T : int64 = (# "conv.ovf.u" value : unativeint #) + when ^T : int32 = (# "conv.ovf.u" value : unativeint #) + when ^T : int16 = (# "conv.ovf.u" value : unativeint #) + when ^T : nativeint = (# "conv.ovf.u" value : unativeint #) + when ^T : sbyte = (# "conv.ovf.u" value : unativeint #) when ^T : uint64 = (# "conv.ovf.u.un" value : unativeint #) when ^T : uint32 = (# "conv.ovf.u.un" value : unativeint #) when ^T : uint16 = (# "conv.ovf.u.un" value : unativeint #) 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 #) + when ^T : unativeint = (# "" value : unativeint #) + when ^T : byte = (# "conv.ovf.u.un" value : unativeint #) when ^T : decimal = (# "conv.ovf.u.un" (uint64 (# "" value : decimal #)) : unativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> unativeint) (value)) @@ -5412,19 +5412,19 @@ namespace Microsoft.FSharp.Core let inline nativeint (value: ^T) = CheckedExplicitDynamic<(^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 #) - when ^T : int64 = (# "conv.ovf.i" value : nativeint #) - when ^T : int32 = (# "conv.ovf.i" value : nativeint #) - when ^T : int16 = (# "conv.ovf.i" value : nativeint #) - when ^T : nativeint = (# "conv.ovf.i" value : nativeint #) - when ^T : sbyte = (# "conv.ovf.i" value : nativeint #) + when ^T : float = (# "conv.ovf.i" value : nativeint #) + when ^T : float32 = (# "conv.ovf.i" value : nativeint #) + when ^T : int64 = (# "conv.ovf.i" value : nativeint #) + when ^T : int32 = (# "conv.ovf.i" value : nativeint #) + when ^T : int16 = (# "conv.ovf.i" value : nativeint #) + when ^T : nativeint = (# "" value : nativeint #) + when ^T : sbyte = (# "conv.ovf.i" value : nativeint #) when ^T : uint64 = (# "conv.ovf.i.un" value : nativeint #) when ^T : uint32 = (# "conv.ovf.i.un" value : nativeint #) when ^T : uint16 = (# "conv.ovf.i.un" value : nativeint #) 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 #) + when ^T : byte = (# "conv.ovf.i.un" value : nativeint #) when ^T : decimal = (# "conv.ovf.i" (int64 (# "" value : decimal #)) : nativeint #) when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value)) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 8514267d18d..5a7c22ce4a0 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -1182,7 +1182,7 @@ let ``Test Operator Declarations for Byte`` () = [], "let testByteAdditionChecked(e1) (e2) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),e1,e2)) @ (24,53--24,70)" [], "let testByteSubtractionChecked(e1) (e2) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),e1,e2)) @ (25,53--25,70)" [], "let testByteMultiplyChecked(e1) (e2) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (26,53--26,70)" - [], "let testByteToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" + [], "let testByteToByteChecked(e1) = e1 @ (29,56--29,58)" [], "let testByteToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" [], "let testByteToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" [], "let testByteToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" @@ -1193,7 +1193,7 @@ let ``Test Operator Declarations for Byte`` () = [], "let testByteToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,43--37,60)" [], "let testByteToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,43--38,63)" [], "let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,43--39,64)" - [], "let testByteToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,43--41,50)" + [], "let testByteToByteOperator(e1) = e1 @ (41,48--41,50)" [], "let testByteToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,43--42,51)" [], "let testByteToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,43--43,51)" [], "let testByteToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,43--44,52)" @@ -1294,7 +1294,7 @@ let ``Test Operator Declarations for SByte`` () = [], "let testSByteMultiplyChecked(e1) (e2) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Checked.op_Multiply (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.MultiplyDynamic (arg0_0,arg1_0),e1,e2)) @ (26,56--26,73)" [], "let testSByteUnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,45--27,60)" [], "let testSByteToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" - [], "let testSByteToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" + [], "let testSByteToSByteChecked(e1) = e1 @ (30,59--30,61)" [], "let testSByteToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" [], "let testSByteToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" [], "let testSByteToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" @@ -1305,7 +1305,7 @@ let ``Test Operator Declarations for SByte`` () = [], "let testSByteToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" [], "let testSByteToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" [], "let testSByteToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" - [], "let testSByteToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" + [], "let testSByteToSByteOperator(e1) = e1 @ (42,51--42,53)" [], "let testSByteToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" [], "let testSByteToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" [], "let testSByteToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" @@ -1404,7 +1404,7 @@ let ``Test Operator Declarations for Int16`` () = [], "let testInt16UnaryNegChecked(e1) = Checked.op_Subtraction (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.SubtractionDynamic (arg0_0,arg1_0),0,e1) @ (27,45--27,60)" [], "let testInt16ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,45--29,60)" [], "let testInt16ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" - [], "let testInt16ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" + [], "let testInt16ToInt16Checked(e1) = e1 @ (31,59--31,61)" [], "let testInt16ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" [], "let testInt16ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" [], "let testInt16ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" @@ -1415,7 +1415,7 @@ let ``Test Operator Declarations for Int16`` () = [], "let testInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" [], "let testInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,45--41,52)" [], "let testInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,45--42,53)" - [], "let testInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,45--43,53)" + [], "let testInt16ToInt16Operator(e1) = e1 @ (43,51--43,53)" [], "let testInt16ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,45--44,54)" [], "let testInt16ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" [], "let testInt16ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" @@ -1472,6 +1472,7 @@ let ``Test Operator Declarations for UInt16`` () = [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt16ToCharChecked(e1) = Checked.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (40,47--40,62)" [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" @@ -1513,7 +1514,7 @@ let ``Test Operator Declarations for UInt16`` () = [], "let testUInt16ToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,47--29,62)" [], "let testUInt16ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,47--30,63)" [], "let testUInt16ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,47--31,63)" - [], "let testUInt16ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" + [], "let testUInt16ToUInt16Checked(e1) = e1 @ (32,62--32,64)" [], "let testUInt16ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" [], "let testUInt16ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" [], "let testUInt16ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" @@ -1521,10 +1522,11 @@ let ``Test Operator Declarations for UInt16`` () = [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" + [], "let testUInt16ToCharChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (40,47--40,62)" [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" - [], "let testUInt16ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" + [], "let testUInt16ToUInt16Operator(e1) = e1 @ (44,54--44,56)" [], "let testUInt16ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" [], "let testUInt16ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" [], "let testUInt16ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" @@ -1623,8 +1625,8 @@ let ``Test Operator Declarations for Int`` () = [], "let testIntToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,41--30,57)" [], "let testIntToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,41--31,57)" [], "let testIntToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,41--32,58)" - [], "let testIntToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,41--33,55)" - [], "let testIntToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,41--34,57)" + [], "let testIntToIntChecked(e1) = e1 @ (33,53--33,55)" + [], "let testIntToInt32Checked(e1) = e1 @ (34,55--34,57)" [], "let testIntToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,41--35,58)" [], "let testIntToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,41--36,57)" [], "let testIntToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,41--37,58)" @@ -1732,8 +1734,8 @@ let ``Test Operator Declarations for Int32`` () = [], "let testInt32ToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,45--30,61)" [], "let testInt32ToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,45--31,61)" [], "let testInt32ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,45--32,62)" - [], "let testInt32ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" - [], "let testInt32ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" + [], "let testInt32ToIntChecked(e1) = e1 @ (33,57--33,59)" + [], "let testInt32ToInt32Checked(e1) = e1 @ (34,59--34,61)" [], "let testInt32ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" [], "let testInt32ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" [], "let testInt32ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" @@ -1843,7 +1845,7 @@ let ``Test Operator Declarations for UInt32`` () = [], "let testUInt32ToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,47--32,64)" [], "let testUInt32ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,47--33,61)" [], "let testUInt32ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" - [], "let testUInt32ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" + [], "let testUInt32ToUInt32Checked(e1) = e1 @ (35,62--35,64)" [], "let testUInt32ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" [], "let testUInt32ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" [], "let testUInt32ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" @@ -1854,7 +1856,7 @@ let ``Test Operator Declarations for UInt32`` () = [], "let testUInt32ToUInt16Operator(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (44,47--44,56)" [], "let testUInt32ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,47--45,53)" [], "let testUInt32ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,47--46,55)" - [], "let testUInt32ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,47--47,56)" + [], "let testUInt32ToUInt32Operator(e1) = e1 @ (47,54--47,56)" [], "let testUInt32ToInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,47--48,55)" [], "let testUInt32ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,47--49,56)" [], "let testUInt32ToIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,47--50,59)" @@ -1953,7 +1955,7 @@ let ``Test Operator Declarations for Int64`` () = [], "let testInt64ToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,45--33,59)" [], "let testInt64ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,45--34,61)" [], "let testInt64ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,45--35,62)" - [], "let testInt64ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,45--36,61)" + [], "let testInt64ToInt64Checked(e1) = e1 @ (36,59--36,61)" [], "let testInt64ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,45--37,62)" [], "let testInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,45--38,65)" [], "let testInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,45--39,66)" @@ -1964,7 +1966,7 @@ let ``Test Operator Declarations for Int64`` () = [], "let testInt64ToIntOperator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (45,45--45,51)" [], "let testInt64ToInt32Operator(e1) = Operators.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (46,45--46,53)" [], "let testInt64ToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,45--47,54)" - [], "let testInt64ToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,45--48,53)" + [], "let testInt64ToInt64Operator(e1) = e1 @ (48,51--48,53)" [], "let testInt64ToUInt64Operator(e1) = Operators.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,45--49,54)" [], "let testInt64ToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,45--50,57)" [], "let testInt64ToUIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,45--51,58)" @@ -2063,7 +2065,7 @@ let ``Test Operator Declarations for UInt64`` () = [], "let testUInt64ToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,47--34,63)" [], "let testUInt64ToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,47--35,64)" [], "let testUInt64ToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,47--36,63)" - [], "let testUInt64ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" + [], "let testUInt64ToUInt64Checked(e1) = e1 @ (37,62--37,64)" [], "let testUInt64ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" [], "let testUInt64ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" [], "let testUInt64ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" @@ -2173,7 +2175,7 @@ let ``Test Operator Declarations for IntPtr`` () = [], "let testIntPtrToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,50--35,67)" [], "let testIntPtrToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,50--36,66)" [], "let testIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,50--37,67)" - [], "let testIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,50--38,70)" + [], "let testIntPtrToIntPtrChecked(e1) = e1 @ (38,68--38,70)" [], "let testIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,50--39,71)" [], "let testIntPtrToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,50--41,57)" [], "let testIntPtrToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,50--42,58)" @@ -2184,7 +2186,7 @@ let ``Test Operator Declarations for IntPtr`` () = [], "let testIntPtrToUInt32Operator(e1) = Operators.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (47,50--47,59)" [], "let testIntPtrToInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (48,50--48,58)" [], "let testIntPtrToUInt64Operator(e1) = Operators.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (49,50--49,59)" - [], "let testIntPtrToIntPtrOperator(e1) = Operators.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (50,50--50,62)" + [], "let testIntPtrToIntPtrOperator(e1) = e1 @ (50,60--50,62)" [], "let testIntPtrToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,50--51,63)" [], "let testIntPtrToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (52,50--52,60)" [], "let testIntPtrToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (53,50--53,58)" @@ -2282,7 +2284,7 @@ let ``Test Operator Declarations for UIntPtr`` () = [], "let testUIntPtrToInt64Checked(e1) = Checked.ToInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (36,52--36,68)" [], "let testUIntPtrToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,52--37,69)" [], "let testUIntPtrToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,52--38,72)" - [], "let testUIntPtrToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,52--39,73)" + [], "let testUIntPtrToUIntPtrChecked(e1) = e1 @ (39,71--39,73)" [], "let testUIntPtrToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,52--41,59)" [], "let testUIntPtrToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,52--42,60)" [], "let testUIntPtrToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,52--43,60)" @@ -2889,7 +2891,7 @@ let ``Test Operator Declarations for Char`` () = [], "let testCharToUIntPtrOperator(e1) = Operators.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (51,43--51,56)" [], "let testCharToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,43--52,53)" [], "let testCharToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,43--53,51)" - [], "let testCharToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,43--55,50)" + [], "let testCharToCharOperator(e1) = e1 @ (55,48--55,50)" [FC47; FC50], "let testCharToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.char = e1 in copyOfStruct.ToString() @ (56,43--56,52)" ] From e350d811a98ef95c8b2aa2bd46c616e18f1bb646 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 20 Aug 2021 20:49:37 +0800 Subject: [PATCH 74/78] Fix tests again --- tests/service/ExprTests.fs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 5a7c22ce4a0..b99bd59b726 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -1472,7 +1472,6 @@ let ``Test Operator Declarations for UInt16`` () = [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" - [], "let testUInt16ToCharChecked(e1) = Checked.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (40,47--40,62)" [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" @@ -1522,7 +1521,6 @@ let ``Test Operator Declarations for UInt16`` () = [], "let testUInt16ToUInt64Checked(e1) = Checked.ToUInt64 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (37,47--37,64)" [], "let testUInt16ToIntPtrChecked(e1) = Checked.ToIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (38,47--38,67)" [], "let testUInt16ToUIntPtrChecked(e1) = Checked.ToUIntPtr (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (39,47--39,68)" - [], "let testUInt16ToCharChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (40,47--40,62)" [], "let testUInt16ToByteOperator(e1) = Operators.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (41,47--41,54)" [], "let testUInt16ToSByteOperator(e1) = Operators.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (42,47--42,55)" [], "let testUInt16ToInt16Operator(e1) = Operators.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (43,47--43,55)" @@ -2870,7 +2868,7 @@ let ``Test Operator Declarations for Char`` () = [], "let testCharToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" [], "let testCharToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" [], "let testCharToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" - [], "let testCharToUInt16Checked(e1) = Checked.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" + [], "let testCharToUInt16Checked(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,52)" [], "let testCharToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,43--33,57)" [], "let testCharToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,43--34,59)" [], "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,43--35,60)" From a274e2088957fb80af717251a528f6c91ddf5cac Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Fri, 20 Aug 2021 21:27:25 +0800 Subject: [PATCH 75/78] Fix tests 3 --- tests/service/ExprTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index b99bd59b726..178f8829502 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -1535,7 +1535,7 @@ let ``Test Operator Declarations for UInt16`` () = [], "let testUInt16ToSingleOperator(e1) = Operators.ToSingle (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (52,47--52,57)" [], "let testUInt16ToDoubleOperator(e1) = Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),Operators.ToDouble (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1)) @ (53,47--53,55)" [], "let testUInt16ToDecimalOperator(e1) = Convert.ToDecimal (e1) @ (54,47--54,57)" - [], "let testUInt16ToCharOperator(e1) = Operators.ToChar (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (55,47--55,54)" + [], "let testUInt16ToCharOperator(e1) = e1 @ (55,47--55,54)" [FC47; FC50], "let testUInt16ToStringOperator(e1) = let mutable copyOfStruct: Microsoft.FSharp.Core.uint16 = e1 in copyOfStruct.ToString() @ (56,47--56,56)" ] @@ -2868,7 +2868,7 @@ let ``Test Operator Declarations for Char`` () = [], "let testCharToByteChecked(e1) = Checked.ToByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (29,43--29,58)" [], "let testCharToSByteChecked(e1) = Checked.ToSByte (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (30,43--30,59)" [], "let testCharToInt16Checked(e1) = Checked.ToInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (31,43--31,59)" - [], "let testCharToUInt16Checked(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,52)" + [], "let testCharToUInt16Checked(e1) = Operators.ToUInt16 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (32,43--32,60)" [], "let testCharToIntChecked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (33,43--33,57)" [], "let testCharToInt32Checked(e1) = Checked.ToInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (34,43--34,59)" [], "let testCharToUInt32Checked(e1) = Checked.ToUInt32 (fun arg0_0 -> LanguagePrimitives.ExplicitDynamic (arg0_0),e1) @ (35,43--35,60)" From 700084dfffb6221c6e41503e9225fec5b3318b1e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 21 Aug 2021 00:38:49 +0800 Subject: [PATCH 76/78] Fix tests 4 --- tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index 1a281fd465a..abec489fc69 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -52,11 +52,11 @@ type OperatorsModule2() = // Overflow. let result = Operators.int Single.MaxValue - Assert.AreEqual(0, result) + Assert.AreEqual(Int32.MinValue, result) // Overflow let result = Operators.int Single.MinValue - Assert.AreEqual(0, result) + Assert.AreEqual(Int32.MinValue, result) // Overflow let result = Operators.int Double.MaxValue From 1b456c8aed74a74da473e2237b31412cd526af2a Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 22 Aug 2021 20:37:01 +0800 Subject: [PATCH 77/78] Convert PhysicalEquality too --- src/fsharp/FSharp.Core/Linq.fs | 3 +++ tests/fsharp/core/quotes/test.fsx | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/fsharp/FSharp.Core/Linq.fs b/src/fsharp/FSharp.Core/Linq.fs index 466c3c4175f..bb4deffe258 100644 --- a/src/fsharp/FSharp.Core/Linq.fs +++ b/src/fsharp/FSharp.Core/Linq.fs @@ -258,6 +258,7 @@ module LeafExpressionConverter = SpecificCallToMethodInfo minfo let (|GenericArgs|) (minfo: MethodInfo) = minfo.GetGenericArguments() + let (|PhysicalEqualityQ|_|) = (|SpecificCallToMethod|_|) (methodhandleof (fun (x, y) -> LanguagePrimitives.PhysicalEquality x y)) 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)) @@ -524,6 +525,8 @@ module LeafExpressionConverter = | PlusQ (_, GenericArgs [|ty1; ty2; ty3|], [x1; x2]) when ty1 = typeof && ty2 = typeof && ty3 = typeof -> Expression.Add(ConvExprToLinqInContext env x1, ConvExprToLinqInContext env x2, StringConcat) |> asExpr + // LanguagePrimitives.PhysicalEquality's generic constraint of both sides being the same reference type is already sufficient for Linq Expressions' requirements + | PhysicalEqualityQ (_, m, [x1; x2]) -> transBoolOpNoWitness (fun _ -> true) env false x1 x2 false (fun (l, r, _, _) -> Expression.ReferenceEqual(l, r)) m | GenericEqualityQ (_, m, [x1; x2]) | EqualsQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 false Expression.Equal m | NotEqQ (_, m, [x1; x2]) -> transBoolOpNoWitness isLinqExpressionsStructurallyEquatable env false x1 x2 false Expression.NotEqual m diff --git a/tests/fsharp/core/quotes/test.fsx b/tests/fsharp/core/quotes/test.fsx index 07d47a1914c..9f26d8e2ea4 100644 --- a/tests/fsharp/core/quotes/test.fsx +++ b/tests/fsharp/core/quotes/test.fsx @@ -4963,6 +4963,13 @@ module WitnessTests = test "check non-CallWithWitnesses operators" (let tests = [| + <@@ LanguagePrimitives.PhysicalEquality [|3|] [|3|] @@>, box false + <@@ let x = [|3|] in LanguagePrimitives.PhysicalEquality x x @@>, box true + <@@ LanguagePrimitives.PhysicalEquality (seq { 3 }) (seq { 3 }) @@>, box false + <@@ let x = seq { 3 } in LanguagePrimitives.PhysicalEquality x x @@>, box true + <@@ LanguagePrimitives.PhysicalEquality (obj()) (obj()) @@>, box false + <@@ let x = obj() in LanguagePrimitives.PhysicalEquality x x @@>, box true + <@@ 3y = 3y @@>, box true <@@ 3uy = 3uy @@>, box true <@@ 3s = 3s @@>, box true @@ -4983,7 +4990,9 @@ module WitnessTests = <@@ [3] = [3] @@>, box true <@@ [|3|] = [|3|] @@>, box true <@@ seq { 3 } = seq { 3 } @@>, box false // Reference equality + <@@ let x = seq { 3 } in x = x @@>, box true <@@ obj() = obj() @@>, box false + <@@ let x = obj() in x = x @@>, box true <@@ 3y <> 3y @@>, box false <@@ 3uy <> 3uy @@>, box false @@ -5005,7 +5014,9 @@ module WitnessTests = <@@ [3] <> [3] @@>, box false <@@ [|3|] <> [|3|] @@>, box false <@@ seq { 3 } <> seq { 3 } @@>, box true // Reference equality + <@@ let x = seq { 3 } in x <> x @@>, box false <@@ obj() <> obj() @@>, box true + <@@ let x = obj() in x <> x @@>, box false <@@ 3y <= 3y @@>, box true <@@ 3uy <= 3uy @@>, box true From d8b4f45e96cac2a2d98d2e6cbebcff8e30b89c5b Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Tue, 21 Jun 2022 16:48:35 +0200 Subject: [PATCH 78/78] Apply fantomas --- src/FSharp.Core/Linq.fsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/FSharp.Core/Linq.fsi b/src/FSharp.Core/Linq.fsi index 648ffbdf3c8..13f3fa4187e 100644 --- a/src/FSharp.Core/Linq.fsi +++ b/src/FSharp.Core/Linq.fsi @@ -87,4 +87,5 @@ module LeafExpressionConverter = /// val SubstHelperRaw: Expr * Var[] * obj[] -> Expr - val internal (|SpecificCallToMethod|_|): System.RuntimeMethodHandle -> (Expr -> (Expr option * Reflection.MethodInfo * Expr list) option) \ No newline at end of file + val internal (|SpecificCallToMethod|_|): + System.RuntimeMethodHandle -> (Expr -> (Expr option * Reflection.MethodInfo * Expr list) option)