Skip to content

Commit f89e651

Browse files
Happypig375vzarytovskiidsyme
authored
Subtraction of two chars, new conversions, and fixes for dynamic operator invocations and QuotationToExpression (#11681)
Co-authored-by: Vlad Zarytovskii <[email protected]> Co-authored-by: Don Syme <[email protected]>
1 parent 0c1eba0 commit f89e651

File tree

18 files changed

+4288
-699
lines changed

18 files changed

+4288
-699
lines changed

src/Compiler/Checking/ConstraintSolver.fs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ let isFpTy g ty =
428428

429429
/// decimal or decimal<_>
430430
let isDecimalTy g ty =
431-
typeEquivAux EraseMeasures g g.decimal_ty ty
431+
typeEquivAux EraseMeasures g g.decimal_ty ty
432432

433433
let IsNonDecimalNumericOrIntegralEnumType g ty = IsIntegerOrIntegerEnumTy g ty || isFpTy g ty
434434

@@ -443,7 +443,7 @@ let IsRelationalType g ty = IsNumericType g ty || isStringTy g ty || isCharTy g
443443
let IsCharOrStringType g ty = isCharTy g ty || isStringTy g ty
444444

445445
/// Checks the argument type for a built-in solution to an op_Addition, op_Subtraction or op_Modulus constraint.
446-
let IsAddSubModType nm g ty = IsNumericOrIntegralEnumType g ty || (nm = "op_Addition" && IsCharOrStringType g ty)
446+
let IsAddSubModType nm g ty = IsNumericOrIntegralEnumType g ty || (nm = "op_Addition" && IsCharOrStringType g ty) || (nm = "op_Subtraction" && isCharTy g ty)
447447

448448
/// Checks the argument type for a built-in solution to a bitwise operator constraint
449449
let IsBitwiseOpType g ty = IsIntegerOrIntegerEnumTy g ty || (isEnumTy g ty)
@@ -1601,25 +1601,30 @@ and SolveMemberConstraint (csenv: ConstraintSolverEnv) ignoreUnresolvedOverload
16011601
do! SolveTypeEqualsTypeKeepAbbrevs csenv ndeep m2 trace retTy argTy
16021602
return TTraitBuiltIn
16031603

1604-
| _, _, false, "op_Explicit", [argTy]
1605-
when (// The input type.
1604+
// Conversions from non-decimal numbers / strings / chars to non-decimal numbers / chars are built-in
1605+
| _, _, false, "op_Explicit", [argTy]
1606+
when (// The input type.
16061607
(IsNonDecimalNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
16071608
// The output type
1608-
(IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy) &&
1609-
// Exclusion: IntPtr and UIntPtr do not support .Parse() from string
1610-
not (isStringTy g argTy && isNativeIntegerTy g retTy) &&
1611-
// Exclusion: No conversion from char to decimal
1612-
not (isCharTy g argTy && isDecimalTy g retTy)) ->
1609+
(IsNonDecimalNumericOrIntegralEnumType g retTy || isCharTy g retTy)) ->
16131610

16141611
return TTraitBuiltIn
16151612

1616-
1617-
| _, _, false, "op_Explicit", [argTy]
1618-
when (// The input type.
1619-
(IsNumericOrIntegralEnumType g argTy || isStringTy g argTy) &&
1613+
// Conversions from (including decimal) numbers / strings / chars to decimals are built-in
1614+
| _, _, false, "op_Explicit", [argTy]
1615+
when (// The input type.
1616+
(IsNumericOrIntegralEnumType g argTy || isStringTy g argTy || isCharTy g argTy) &&
16201617
// The output type
1621-
(isDecimalTy g retTy)) ->
1618+
(isDecimalTy g retTy)) ->
1619+
return TTraitBuiltIn
16221620

1621+
// Conversions from decimal numbers to native integers are built-in
1622+
// The rest of decimal conversions are handled via op_Explicit lookup on System.Decimal (which also looks for op_Implicit)
1623+
| _, _, false, "op_Explicit", [argTy]
1624+
when (// The input type.
1625+
(isDecimalTy g argTy) &&
1626+
// The output type
1627+
(isNativeIntegerTy g retTy)) ->
16231628
return TTraitBuiltIn
16241629

16251630
| [], _, false, "Pow", [argTy1; argTy2]

src/Compiler/TypedTree/TcGlobals.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1779,7 +1779,7 @@ type TcGlobals(
17791779
[ arg0Ty; arg1Ty ],
17801780
Some retTy ->
17811781
[vara; varb; varc], [ varaTy; varbTy ], varcTy, [ arg0Ty; arg1Ty; retTy ]
1782-
| ("UnaryNegationDynamic" | "CheckedUnaryNegationDynamic" | "LogicalNotDynamic" | "ExplicitDynamic"),
1782+
| ("UnaryNegationDynamic" | "CheckedUnaryNegationDynamic" | "LogicalNotDynamic" | "ExplicitDynamic" | "CheckedExplicitDynamic"),
17831783
[ arg0Ty ],
17841784
Some retTy ->
17851785
[vara; varb ], [ varaTy ], varbTy, [ arg0Ty; retTy ]

src/Compiler/pars.fsy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ namedModuleDefnBlock:
14931493
{ Choice1Of2 $1.LongIdent }
14941494

14951495

1496-
/* A module definition that inccludes a 'begin'...'end' (rarely used in F# with #light syntax) */
1496+
/* A module definition that includes a 'begin'...'end' (rarely used in F# with #light syntax) */
14971497
wrappedNamedModuleDefn:
14981498
| structOrBegin moduleDefnsOrExprPossiblyEmpty END
14991499
{ $2 }

src/FSharp.Core/Linq.fs

Lines changed: 342 additions & 146 deletions
Large diffs are not rendered by default.

src/FSharp.Core/Linq.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,4 @@ module LeafExpressionConverter =
8888
val SubstHelperRaw: Expr * Var[] * obj[] -> Expr
8989

9090
val internal (|SpecificCallToMethod|_|):
91-
System.RuntimeMethodHandle -> (Expr -> (Expr option * Type list * Expr list) option)
91+
System.RuntimeMethodHandle -> (Expr -> (Expr option * Reflection.MethodInfo * Expr list) option)

src/FSharp.Core/Query.fs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,26 +314,27 @@ module Query =
314314
match prop.GetGetMethod true with
315315
| null -> None
316316
| v -> Some v
317+
let (|GenericArgs|) (minfo: MethodInfo) = minfo.GetGenericArguments() |> Array.toList
317318

318319
// Match 'f x'
319320
let (|SpecificCall1|_|) q =
320321
let (|CallQ|_|) = (|SpecificCallToMethod|_|) q
321322
function
322-
| CallQ (Some builderObj, tyargs, [arg1]) -> Some(builderObj, tyargs, arg1)
323+
| CallQ (Some builderObj, GenericArgs tyargs, [arg1]) -> Some(builderObj, tyargs, arg1)
323324
| _ -> None
324325

325326
// Match 'f x y' or 'f (x, y)'
326327
let (|SpecificCall2|_|) q =
327328
let (|CallQ|_|) = (|SpecificCallToMethod|_|) q
328329
function
329-
| CallQ (Some builderObj, tyargs, [arg1; arg2]) -> Some(builderObj, tyargs, arg1, arg2)
330+
| CallQ (Some builderObj, GenericArgs tyargs, [arg1; arg2]) -> Some(builderObj, tyargs, arg1, arg2)
330331
| _ -> None
331332

332333
// Match 'f x y z' or 'f (x, y, z)'
333334
let (|SpecificCall3|_|) q =
334335
let (|CallQ|_|) = (|SpecificCallToMethod|_|) q
335336
function
336-
| CallQ (Some builderObj, tyargs, [arg1; arg2; arg3]) -> Some(builderObj, tyargs, arg1, arg2, arg3)
337+
| CallQ (Some builderObj, GenericArgs tyargs, [arg1; arg2; arg3]) -> Some(builderObj, tyargs, arg1, arg2, arg3)
337338
| _ -> None
338339

339340
/// (fun (x, y) -> z) is represented as 'fun p -> let x = p#0 let y = p#1' etc.
@@ -1286,7 +1287,7 @@ module Query =
12861287
// rewrite has had the custom operator translation mechanism applied. In this case, the
12871288
// body of the "for" will simply contain "yield".
12881289

1289-
| CallQueryBuilderFor (_, [_; qTy; immutResElemTy; _], [immutSource; Lambda(immutSelectorVar, immutSelector) ]) ->
1290+
| CallQueryBuilderFor (_, GenericArgs [_; qTy; immutResElemTy; _], [immutSource; Lambda(immutSelectorVar, immutSelector) ]) ->
12901291

12911292
let mutSource, sourceConv = TransInner CanEliminate.Yes check immutSource
12921293

@@ -1467,7 +1468,7 @@ module Query =
14671468
| _ -> GroupingConv (immutKeySelector.Type, immutElementSelector.Type, selectorConv)
14681469
TransInnerResult.Other(MakeGroupValBy(qTyIsIQueryable qTy, mutVar1.Type, mutKeySelector.Type, mutElementSelector.Type, mutSource, mutVar2, mutKeySelector, mutVar1, mutElementSelector)), conv
14691470

1470-
| CallJoin(_, [_; qTy; _; _; _],
1471+
| CallJoin(_, GenericArgs [_; qTy; _; _; _],
14711472
[ immutOuterSource
14721473
immutInnerSource
14731474
Lambda(immutOuterKeyVar, immutOuterKeySelector)
@@ -1491,7 +1492,7 @@ module Query =
14911492
TransInnerResult.Other joinExpr, elementSelectorConv
14921493

14931494
| CallGroupJoin
1494-
(_, [_; qTy; _; _; _],
1495+
(_, GenericArgs [_; qTy; _; _; _],
14951496
[ immutOuterSource
14961497
immutInnerSource
14971498
Lambda(immutOuterKeyVar, immutOuterKeySelector)
@@ -1517,7 +1518,7 @@ module Query =
15171518
TransInnerResult.Other joinExpr, elementSelectorConv
15181519

15191520
| CallLeftOuterJoin
1520-
(_, [ _; qTy; immutInnerSourceTy; _; _],
1521+
(_, GenericArgs [ _; qTy; immutInnerSourceTy; _; _],
15211522
[ immutOuterSource
15221523
immutInnerSource
15231524
Lambda(immutOuterKeyVar, immutOuterKeySelector)

0 commit comments

Comments
 (0)