Skip to content

Commit 4ad236c

Browse files
committed
support decimal literal attribute
add cctor update docs test: add pattern match test wip wip wip wip wip wip wip
1 parent aa6fd83 commit 4ad236c

File tree

13 files changed

+193
-52
lines changed

13 files changed

+193
-52
lines changed

Diff for: docs/release-notes/.FSharp.Compiler.Service/9.0.200.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
### Added
99

10+
* Support literal attribute on decimals ([PR #17769](https://github.com/dotnet/fsharp/pull/17769))
1011

1112
### Changed
1213

Diff for: src/Compiler/Checking/PostInferenceChecks.fs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1957,7 +1957,8 @@ and CheckAttribArgExpr cenv env expr =
19571957
| Const.Single _
19581958
| Const.Char _
19591959
| Const.Zero
1960-
| Const.String _ -> ()
1960+
| Const.String _
1961+
| Const.Decimal _ -> ()
19611962
| _ ->
19621963
if cenv.reportErrors then
19631964
errorR (Error (FSComp.SR.tastNotAConstantExpression(), m))

Diff for: src/Compiler/CodeGen/IlxGen.fs

+71-2
Original file line numberDiff line numberDiff line change
@@ -8563,10 +8563,15 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
85638563

85648564
let ilFieldDef = mkILStaticField (fspec.Name, fty, None, None, access)
85658565

8566+
let isDecimalConstant =
8567+
match vref.LiteralValue with
8568+
| Some(Const.Decimal _) -> true
8569+
| _ -> false
8570+
85668571
let ilFieldDef =
85678572
match vref.LiteralValue with
8568-
| Some konst -> ilFieldDef.WithLiteralDefaultValue(Some(GenFieldInit m konst))
8569-
| None -> ilFieldDef
8573+
| Some konst when not isDecimalConstant -> ilFieldDef.WithLiteralDefaultValue(Some(GenFieldInit m konst))
8574+
| _ -> ilFieldDef
85708575

85718576
let ilFieldDef =
85728577
let isClassInitializer = (cgbuf.MethodName = ".cctor")
@@ -8578,6 +8583,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
85788583
|| not isClassInitializer
85798584
|| hasLiteralAttr
85808585
)
8586+
|| isDecimalConstant
85818587
)
85828588

85838589
let ilAttribs =
@@ -8590,6 +8596,69 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv bind isStateVar startMarkOpt =
85908596

85918597
let ilAttribs = GenAdditionalAttributesForTy g vspec.Type @ ilAttribs
85928598

8599+
let ilAttribs =
8600+
if isDecimalConstant then
8601+
match vref.LiteralValue with
8602+
| Some(Const.Decimal d) ->
8603+
match System.Decimal.GetBits d with
8604+
| [| lo; med; hi; signExp |] ->
8605+
let scale = (min (((signExp &&& 0xFF0000) >>> 16) &&& 0xFF) 28) |> byte
8606+
let sign = if (signExp &&& 0x80000000) <> 0 then 1uy else 0uy
8607+
8608+
let attrib =
8609+
mkILCustomAttribute (
8610+
g.attrib_DecimalConstantAttribute.TypeRef,
8611+
[
8612+
g.ilg.typ_Byte
8613+
g.ilg.typ_Byte
8614+
g.ilg.typ_Int32
8615+
g.ilg.typ_Int32
8616+
g.ilg.typ_Int32
8617+
],
8618+
[
8619+
ILAttribElem.Byte scale
8620+
ILAttribElem.Byte sign
8621+
ILAttribElem.UInt32(uint32 hi)
8622+
ILAttribElem.UInt32(uint32 med)
8623+
ILAttribElem.UInt32(uint32 lo)
8624+
],
8625+
[]
8626+
)
8627+
8628+
let ilInstrs =
8629+
[
8630+
mkLdcInt32 lo
8631+
mkLdcInt32 med
8632+
mkLdcInt32 hi
8633+
mkLdcInt32 (int32 sign)
8634+
mkLdcInt32 (int32 scale)
8635+
mkNormalNewobj (
8636+
mkILCtorMethSpecForTy (
8637+
fspec.ActualType,
8638+
[
8639+
g.ilg.typ_Int32
8640+
g.ilg.typ_Int32
8641+
g.ilg.typ_Int32
8642+
g.ilg.typ_Bool
8643+
g.ilg.typ_Byte
8644+
]
8645+
)
8646+
)
8647+
mkNormalStsfld fspec
8648+
]
8649+
8650+
// let ilCode =
8651+
// mkILMethodBody (true, [], 8, nonBranchingInstrsToCode ilInstrs, None, None)
8652+
8653+
// let cctorMethDef = mkILClassCtor (MethodBody.IL(notlazy ilCode))
8654+
cgbuf.mgbuf.AddExplicitInitToCctor(fspec.DeclaringTypeRef, fspec, None, None, ilInstrs, [])
8655+
//cgbuf.mgbuf.AddMethodDef(fspec.DeclaringTypeRef, cctorMethDef)
8656+
[ attrib ]
8657+
| _ -> failwith "unreachable"
8658+
| _ -> failwith "unreachable"
8659+
else
8660+
ilAttribs
8661+
85938662
let ilFieldDef =
85948663
ilFieldDef.With(customAttrs = mkILCustomAttrs (ilAttribs @ [ g.DebuggerBrowsableNeverAttribute ]))
85958664

