未验证 提交 f89e6518 编写于 作者: H Hadrian Tang 提交者: GitHub

Subtraction of two chars, new conversions, and fixes for dynamic operator...

Subtraction of two chars, new conversions, and fixes for dynamic operator invocations and QuotationToExpression (#11681)
Co-authored-by: NVlad Zarytovskii <vzaritovsky@hotmail.com>
Co-authored-by: NDon Syme <dsyme@users.noreply.github.com>
上级 0c1eba06
......@@ -428,7 +428,7 @@ 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
......@@ -443,7 +443,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)
......@@ -1601,25 +1601,30 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
return TTraitBuiltIn
| _, _, false, "op_Explicit", [argTy]
when (// The input type.
// Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in
| _, _, false, "op_Explicit", [argTy]
when (// The input type.
(IsNonDecimalNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
// The output type
(IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy) &&
// Exclusion: IntPtr and UIntPtr do not support .Parse() from string
not (isStringTy g argTy && isNativeIntegerTy g retTy) &&
// Exclusion: No conversion from char to decimal
not (isCharTy g argTy && isDecimalTy g retTy)) ->
(IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy)) ->
return TTraitBuiltIn
| _, _, false, "op_Explicit", [argTy]
when (// The input type.
(IsNumericOrIntegralEnumType g argTy || isStringTy g argTy) &&
// 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 || isCharTy g argTy) &&
// The output type
(isDecimalTy g retTy)) ->
(isDecimalTy g retTy)) ->
return TTraitBuiltIn
// Conversions from decimal numbers to native integers are built-in
// 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) &&
// The output type
(isNativeIntegerTy g retTy)) ->
return TTraitBuiltIn
| [], _, false, "Pow", [argTy1; argTy2]
......
......@@ -1779,7 +1779,7 @@ type TcGlobals(
[ 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 ]
......
......@@ -1493,7 +1493,7 @@ namedModuleDefnBlock:
{ Choice1Of2 $1.LongIdent }
/* 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 }
......
此差异已折叠。
......@@ -88,4 +88,4 @@ module LeafExpressionConverter =
val SubstHelperRaw: Expr * Var[] * obj[] -> Expr
val internal (|SpecificCallToMethod|_|):
System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option)
System.RuntimeMethodHandle -> (Expr -> (Expr option * Reflection.MethodInfo * Expr list) option)
......@@ -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|_|) = (|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|_|) = (|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|_|) = (|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.
......@@ -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)
......
此差异已折叠。
......@@ -1542,6 +1542,10 @@ namespace Microsoft.FSharp.Core
[<CompilerMessage("This function is for use by dynamic invocations of F# code and should not be used directly", 1204, IsHidden=true)>]
val ExplicitDynamic: value: 'T -> 'U
/// <summary>A compiler intrinsic that implements dynamic invocations related to checked conversion operators.</summary>
[<CompilerMessage("This function is for use by dynamic invocations of F# code and should not be used directly", 1204, IsHidden=true)>]
val CheckedExplicitDynamic : value:'T -> 'U
/// <summary>A compiler intrinsic that implements dynamic invocations related to the '&lt;' operator.</summary>
[<CompilerMessage("This function is for use by dynamic invocations of F# code and should not be used directly", 1204, IsHidden=true)>]
val LessThanDynamic: x: 'T1 -> y: 'T2 -> 'U
......
......@@ -42,6 +42,7 @@
<Compile Include="FSharp.Core\OperatorsModule1.fs" />
<Compile Include="FSharp.Core\OperatorsModule2.fs" />
<Compile Include="FSharp.Core\OperatorsModuleChecked.fs" />
<Compile Include="FSharp.Core\OperatorsModuleDynamic.fs" />
<Compile Include="FSharp.Core\NativeInterop.fs" />
<Compile Include="FSharp.Core\Microsoft.FSharp.Collections\Utils.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)
[<Fact>]
member _.ceil() =
......@@ -301,18 +309,44 @@ 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)
[<Fact>]
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)
// 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 " "
......@@ -366,12 +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 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)
[<Fact>]
member _.decr() =
......@@ -416,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)
[<Fact>]
member _.enum() =
......@@ -424,7 +474,7 @@ type OperatorsModule1() =
let intenum = Operators.enum<System.ConsoleColor> intarg
Assert.AreEqual(System.ConsoleColor.Black, intenum)
// big number
// big number
let bigarg : int32 = 15
let charenum = Operators.enum<System.ConsoleColor> bigarg
Assert.AreEqual(System.ConsoleColor.White, charenum)
......@@ -488,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)
[<Fact>]
member _.float32() =
// int type
......@@ -497,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)
[<Fact>]
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)
[<Fact>]
member _.fst() =
......
......@@ -51,6 +51,14 @@ type OperatorsModule2() =
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)
......@@ -72,7 +80,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)
[<Fact>]
member _.int16() =
......@@ -96,6 +104,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)
......@@ -116,7 +132,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)
[<Fact>]
member _.int32() =
......@@ -140,6 +156,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)
......@@ -161,7 +185,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)
[<Fact>]
member _.int64() =
......@@ -185,6 +209,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)
......@@ -202,11 +234,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)
[<Fact>]
member _.invalidArg() =
CheckThrowsArgumentException(fun() -> Operators.invalidArg "A" "B" |>ignore )
CheckThrowsArgumentException(fun () -> Operators.invalidArg "A" "B" |>ignore )
[<Fact>]
......@@ -328,6 +360,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
......@@ -396,7 +444,7 @@ type OperatorsModule2() =
[<Fact>]
member _.nullArg() =
CheckThrowsArgumentNullException(fun() -> Operators.nullArg "A" |> ignore)
CheckThrowsArgumentNullException(fun () -> Operators.nullArg "A" |> ignore)
[<Fact>]
......@@ -429,11 +477,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)
[<Fact>]
member _.raise() =
CheckThrowsArgumentException(fun()-> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore)
CheckThrowsArgumentException(fun () -> Operators.raise <| new ArgumentException("Invalid Argument ") |> ignore)
[<Fact>]
......@@ -559,7 +607,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)
[<Fact>]
member _.sign() =
......@@ -694,6 +742,10 @@ type OperatorsModule2() =
let result = Operators.sizeof<System.Int64>
Assert.AreEqual(8, result)
// custom struct
let result = Operators.sizeof<System.ConsoleKeyInfo>
Assert.AreEqual(12, result)
// reference type should have the same size as the IntPtr
let result = Operators.sizeof<string>
Assert.AreEqual(IntPtr.Size, result)
......@@ -899,9 +951,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)
[<Fact>]
member _.uint32() =
......@@ -917,6 +985,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)
......@@ -943,7 +1019,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)
[<Fact>]
member _.uint64() =
......@@ -959,6 +1035,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)
......@@ -980,7 +1064,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)
[<Fact>]
member _.unativeint() =
......@@ -993,6 +1077,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)
......
......@@ -21,12 +21,14 @@ 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)
// 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)
[<Fact>]
......@@ -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)
......@@ -1486,6 +1486,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)
......
......@@ -3657,6 +3657,46 @@ 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')
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)
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)
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)
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
......
此差异已折叠。
......@@ -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,37 @@ 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 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
......@@ -1265,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
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册