From 079a4baa20382ce920aeb4f73b3284ba6eed3802 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Sun, 28 Jun 2020 09:47:18 +0200 Subject: [PATCH 01/11] Detect type equiv for System.Tuple`8 --- src/fsharp/ConstraintSolver.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 0469946c180..2d0d0ed1fb5 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -379,6 +379,8 @@ 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 +let IsEncodedTuple tupInfo g ty = tyconRefEq g ty (if evalTupInfoIsStruct tupInfo then g.struct_tuple8_tcr else g.ref_tuple8_tcr) + // Get measure of type, float<_> or float32<_> or decimal<_> but not float=float<1> or float32=float32<1> or decimal=decimal<1> let GetMeasureOfType g ty = match ty with @@ -1025,6 +1027,11 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr -> SolveTypeEqualsType csenv ndeep m2 trace None ms (TType_measure Measure.One) | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 + + // Catch System.Tuple<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TRest> arising from SRTP constructions + | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, a2::b2::c2::d2::e2::f2::g2::rest2) when IsEncodedTuple tupInfo g tc1 -> + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_tuple (tupInfo, rest2)] + | TType_app (_, _), TType_app (_, _) -> localAbortD | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else From ff58d27c9d3b03df2f45ff61372c2aae6050c2e7 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Sun, 28 Jun 2020 16:39:23 +0200 Subject: [PATCH 02/11] + check for tuple in binding --- src/fsharp/Optimizer.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 1c8e4928b0d..a05c583546f 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1596,7 +1596,8 @@ let ExpandStructuralBindingRaw cenv expr = assert cenv.settings.ExpandStructuralValues() match expr with | Expr.Let (TBind(v, rhs, tgtSeqPtOpt), body, m, _) - when (isRefTupleExpr rhs && + when (isAnyTupleTy cenv.g v.Type && + isRefTupleExpr rhs && CanExpandStructuralBinding v) -> let args = tryDestRefTupleExpr rhs if List.forall ExprIsValue args then From ab217cc18f6b9d07283f5efab960e85382e1abb1 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Sun, 28 Jun 2020 18:00:36 +0200 Subject: [PATCH 03/11] + test --- tests/fsharp/core/csext/test.fsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fsharp/core/csext/test.fsx b/tests/fsharp/core/csext/test.fsx index c77a7307642..6b18b2008bc 100644 --- a/tests/fsharp/core/csext/test.fsx +++ b/tests/fsharp/core/csext/test.fsx @@ -311,6 +311,8 @@ module TupleSRTP = let v1b = (^T : (member get_Item2 : unit -> _ ) (new System.Tuple(1,3))) let v2b = (^T : (member get_Item2 : unit -> _ ) (System.Tuple(1,3))) let v3b = (^T : (member get_Item2 : unit -> _ ) ((1,3))) + + let areEqual = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) (*--------------------*) From a3e1db1b001a947fc724963db13f7b58fe584ff8 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Sun, 28 Jun 2020 19:35:03 +0200 Subject: [PATCH 04/11] Handle cases with 1-uple --- src/fsharp/ConstraintSolver.fs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 2d0d0ed1fb5..b234ae11b6d 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1029,6 +1029,10 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 // Catch System.Tuple<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TRest> arising from SRTP constructions + | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, [a2;b2;c2;d2;e2;f2;g2;h2]) when IsEncodedTuple tupInfo g tc1 -> + match stripTyEqnsA csenv.g canShortcut rest1 with + | TType_app (_, [h1]) -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;h1] [a2;b2;c2;d2;e2;f2;g2;h2] + | _ -> localAbortD | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, a2::b2::c2::d2::e2::f2::g2::rest2) when IsEncodedTuple tupInfo g tc1 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_tuple (tupInfo, rest2)] From 6b44c767b3de97a8aa32c8ce7c559cb1006e0f82 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Sun, 28 Jun 2020 19:39:18 +0200 Subject: [PATCH 05/11] + test for tuple with 8 elements --- tests/fsharp/core/csext/test.fsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/fsharp/core/csext/test.fsx b/tests/fsharp/core/csext/test.fsx index 6b18b2008bc..78aec29c81c 100644 --- a/tests/fsharp/core/csext/test.fsx +++ b/tests/fsharp/core/csext/test.fsx @@ -312,7 +312,8 @@ module TupleSRTP = let v2b = (^T : (member get_Item2 : unit -> _ ) (System.Tuple(1,3))) let v3b = (^T : (member get_Item2 : unit -> _ ) ((1,3))) - let areEqual = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) + let areEqualT8 = System.Tuple<_,_,_,_,_,_,_> (1,2,3,4,5,6,7,System.Tuple<_,_>(8) ) = (1,2,3,4,5,6,7,8) + let areEqualT9 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) (*--------------------*) From 9696eea854b652a5d85bc422f5fd3d71228e7206 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Wed, 1 Jul 2020 20:31:59 +0200 Subject: [PATCH 06/11] Fix test code --- tests/fsharp/core/csext/test.fsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/core/csext/test.fsx b/tests/fsharp/core/csext/test.fsx index 78aec29c81c..09b49414cc2 100644 --- a/tests/fsharp/core/csext/test.fsx +++ b/tests/fsharp/core/csext/test.fsx @@ -312,8 +312,8 @@ module TupleSRTP = let v2b = (^T : (member get_Item2 : unit -> _ ) (System.Tuple(1,3))) let v3b = (^T : (member get_Item2 : unit -> _ ) ((1,3))) - let areEqualT8 = System.Tuple<_,_,_,_,_,_,_> (1,2,3,4,5,6,7,System.Tuple<_,_>(8) ) = (1,2,3,4,5,6,7,8) - let areEqualT9 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) + let areEqualT8 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_> (8) ) = (1,2,3,4,5,6,7,8) + let areEqualT9 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) (*--------------------*) From c0c13eb7d6886726bd605aaca8a2c95dcb3d6ec9 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Fri, 24 Jul 2020 09:53:53 +0200 Subject: [PATCH 07/11] Construct left instead of deconstruct right --- src/fsharp/ConstraintSolver.fs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index b234ae11b6d..03e4626b6ea 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1028,11 +1028,9 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr | TType_app (tc1, l1), TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 - // Catch System.Tuple<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TRest> arising from SRTP constructions + // Catch System.Tuple<'T1,'T2,'T3,'T4,'T5,'T6,'T7,...> = 'T1*'T2*'T3*'T4*'T5*'T6*'T7*... | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, [a2;b2;c2;d2;e2;f2;g2;h2]) when IsEncodedTuple tupInfo g tc1 -> - match stripTyEqnsA csenv.g canShortcut rest1 with - | TType_app (_, [h1]) -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;h1] [a2;b2;c2;d2;e2;f2;g2;h2] - | _ -> localAbortD + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_app (if evalTupInfoIsStruct tupInfo then g.struct_tuple1_tcr else g.ref_tuple1_tcr, [h2])] | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, a2::b2::c2::d2::e2::f2::g2::rest2) when IsEncodedTuple tupInfo g tc1 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_tuple (tupInfo, rest2)] From f5d776e839031463bd302d31e09f8cc11a43e012 Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Fri, 24 Jul 2020 10:02:02 +0200 Subject: [PATCH 08/11] Fix previous commit --- 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 03e4626b6ea..6f35771a685 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1030,7 +1030,7 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr // Catch System.Tuple<'T1,'T2,'T3,'T4,'T5,'T6,'T7,...> = 'T1*'T2*'T3*'T4*'T5*'T6*'T7*... | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, [a2;b2;c2;d2;e2;f2;g2;h2]) when IsEncodedTuple tupInfo g tc1 -> - SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_app (if evalTupInfoIsStruct tupInfo then g.struct_tuple1_tcr else g.ref_tuple1_tcr, [h2])] + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_app ((if evalTupInfoIsStruct tupInfo then g.struct_tuple1_tcr else g.ref_tuple1_tcr), [h2])] | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, a2::b2::c2::d2::e2::f2::g2::rest2) when IsEncodedTuple tupInfo g tc1 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_tuple (tupInfo, rest2)] From 285bba5159c856c993c78950eff080070d2b6d6f Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Fri, 24 Jul 2020 20:00:35 +0200 Subject: [PATCH 09/11] + tests for #9639 --- tests/fsharp/core/csext/test.fsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/fsharp/core/csext/test.fsx b/tests/fsharp/core/csext/test.fsx index 09b49414cc2..676ff0b51be 100644 --- a/tests/fsharp/core/csext/test.fsx +++ b/tests/fsharp/core/csext/test.fsx @@ -314,6 +314,11 @@ module TupleSRTP = let areEqualT8 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_> (8) ) = (1,2,3,4,5,6,7,8) let areEqualT9 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) + + let c8 = System.Tuple>(1,2,3,4,5,6,7,System.Tuple(8)) + let c9 = System.Tuple>(1,2,3,4,5,6,7,System.Tuple(8,9)) + + (*--------------------*) From c61e3ad7f0b0eafa10c6a3e436fcda598aafd8cc Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Fri, 24 Jul 2020 20:20:06 +0200 Subject: [PATCH 10/11] + cases for the other way around --- src/fsharp/ConstraintSolver.fs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 6f35771a685..f29008486ba 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1033,6 +1033,10 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_app ((if evalTupInfoIsStruct tupInfo then g.struct_tuple1_tcr else g.ref_tuple1_tcr), [h2])] | TType_app (tc1, [a1;b1;c1;d1;e1;f1;g1;rest1]), TType_tuple (tupInfo, a2::b2::c2::d2::e2::f2::g2::rest2) when IsEncodedTuple tupInfo g tc1 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;rest1] [a2;b2;c2;d2;e2;f2;g2;TType_tuple (tupInfo, rest2)] + | TType_tuple (tupInfo, [a1;b1;c1;d1;e1;f1;g1;h1]), TType_app (tc2, [a2;b2;c2;d2;e2;f2;g2;rest2]) when IsEncodedTuple tupInfo g tc2 -> + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;TType_app ((if evalTupInfoIsStruct tupInfo then g.struct_tuple2_tcr else g.ref_tuple2_tcr), [h1])] [a2;b2;c2;d2;e2;f2;g2;rest2] + | TType_tuple (tupInfo, a1::b1::c1::d1::e1::f1::g1::rest1), TType_app (tc2, [a2;b2;c2;d2;e2;f2;g2;rest2]) when IsEncodedTuple tupInfo g tc2 -> + SolveTypeEqualsTypeEqns csenv ndeep m2 trace None [a1;b1;c1;d1;e1;f1;g1;TType_tuple (tupInfo, rest1)] [a2;b2;c2;d2;e2;f2;g2;rest2] | TType_app (_, _), TType_app (_, _) -> localAbortD | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> From 73f4f843ba3cdcd39ee60b22f95523721e2f21ff Mon Sep 17 00:00:00 2001 From: Gustavo Leon <1261319+gusty@users.noreply.github.com> Date: Fri, 24 Jul 2020 22:01:05 +0200 Subject: [PATCH 11/11] + test with mixed types --- tests/fsharp/core/csext/test.fsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fsharp/core/csext/test.fsx b/tests/fsharp/core/csext/test.fsx index 676ff0b51be..966437c90a1 100644 --- a/tests/fsharp/core/csext/test.fsx +++ b/tests/fsharp/core/csext/test.fsx @@ -315,6 +315,8 @@ module TupleSRTP = let areEqualT8 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_> (8) ) = (1,2,3,4,5,6,7,8) let areEqualT9 = System.Tuple<_,_,_,_,_,_,_,_>(1,2,3,4,5,6,7,System.Tuple<_,_>(8,9)) = (1,2,3,4,5,6,7,8,9) + let areEqualT9' = System.Tuple<_,_,_,_,_,_,_,(int * int)>(1,2,3,4,5,6,7,(8,9)) = (1,2,3,4,5,6,7,8,9) + let c8 = System.Tuple>(1,2,3,4,5,6,7,System.Tuple(8)) let c9 = System.Tuple>(1,2,3,4,5,6,7,System.Tuple(8,9))