Diff for: src/Compiler/TypedTree/TcGlobals.fs

+1
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,7 @@ type TcGlobals(
14901490
member val attrib_CallerFilePathAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerFilePathAttribute"
14911491
member val attrib_CallerMemberNameAttribute = findSysAttrib "System.Runtime.CompilerServices.CallerMemberNameAttribute"
14921492
member val attrib_SkipLocalsInitAttribute = findSysAttrib "System.Runtime.CompilerServices.SkipLocalsInitAttribute"
1493+
member val attrib_DecimalConstantAttribute = findSysAttrib "System.Runtime.CompilerServices.DecimalConstantAttribute"
14931494
member val attribs_Unsupported = v_attribs_Unsupported
14941495

14951496
member val attrib_ProjectionParameterAttribute = mk_MFCore_attrib "ProjectionParameterAttribute"

Diff for: src/Compiler/TypedTree/TcGlobals.fsi

+2
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ type internal TcGlobals =
474474

475475
member attrib_SkipLocalsInitAttribute: BuiltinAttribInfo
476476

477+
member attrib_DecimalConstantAttribute: BuiltinAttribInfo
478+
477479
member attrib_StructAttribute: BuiltinAttribInfo
478480

479481
member attrib_StructLayoutAttribute: BuiltinAttribInfo

Diff for: src/Compiler/TypedTree/TypedTreeOps.fs

+14-12
Original file line numberDiff line numberDiff line change
@@ -10014,7 +10014,7 @@ let EvalArithUnOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt3
1001410014
| _ -> error (Error ( FSComp.SR.tastNotAConstantExpression(), m))
1001510015
with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m))
1001610016

10017-
let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt32, opUInt64, opSingle, opDouble) (arg1: Expr) (arg2: Expr) =
10017+
let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt32, opUInt64, opSingle, opDouble, opDecimal) (arg1: Expr) (arg2: Expr) =
1001810018
// At compile-time we check arithmetic
1001910019
let m = unionRanges arg1.Range arg2.Range
1002010020
try
@@ -10029,6 +10029,7 @@ let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt
1002910029
| Expr.Const (Const.UInt64 x1, _, ty), Expr.Const (Const.UInt64 x2, _, _) -> Expr.Const (Const.UInt64 (opUInt64 x1 x2), m, ty)
1003010030
| Expr.Const (Const.Single x1, _, ty), Expr.Const (Const.Single x2, _, _) -> Expr.Const (Const.Single (opSingle x1 x2), m, ty)
1003110031
| Expr.Const (Const.Double x1, _, ty), Expr.Const (Const.Double x2, _, _) -> Expr.Const (Const.Double (opDouble x1 x2), m, ty)
10032+
| Expr.Const (Const.Decimal x1, _, ty), Expr.Const (Const.Decimal x2, _, _) -> Expr.Const (Const.Decimal (opDecimal x1 x2), m, ty)
1003210033
| _ -> error (Error ( FSComp.SR.tastNotAConstantExpression(), m))
1003310034
with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m))
1003410035

@@ -10060,9 +10061,10 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1006010061
| Const.Single _
1006110062
| Const.Char _
1006210063
| Const.Zero
10063-
| Const.String _ ->
10064+
| Const.String _
10065+
| Const.Decimal _ ->
1006410066
x
10065-
| Const.Decimal _ | Const.IntPtr _ | Const.UIntPtr _ | Const.Unit ->
10067+
| Const.IntPtr _ | Const.UIntPtr _ | Const.Unit ->
1006610068
errorR (Error ( FSComp.SR.tastNotAConstantExpression(), m))
1006710069
x
1006810070

@@ -10078,7 +10080,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1007810080

