From a9617cdbb63538b4b8c10fc77f7d4a27de812f1b Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 23 Jul 2020 13:37:49 -0700 Subject: [PATCH 1/8] Initial work to fix op_UnaryPlus witness info --- src/fsharp/TcGlobals.fs | 5 +++ .../Compiler/Language/CodeQuotationTests.fs | 40 +++++++++++++++++++ .../fsharp/Compiler/Language/WitnessTests.fs | 25 ++++++++++++ tests/fsharp/FSharpSuite.Tests.fsproj | 2 + 4 files changed, 72 insertions(+) create mode 100644 tests/fsharp/Compiler/Language/CodeQuotationTests.fs create mode 100644 tests/fsharp/Compiler/Language/WitnessTests.fs diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index b574214ecec..fe2502c6853 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -1601,6 +1601,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d Some (g.array_set_info, [ety], argExprs) | "get_Item", [sty; _; _], _, [_; _] when isStringTy g sty -> Some (g.getstring_info, [], argExprs) + | "op_UnaryPlus", [aty], _, [_] -> + // Call Operators.(~+) + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "op_UnaryPlus", None, None, [vara], ([[varaTy]], varaTy)) + let tyargs = [aty] + Some (info, tyargs, argExprs) | _ -> None diff --git a/tests/fsharp/Compiler/Language/CodeQuotationTests.fs b/tests/fsharp/Compiler/Language/CodeQuotationTests.fs new file mode 100644 index 00000000000..aca1a864f93 --- /dev/null +++ b/tests/fsharp/Compiler/Language/CodeQuotationTests.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test.Utilities.Compiler +open FSharp.Quotations.Patterns + +[] +module CodeQuotationsTests = + + [] + let ``Quotation on op_UnaryPlus(~+) compiles and runs`` () = + Fsx """ +open FSharp.Linq.RuntimeHelpers +open FSharp.Quotations.Patterns +open FSharp.Quotations.DerivedPatterns + +let eval q = LeafExpressionConverter.EvaluateQuotation q + +let inline f x = <@ (~+) x @> +let x = <@ f 1 @> +let y : unit = + match f 1 with + | Call(_, methInfo, _) when methInfo.Name = "op_UnaryPlus" -> + () + | e -> + failwithf "did not expect expression for 'y': %A" e +let z : obj = + match f 1 with + | (CallWithWitnesses(_, methInfo, methInfoW, _, _) as e) when methInfo.Name = "op_UnaryPlus" && methInfoW.Name = "op_UnaryPlus$W" -> + eval e + | e -> + failwithf "did not expect expression for 'z': %A" e + """ + |> asExe + |> withOptions ["--langversion:preview"] + |> compileAndRun + + diff --git a/tests/fsharp/Compiler/Language/WitnessTests.fs b/tests/fsharp/Compiler/Language/WitnessTests.fs new file mode 100644 index 00000000000..b4501ffdd28 --- /dev/null +++ b/tests/fsharp/Compiler/Language/WitnessTests.fs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.UnitTests + +open NUnit.Framework +open FSharp.Test.Utilities.Compiler +open FSharp.Tests + +[] +module WitnessTests = + + [] + let ``Witness expressions are created as a result of compiling the type provider tests`` () = + let dir = Core.getTestsDirectory "typeProviders/helloWorld" + Fsx (sprintf """ +#load @"%s" + """ (dir ++ "provider.fsx")) + |> asExe + |> ignoreWarnings + |> withOptions ["--langversion:preview"] + |> compile + |> shouldSucceed + |> ignore + + diff --git a/tests/fsharp/FSharpSuite.Tests.fsproj b/tests/fsharp/FSharpSuite.Tests.fsproj index db41395b37c..1c4f337025d 100644 --- a/tests/fsharp/FSharpSuite.Tests.fsproj +++ b/tests/fsharp/FSharpSuite.Tests.fsproj @@ -41,6 +41,8 @@ + + From 57df7948148dcf5cb4a13dc60ea4e8596a3ec52e Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 23 Jul 2020 19:26:50 -0700 Subject: [PATCH 2/8] Added UnaryPlusDynamic --- src/fsharp/FSharp.Core/prim-types.fs | 17 +++-------------- src/fsharp/FSharp.Core/prim-types.fsi | 5 +++++ src/fsharp/TcGlobals.fs | 7 ++----- .../Compiler/Language/CodeQuotationTests.fs | 9 ++++++--- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 36567214f14..a193dd2dacd 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2634,6 +2634,8 @@ namespace Microsoft.FSharp.Core elif type2eq<'T, 'U, decimal> then convPrim<_,'U> (Decimal.op_UnaryNegation(convPrim<_,decimal> value)) else UnaryOpDynamicImplTable.Invoke "op_UnaryNegation" value + let UnaryPlusDynamic<'T> (value: 'T) : 'T = value + type OpCheckedAdditionInfo = class end let CheckedAdditionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "add.ovf" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) @@ -3993,20 +3995,7 @@ namespace Microsoft.FSharp.Core [] let inline (~+) (value: ^T) : ^T = - value - when ^T : int32 = value - when ^T : float = value - when ^T : float32 = value - when ^T : int64 = value - when ^T : uint64 = value - when ^T : uint32 = value - when ^T : int16 = value - when ^T : uint16 = value - when ^T : nativeint = value - when ^T : unativeint = value - when ^T : sbyte = value - when ^T : byte = value - when ^T : decimal = value + UnaryPlusDynamic<(^T)> value when ^T : ^T = (^T: (static member (~+) : ^T -> ^T) (value)) [] diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 3c35192188e..d09cf029978 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -1101,6 +1101,11 @@ namespace Microsoft.FSharp.Core [] val UnaryNegationDynamic : value:'T -> 'U + /// A compiler intrinsic that implements dynamic invocations to the unary '~+' operator. + [] + [] + val UnaryPlusDynamic : value:'T -> 'T + /// A compiler intrinsic that implements dynamic invocations to the '%' operator. [] [] diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index fe2502c6853..594ae636e97 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -1550,6 +1550,8 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d [vara], [ varaTy; v_int32_ty ], varaTy, [ arg0Ty ] | ("GenericZeroDynamic" | "GenericOneDynamic"), [], Some retTy -> [vara], [ ], varaTy, [ retTy ] + | "UnaryPlusDynamic", [ arg0Ty ], Some retTy -> + [vara], [ arg0Ty ], varaTy, [ retTy ] | _ -> failwithf "unknown builtin witness '%s'" memberName let vref = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, memberName, None, None, gtps, (List.map List.singleton argTys, retTy)) vref, tinst @@ -1601,11 +1603,6 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d Some (g.array_set_info, [ety], argExprs) | "get_Item", [sty; _; _], _, [_; _] when isStringTy g sty -> Some (g.getstring_info, [], argExprs) - | "op_UnaryPlus", [aty], _, [_] -> - // Call Operators.(~+) - let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "op_UnaryPlus", None, None, [vara], ([[varaTy]], varaTy)) - let tyargs = [aty] - Some (info, tyargs, argExprs) | _ -> None diff --git a/tests/fsharp/Compiler/Language/CodeQuotationTests.fs b/tests/fsharp/Compiler/Language/CodeQuotationTests.fs index aca1a864f93..c3feb8277a4 100644 --- a/tests/fsharp/Compiler/Language/CodeQuotationTests.fs +++ b/tests/fsharp/Compiler/Language/CodeQuotationTests.fs @@ -26,10 +26,13 @@ let y : unit = () | e -> failwithf "did not expect expression for 'y': %A" e -let z : obj = - match f 1 with +let z : unit = + match f 5 with | (CallWithWitnesses(_, methInfo, methInfoW, _, _) as e) when methInfo.Name = "op_UnaryPlus" && methInfoW.Name = "op_UnaryPlus$W" -> - eval e + if ((eval e) :?> int) = 5 then + () + else + failwith "did not expect evaluation false" | e -> failwithf "did not expect expression for 'z': %A" e """ From 561b2855ea57cbbf74b6112b9a9688cb94b8efd9 Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 24 Jul 2020 00:44:58 -0700 Subject: [PATCH 3/8] update surface area --- tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs | 1 + tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index 5f6fa5cc7f0..e698423d117 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -2796,6 +2796,7 @@ Microsoft.FSharp.Core.LanguagePrimitives: TResult LogicalNotDynamic[T,TResult](T Microsoft.FSharp.Core.LanguagePrimitives: TResult RightShiftDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult SubtractionDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult UnaryNegationDynamic[T,TResult](T) +Microsoft.FSharp.Core.LanguagePrimitives: T UnaryPlusDynamic[T](T) Microsoft.FSharp.Core.Operators+Checked: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) Microsoft.FSharp.Core.Operators+Checked: Char ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], T) Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], T) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index 20a8635188e..47d5bc0db34 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -2797,6 +2797,7 @@ Microsoft.FSharp.Core.LanguagePrimitives: TResult LogicalNotDynamic[T,TResult](T Microsoft.FSharp.Core.LanguagePrimitives: TResult RightShiftDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult SubtractionDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult UnaryNegationDynamic[T,TResult](T) +Microsoft.FSharp.Core.LanguagePrimitives: T UnaryPlusDynamic[T](T) Microsoft.FSharp.Core.Operators+Checked: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) Microsoft.FSharp.Core.Operators+Checked: Char ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], T) Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], T) From d103f113d17e81196c59aa306c7be89067a4442e Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 24 Jul 2020 12:00:24 -0700 Subject: [PATCH 4/8] Only enable type provider test on net472 --- tests/fsharp/Compiler/Language/WitnessTests.fs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/fsharp/Compiler/Language/WitnessTests.fs b/tests/fsharp/Compiler/Language/WitnessTests.fs index b4501ffdd28..67f383c7827 100644 --- a/tests/fsharp/Compiler/Language/WitnessTests.fs +++ b/tests/fsharp/Compiler/Language/WitnessTests.fs @@ -6,6 +6,8 @@ open NUnit.Framework open FSharp.Test.Utilities.Compiler open FSharp.Tests +#if !NETCOREAPP + [] module WitnessTests = @@ -21,5 +23,6 @@ module WitnessTests = |> compile |> shouldSucceed |> ignore +#endif From b4772fac151b9afe650da39b3c6028580c36e053 Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 24 Jul 2020 12:39:38 -0700 Subject: [PATCH 5/8] Removing UnaryPlusDynamic --- src/fsharp/FSharp.Core/prim-types.fs | 2 -- src/fsharp/FSharp.Core/prim-types.fsi | 5 ----- src/fsharp/TcGlobals.fs | 7 +++++-- tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs | 1 - tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs | 1 - 5 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index a193dd2dacd..d4062bb0eba 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2634,8 +2634,6 @@ namespace Microsoft.FSharp.Core elif type2eq<'T, 'U, decimal> then convPrim<_,'U> (Decimal.op_UnaryNegation(convPrim<_,decimal> value)) else UnaryOpDynamicImplTable.Invoke "op_UnaryNegation" value - let UnaryPlusDynamic<'T> (value: 'T) : 'T = value - type OpCheckedAdditionInfo = class end let CheckedAdditionDynamic<'T1, 'T2, 'U> (x: 'T1) (y: 'T2) : 'U = if type3eq<'T1, 'T2, 'U, int32> then convPrim<_,'U> (# "add.ovf" (convPrim<_,int32> x) (convPrim<_,int32> y) : int32 #) diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index d09cf029978..3c35192188e 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -1101,11 +1101,6 @@ namespace Microsoft.FSharp.Core [] val UnaryNegationDynamic : value:'T -> 'U - /// A compiler intrinsic that implements dynamic invocations to the unary '~+' operator. - [] - [] - val UnaryPlusDynamic : value:'T -> 'T - /// A compiler intrinsic that implements dynamic invocations to the '%' operator. [] [] diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 594ae636e97..f8f5f032e5e 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -1550,8 +1550,6 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d [vara], [ varaTy; v_int32_ty ], varaTy, [ arg0Ty ] | ("GenericZeroDynamic" | "GenericOneDynamic"), [], Some retTy -> [vara], [ ], varaTy, [ retTy ] - | "UnaryPlusDynamic", [ arg0Ty ], Some retTy -> - [vara], [ arg0Ty ], varaTy, [ retTy ] | _ -> failwithf "unknown builtin witness '%s'" memberName let vref = makeOtherIntrinsicValRef (fslib_MFLanguagePrimitives_nleref, memberName, None, None, gtps, (List.map List.singleton argTys, retTy)) vref, tinst @@ -1603,6 +1601,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d Some (g.array_set_info, [ety], argExprs) | "get_Item", [sty; _; _], _, [_; _] when isStringTy g sty -> Some (g.getstring_info, [], argExprs) + | "op_UnaryPlus", [aty], _, [_] -> + // Call Operators.(~+) + let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "id", None, None, [vara], ([[varaTy]], varaTy)) + let tyargs = [aty] + Some (info, tyargs, argExprs) | _ -> None diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index e698423d117..5f6fa5cc7f0 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -2796,7 +2796,6 @@ Microsoft.FSharp.Core.LanguagePrimitives: TResult LogicalNotDynamic[T,TResult](T Microsoft.FSharp.Core.LanguagePrimitives: TResult RightShiftDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult SubtractionDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult UnaryNegationDynamic[T,TResult](T) -Microsoft.FSharp.Core.LanguagePrimitives: T UnaryPlusDynamic[T](T) Microsoft.FSharp.Core.Operators+Checked: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) Microsoft.FSharp.Core.Operators+Checked: Char ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], T) Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], T) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index 47d5bc0db34..20a8635188e 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -2797,7 +2797,6 @@ Microsoft.FSharp.Core.LanguagePrimitives: TResult LogicalNotDynamic[T,TResult](T Microsoft.FSharp.Core.LanguagePrimitives: TResult RightShiftDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult SubtractionDynamic[T1,T2,TResult](T1, T2) Microsoft.FSharp.Core.LanguagePrimitives: TResult UnaryNegationDynamic[T,TResult](T) -Microsoft.FSharp.Core.LanguagePrimitives: T UnaryPlusDynamic[T](T) Microsoft.FSharp.Core.Operators+Checked: Byte ToByte$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Byte], T) Microsoft.FSharp.Core.Operators+Checked: Char ToChar$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Char], T) Microsoft.FSharp.Core.Operators+Checked: Int16 ToInt16$W[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Int16], T) From db517d55e467e05fab2913fae785eddf46641b62 Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 24 Jul 2020 12:44:58 -0700 Subject: [PATCH 6/8] fixing build --- 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 d4062bb0eba..20fab66af0d 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3993,7 +3993,7 @@ namespace Microsoft.FSharp.Core [] let inline (~+) (value: ^T) : ^T = - UnaryPlusDynamic<(^T)> value + value when ^T : ^T = (^T: (static member (~+) : ^T -> ^T) (value)) [] From 04a1f19186308ff80860d8b8e427842bc662ebc8 Mon Sep 17 00:00:00 2001 From: TIHan Date: Fri, 24 Jul 2020 12:46:08 -0700 Subject: [PATCH 7/8] fix comment --- src/fsharp/TcGlobals.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index f8f5f032e5e..0c335fdfff2 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -1602,7 +1602,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d | "get_Item", [sty; _; _], _, [_; _] when isStringTy g sty -> Some (g.getstring_info, [], argExprs) | "op_UnaryPlus", [aty], _, [_] -> - // Call Operators.(~+) + // Call Operators.id let info = makeOtherIntrinsicValRef (fslib_MFOperators_nleref, "id", None, None, [vara], ([[varaTy]], varaTy)) let tyargs = [aty] Some (info, tyargs, argExprs) From 727b8762da9df82eb39146ab90e90c8a0dc5f9da Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 24 Jul 2020 14:09:53 -0700 Subject: [PATCH 8/8] Update prim-types.fs --- src/fsharp/FSharp.Core/prim-types.fs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 20fab66af0d..36567214f14 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -3994,6 +3994,19 @@ namespace Microsoft.FSharp.Core [] let inline (~+) (value: ^T) : ^T = value + when ^T : int32 = value + when ^T : float = value + when ^T : float32 = value + when ^T : int64 = value + when ^T : uint64 = value + when ^T : uint32 = value + when ^T : int16 = value + when ^T : uint16 = value + when ^T : nativeint = value + when ^T : unativeint = value + when ^T : sbyte = value + when ^T : byte = value + when ^T : decimal = value when ^T : ^T = (^T: (static member (~+) : ^T -> ^T) (value)) []