1007910081
match v1 with
1008010082
| IntegerConstExpr ->
10081-
EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||), ignore2, ignore2) v1 (EvalAttribArgExpr suppressLangFeatureCheck g arg2)
10083+
EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||), ignore2, ignore2, ignore2) v1 (EvalAttribArgExpr suppressLangFeatureCheck g arg2)
1008210084
| _ ->
1008310085
errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range))
1008410086
x
@@ -10093,7 +10095,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1009310095
Expr.Const (Const.Char (x1 + x2), m, ty)
1009410096
| _ ->
1009510097
checkFeature()
10096-
EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) v1 v2
10098+
EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) v1 v2
1009710099
| SpecificBinopExpr g g.unchecked_subtraction_vref (arg1, arg2) ->
1009810100
checkFeature()
1009910101
let v1, v2 = EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1, EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2
@@ -10102,16 +10104,16 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1010210104
| Expr.Const (Const.Char x1, m, ty), Expr.Const (Const.Char x2, _, _) ->
1010310105
Expr.Const (Const.Char (x1 - x2), m, ty)
1010410106
| _ ->
10105-
EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) v1 v2
10107+
EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) v1 v2
1010610108
| SpecificBinopExpr g g.unchecked_multiply_vref (arg1, arg2) ->
1010710109
checkFeature()
10108-
EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
10110+
EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
1010910111
| SpecificBinopExpr g g.unchecked_division_vref (arg1, arg2) ->
1011010112
checkFeature()
10111-
EvalArithBinOp ((/), (/), (/), (/), (/), (/), (/), (/), (/), (/)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
10113+
EvalArithBinOp ((/), (/), (/), (/), (/), (/), (/), (/), (/), (/), (/)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
1011210114
| SpecificBinopExpr g g.unchecked_modulus_vref (arg1, arg2) ->
1011310115
checkFeature()
10114-
EvalArithBinOp ((%), (%), (%), (%), (%), (%), (%), (%), (%), (%)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
10116+
EvalArithBinOp ((%), (%), (%), (%), (%), (%), (%), (%), (%), (%), (%)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
1011510117
| SpecificBinopExpr g g.bitwise_shift_left_vref (arg1, arg2) ->
1011610118
checkFeature()
1011710119
EvalArithShiftOp ((<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
@@ -10124,7 +10126,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1012410126

1012510127
match v1 with
1012610128
| IntegerConstExpr ->
10127-
EvalArithBinOp ((&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
10129+
EvalArithBinOp ((&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), ignore2, ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
1012810130
| _ ->
1012910131
errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range))
1013010132
x
@@ -10134,7 +10136,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1013410136

1013510137
match v1 with
1013610138
| IntegerConstExpr ->
10137-
EvalArithBinOp ((^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
10139+
EvalArithBinOp ((^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), (^^^), ignore2, ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
1013810140
| _ ->
1013910141
errorR (Error (FSComp.SR.tastNotAConstantExpression(), x.Range))
1014010142
x
@@ -10144,7 +10146,7 @@ let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) =
1014410146

1014510147
match v1 with
1014610148
| FloatConstExpr ->
10147-
EvalArithBinOp (ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ( ** ), ( ** )) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
10149+
EvalArithBinOp (ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ignore2, ( ** ), ( ** ), ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2)
1014810150
| _ ->
1014910151
errorR (Error (FSComp.SR.tastNotAConstantExpression(), x.Range))
1015010152
x

Diff for: tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/Basic.fs

+7-8
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,12 @@ module LetBindings_Basic =
144144
|> verifyCompile
145145
|> shouldFail
146146
|> withDiagnostics [
147-
(Error 267, Line 11, Col 18, Line 11, Col 19, "This is not a valid constant expression or custom attribute value")
148-
(Error 837, Line 11, Col 13, Line 11, Col 31, "This is not a valid constant expression")
149-
(Error 267, Line 14, Col 13, Line 14, Col 17, "This is not a valid constant expression or custom attribute value")
150-
(Error 267, Line 17, Col 13, Line 17, Col 15, "This is not a valid constant expression or custom attribute value")
151-
(Error 267, Line 20, Col 13, Line 20, Col 17, "This is not a valid constant expression or custom attribute value")
152-
(Error 267, Line 23, Col 13, Line 23, Col 18, "This is not a valid constant expression or custom attribute value")
153-
(Warning 3178, Line 26, Col 13, Line 26, Col 26, "This is not valid literal expression. The [<Literal>] attribute will be ignored.")
147+
(Error 267, Line 10, Col 18, Line 10, Col 19, "This is not a valid constant expression or custom attribute value")
148+
(Error 837, Line 10, Col 13, Line 10, Col 31, "This is not a valid constant expression")
149+
(Error 267, Line 16, Col 13, Line 16, Col 15, "This is not a valid constant expression or custom attribute value")
150+
(Error 267, Line 19, Col 13, Line 19, Col 17, "This is not a valid constant expression or custom attribute value")
151+
(Error 267, Line 22, Col 13, Line 22, Col 18, "This is not a valid constant expression or custom attribute value")
152+
(Warning 3178, Line 25, Col 13, Line 25, Col 26, "This is not valid literal expression. The [<Literal>] attribute will be ignored.")
154153
]
155154

156155
// SOURCE=E_Pathological01.fs SCFLAGS=--test:ErrorRanges # E_Pathological01.fs
@@ -303,4 +302,4 @@ type C() =
303302
|> withDiagnostics [
304303
(Warning 3582, Line 4, Col 5, Line 4, Col 12, "This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses.")
305304
(Warning 3582, Line 5, Col 5, Line 5, Col 11, "This is a function definition that shadows a union case. If this is what you want, ignore or suppress this warning. If you want it to be a union case deconstruction, add parentheses.")
306-
]
305+
]

Diff for: tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/LetBindings/Basic/E_Literals04.fs

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
// #Regression #Conformance #DeclarationElements #LetBindings
2-
//<Expects status="error" span="(11,18)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
3-
//<Expects status="error" span="(11,13)" id="FS0837">This is not a valid constant expression$</Expects>
4-
//<Expects status="error" span="(14,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
5-
//<Expects status="error" span="(17,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
6-
//<Expects status="error" span="(20,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
7-
//<Expects status="error" span="(23,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
8-
//<Expects status="warning" span="(26,13)" id="FS3178">This is not valid literal expression. The \[<Literal>\] attribute will be ignored\.$</Expects>
2+
//<Expects status="error" span="(10,18)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
3+
//<Expects status="error" span="(10,13)" id="FS0837">This is not a valid constant expression$</Expects>
4+
//<Expects status="error" span="(16,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
5+
//<Expects status="error" span="(19,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
6+
//<Expects status="error" span="(22,13)" id="FS0267">This is not a valid constant expression or custom attribute value$</Expects>
7+
//<Expects status="warning" span="(25,13)" id="FS3178">This is not valid literal expression. The \[<Literal>\] attribute will be ignored\.$</Expects>
98

109
[<Literal>]
1110
let lit01 = (let x = "2" in x)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace Conformance.PatternMatching
4+
5+
open Xunit
6+
open FSharp.Test
7+
open FSharp.Test.Compiler
8+
9+
module Decimal =
10+
11+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"literal01.fs"|])>]
12+
let ``Decimal - literal01.fs - --test:ErrorRanges`` compilation =
13+
compilation
14+
|> asFsx
15+
|> withOptions ["--test:ErrorRanges";]
16+
|> compile
17+
|> shouldSucceed
18+
19+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes = [|"incompleteMatchesLiteral01.fs"|])>]
20+
let ``Decimal - incompleteMatchesLiteral01.fs - --test:ErrorRanges`` compilation =
21+
compilation
22+
|> asFs
23+
|> withOptions ["--test:ErrorRanges"]
24+
|> typecheck
25+
|> shouldFail
26+
|> withSingleDiagnostic (Warning 25, Line 7, Col 11, Line 7, Col 13, "Incomplete pattern matches on this expression. For example, the value '3' may indicate a case not covered by the pattern(s).")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[<Literal>]
2+
let One = 1m
3+
[<Literal>]
4+
let Two = 2m
5+
6+
let test() =
7+
match 3m with
8+
| 0m -> false
9+
| One | Two -> false
10+
11+
exit 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// #Conformance #PatternMatching
2+
#light
3+
4+
// Pattern match decimal literals
5+
6+
[<Literal>]
7+
let Decimal1 = 5m
8+
9+
[<Literal>]
10+
let Decimal2 = 42.42m
11+
12+
let testDecimal x =
13+
match x with
14+
| Decimal1 -> 1
15+
| Decimal2 -> 2
16+
| _ -> 0
17+
18+
if testDecimal 1m <> 0 then exit 1
19+
20+
if testDecimal Decimal1 <> 1 then exit 1
21+
if testDecimal 5m <> 1 then exit 1
22+
23+
if testDecimal Decimal2 <> 2 then exit 1
24+
if testDecimal 42.42m <> 2 then exit 1
25+
26+
exit 0

0 commit comments

Comments
 (0)