diff --git a/src/FSharp.Core/quotations.fs b/src/FSharp.Core/quotations.fs index 0115811553a..338820c3f66 100644 --- a/src/FSharp.Core/quotations.fs +++ b/src/FSharp.Core/quotations.fs @@ -19,7 +19,6 @@ open Microsoft.FSharp.Text.StructuredPrintfImpl.Layout open Microsoft.FSharp.Text.StructuredPrintfImpl.TaggedText #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation - //-------------------------------------------------------------------------- // RAW quotations - basic data types //-------------------------------------------------------------------------- @@ -1101,6 +1100,10 @@ module Patterns = let ty = FSharpType.MakeStructTupleType(asm, Array.map typeOf (Array.ofList args)) mkFEN (NewTupleOp ty) args + let mkNewStructTupleNetStandard args = + let ty = FSharpType.MakeStructTupleType(Array.map typeOf (Array.ofList args)) + mkFEN (NewTupleOp ty) args + let mkTupleGet (ty, n, x) = checkTypesSR ty (typeOf x) "tupleGet" (SR.GetString(SR.QtmmExprNotMatchTuple)) let mems = FSharpType.GetTupleElements ty @@ -2586,6 +2589,9 @@ type Expr with static member NewStructTuple(asm: Assembly, elements) = mkNewStructTuple (asm, elements) + static member NewStructTuple elements = + mkNewStructTupleNetStandard elements + static member NewRecord(recordType: Type, elements) = checkNonNull "recordType" recordType mkNewRecord (recordType, elements) diff --git a/src/FSharp.Core/quotations.fsi b/src/FSharp.Core/quotations.fsi index 5ec624e1438..7b689671c18 100644 --- a/src/FSharp.Core/quotations.fsi +++ b/src/FSharp.Core/quotations.fsi @@ -673,6 +673,22 @@ type Expr = /// static member NewStructTuple: asm: Assembly * elements: Expr list -> Expr + /// Builds an expression that represents the creation of an F# tuple value + /// + /// The list of elements of the tuple. + /// + /// The resulting expression. + /// + /// + /// + /// open FSharp.Quotations + /// + /// Expr.NewStructTuple( [ <@ 1 @>; <@ "a" @> ]) + /// + /// Evaluates to a quotation with the same structure as <@ struct (1, "a") @>. + /// + static member NewStructTuple: elements: Expr list -> Expr + /// Builds record-construction expressions /// /// The type of record. diff --git a/src/FSharp.Core/reflect.fs b/src/FSharp.Core/reflect.fs index 6e0977e6edd..14726931473 100644 --- a/src/FSharp.Core/reflect.fs +++ b/src/FSharp.Core/reflect.fs @@ -628,27 +628,6 @@ module internal Impl = //----------------------------------------------------------------- // TUPLE DECOMPILATION - let tupleNames = - [| - "System.Tuple`1" - "System.Tuple`2" - "System.Tuple`3" - "System.Tuple`4" - "System.Tuple`5" - "System.Tuple`6" - "System.Tuple`7" - "System.Tuple`8" - "System.Tuple" - "System.ValueTuple`1" - "System.ValueTuple`2" - "System.ValueTuple`3" - "System.ValueTuple`4" - "System.ValueTuple`5" - "System.ValueTuple`6" - "System.ValueTuple`7" - "System.ValueTuple`8" - "System.ValueTuple" - |] let simpleTupleNames = [| @@ -679,69 +658,137 @@ module internal Impl = // used in F# type providers. typ.IsGenericType && typ.Namespace = "System" - && simpleTupleNames |> Seq.exists typ.Name.StartsWith + && simpleTupleNames |> Array.exists typ.Name.StartsWith let maxTuple = 8 // Which field holds the nested tuple? let tupleEncField = maxTuple - 1 - let dictionaryLock = obj () - let refTupleTypes = Dictionary() - let valueTupleTypes = Dictionary() - - let rec mkTupleType isStruct (asm: Assembly) (tys: Type[]) = - let table = - let makeIt n = - let tupleFullName n = - let structOffset = if isStruct then 9 else 0 - let index = n - 1 + structOffset - tupleNames.[index] - - match n with - | 1 -> asm.GetType(tupleFullName 1) - | 2 -> asm.GetType(tupleFullName 2) - | 3 -> asm.GetType(tupleFullName 3) - | 4 -> asm.GetType(tupleFullName 4) - | 5 -> asm.GetType(tupleFullName 5) - | 6 -> asm.GetType(tupleFullName 6) - | 7 -> asm.GetType(tupleFullName 7) - | 8 -> asm.GetType(tupleFullName 8) - | _ -> invalidArg "tys" (SR.GetString(SR.invalidTupleTypes)) - - let tables = - if isStruct then - valueTupleTypes - else - refTupleTypes - - match lock dictionaryLock (fun () -> tables.TryGetValue asm) with - | false, _ -> - // the Dictionary<>s here could be ConcurrentDictionary<>'s, but then - // that would lock while initializing the Type array (maybe not an issue) - let mutable a = Array.init 8 (fun i -> makeIt (i + 1)) - - lock dictionaryLock (fun () -> - match tables.TryGetValue asm with - | true, t -> a <- t - | false, _ -> tables.Add(asm, a)) - - a - | true, t -> t - - match tys.Length with - | 1 -> table.[0].MakeGenericType tys - | 2 -> table.[1].MakeGenericType tys - | 3 -> table.[2].MakeGenericType tys - | 4 -> table.[3].MakeGenericType tys - | 5 -> table.[4].MakeGenericType tys - | 6 -> table.[5].MakeGenericType tys - | 7 -> table.[6].MakeGenericType tys - | n when n >= maxTuple -> - let tysA = tys.[0 .. tupleEncField - 1] - let tysB = tys.[maxTuple - 1 ..] - let tyB = mkTupleType isStruct asm tysB - table.[7].MakeGenericType(Array.append tysA [| tyB |]) - | _ -> invalidArg "tys" (SR.GetString(SR.invalidTupleTypes)) + module internal TupleFromSpecifiedAssembly = + let private tupleNames = + [| + "System.Tuple`1" + "System.Tuple`2" + "System.Tuple`3" + "System.Tuple`4" + "System.Tuple`5" + "System.Tuple`6" + "System.Tuple`7" + "System.Tuple`8" + "System.Tuple" + "System.ValueTuple`1" + "System.ValueTuple`2" + "System.ValueTuple`3" + "System.ValueTuple`4" + "System.ValueTuple`5" + "System.ValueTuple`6" + "System.ValueTuple`7" + "System.ValueTuple`8" + "System.ValueTuple" + |] + + let private dictionaryLock = obj () + let private refTupleTypes = Dictionary() + let private valueTupleTypes = Dictionary() + + let rec mkTupleType isStruct (asm: Assembly) (tys: Type[]) = + let table = + let makeIt n = + let tupleFullName n = + let structOffset = if isStruct then 9 else 0 + let index = n - 1 + structOffset + tupleNames.[index] + + match n with + | 1 -> asm.GetType(tupleFullName 1) + | 2 -> asm.GetType(tupleFullName 2) + | 3 -> asm.GetType(tupleFullName 3) + | 4 -> asm.GetType(tupleFullName 4) + | 5 -> asm.GetType(tupleFullName 5) + | 6 -> asm.GetType(tupleFullName 6) + | 7 -> asm.GetType(tupleFullName 7) + | 8 -> asm.GetType(tupleFullName 8) + | _ -> invalidArg "tys" (SR.GetString(SR.invalidTupleTypes)) + + let tables = + if isStruct then + valueTupleTypes + else + refTupleTypes + + match lock dictionaryLock (fun () -> tables.TryGetValue asm) with + | false, _ -> + // the Dictionary<>s here could be ConcurrentDictionary<>'s, but then + // that would lock while initializing the Type array (maybe not an issue) + let mutable a = Array.init 8 (fun i -> makeIt (i + 1)) + + lock dictionaryLock (fun () -> + match tables.TryGetValue asm with + | true, t -> a <- t + | false, _ -> tables.Add(asm, a)) + + a + | true, t -> t + + match tys.Length with + | 1 -> table.[0].MakeGenericType tys + | 2 -> table.[1].MakeGenericType tys + | 3 -> table.[2].MakeGenericType tys + | 4 -> table.[3].MakeGenericType tys + | 5 -> table.[4].MakeGenericType tys + | 6 -> table.[5].MakeGenericType tys + | 7 -> table.[6].MakeGenericType tys + | n when n >= maxTuple -> + let tysA = tys.[0 .. tupleEncField - 1] + let tysB = tys.[maxTuple - 1 ..] + let tyB = mkTupleType isStruct asm tysB + table.[7].MakeGenericType(Array.append tysA [| tyB |]) + | _ -> invalidArg "tys" (SR.GetString(SR.invalidTupleTypes)) + + let refTupleTypesNetStandard = + [| + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + |] + + let structTupleTypesNetStandard = + [| + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + typedefof> + |] + + /// Index of the recursively-nested Tuple type within the table of types + [] + let nestedTupIndex = 7 + + /// Index of the last regular (non-nested) tuple type within the table of types + [] + let lastRegularTupIndex = 6 //nestedTupIndex - 1 (wait for arithmetic in constants) + + let rec mkTupleTypeNetStandard (tupTyTbl: Type[]) (tys: Type[]) = + let tblIdx = tys.Length - 1 + assert (tblIdx >= 0) + assert (nestedTupIndex = tupTyTbl.Length - 1) + + match tblIdx with + | idx when idx < nestedTupIndex -> tupTyTbl[ idx ].MakeGenericType tys + | _ -> + let tysA = tys.[0..lastRegularTupIndex] + let tysB = tys.[nestedTupIndex..] + let tyB = mkTupleTypeNetStandard tupTyTbl tysB + tupTyTbl.[nestedTupIndex].MakeGenericType([| yield! tysA; yield tyB |]) let rec getTupleTypeInfo (typ: Type) = if not (isTupleType typ) then @@ -1111,18 +1158,13 @@ type FSharpType = static member MakeTupleType(types: Type[]) = checkNonNull "types" types - // No assembly passed therefore just get framework local version of Tuple - let asm = typeof.Assembly + if types.Length = 0 then + invalidArg "types" (SR.GetString(SR.invalidTupleTypes)) - if - types - |> Array.exists (function - | null -> true - | _ -> false) - then + if types |> Array.exists isNull then invalidArg "types" (SR.GetString(SR.nullsNotAllowedInArray)) - mkTupleType false asm types + mkTupleTypeNetStandard refTupleTypesNetStandard types static member MakeTupleType(asm: Assembly, types: Type[]) = checkNonNull "types" types @@ -1135,7 +1177,7 @@ type FSharpType = then invalidArg "types" (SR.GetString(SR.nullsNotAllowedInArray)) - mkTupleType false asm types + TupleFromSpecifiedAssembly.mkTupleType false asm types static member MakeStructTupleType(asm: Assembly, types: Type[]) = checkNonNull "types" types @@ -1148,7 +1190,18 @@ type FSharpType = then invalidArg "types" (SR.GetString(SR.nullsNotAllowedInArray)) - mkTupleType true asm types + TupleFromSpecifiedAssembly.mkTupleType true asm types + + static member MakeStructTupleType(types: Type[]) = + checkNonNull "types" types + + if types.Length = 0 then + invalidArg "types" (SR.GetString(SR.invalidTupleTypes)) + + if types |> Array.exists isNull then + invalidArg "types" (SR.GetString(SR.nullsNotAllowedInArray)) + + mkTupleTypeNetStandard structTupleTypesNetStandard types static member GetTupleElements(tupleType: Type) = checkTupleType ("tupleType", tupleType) diff --git a/src/FSharp.Core/reflect.fsi b/src/FSharp.Core/reflect.fsi index 881c95331c9..6f528195ae5 100644 --- a/src/FSharp.Core/reflect.fsi +++ b/src/FSharp.Core/reflect.fsi @@ -619,6 +619,15 @@ type FSharpType = /// static member MakeStructTupleType: asm: Assembly * types: Type[] -> Type + /// Returns a representing an F# struct tuple type with the given element types + /// + /// An array of types for the tuple elements. + /// + /// The type representing the struct tuple containing the input elements. + /// + /// + static member MakeStructTupleType: types: Type[] -> Type + /// Return true if the typ is a representation of an F# tuple type /// /// The type to check. diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl index b0ec5cbb925..7d0927147c0 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl @@ -2350,6 +2350,7 @@ Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr N Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) @@ -2467,6 +2468,7 @@ Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetReco Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl index bb1dd5db9d6..36b4f758dff 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl @@ -2349,6 +2349,7 @@ Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr N Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) @@ -2466,6 +2467,7 @@ Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetReco Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl index 028a4fee29b..fecb8627b97 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl @@ -2351,6 +2351,7 @@ Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr N Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) @@ -2468,6 +2469,7 @@ Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetReco Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl index 029951a590b..cd9e92fa8c6 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl @@ -2350,6 +2350,7 @@ Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr N Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewDelegate(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpVar], Microsoft.FSharp.Quotations.FSharpExpr) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewObject(System.Reflection.ConstructorInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewRecord(System.Type, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) +Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewStructTuple(System.Reflection.Assembly, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewTuple(Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) Microsoft.FSharp.Quotations.FSharpExpr: Microsoft.FSharp.Quotations.FSharpExpr NewUnionCase(Microsoft.FSharp.Reflection.UnionCaseInfo, Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]) @@ -2467,6 +2468,7 @@ Microsoft.FSharp.Reflection.FSharpType: System.Reflection.PropertyInfo[] GetReco Microsoft.FSharp.Reflection.FSharpType: System.Tuple`2[System.Type,System.Type] GetFunctionElements(System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeFunctionType(System.Type, System.Type) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Reflection.Assembly, System.Type[]) +Microsoft.FSharp.Reflection.FSharpType: System.Type MakeStructTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Reflection.Assembly, System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type MakeTupleType(System.Type[]) Microsoft.FSharp.Reflection.FSharpType: System.Type[] GetTupleElements(System.Type) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs index 02a3070d497..a8ea2816a73 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Quotations/FSharpQuotations.fs @@ -120,6 +120,20 @@ type FSharpQuotationsTests() = | NewTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () | _ -> Assert.Fail() + [] + member x.``NewStructTuple without assembly should be recognized by NewStructTuple active pattern`` () = + let expr = Expr.NewStructTuple([ <@@ 1 @@>; <@@ "" @@> ]) + match expr with + | NewStructTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () + | _ -> Assert.Fail() + + [] + member x.``NewStructTuple without assembly should be recognized by NewTuple active pattern`` () = + let expr = Expr.NewStructTuple([ <@@ 1 @@>; <@@ "" @@> ]) + match expr with + | NewTuple [ Value(:? int as i, _) ; Value(:? string as s, _) ] when i = 1 && s = "" -> () + | _ -> Assert.Fail() + [] member x.``NewTuple should not be recognized by NewStructTuple active pattern`` () = let expr = Expr.NewTuple [ <@@ 1 @@>; <@@ "" @@> ] diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs index ff1223b482a..987b779df17 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Reflection/FSharpReflection.fs @@ -1164,6 +1164,24 @@ type FSharpTypeTests() = // null CheckThrowsArgumentException(fun () ->FSharpType.MakeStructTupleType(asm, [|null;null|]) |> ignore ) + [] + member _.MakeStructTupleTypeNoAsm() = + // positive + Assert.AreEqual(FSharpType.MakeStructTupleType( [|typeof; typeof|]), typeof) + // positive for nested tuple + Assert.AreEqual(FSharpType.MakeStructTupleType( [|for i in 1..10 -> typeof|]), typeof) + // the representations above and below are equivalent, as tuple types are nested from 8th element on + Assert.AreEqual(FSharpType.MakeStructTupleType( [|for i in 1..10 -> typeof|]), typeof>>) + + + // negative + Assert.AreNotEqual(FSharpType.MakeStructTupleType( [|typeof; typeof|]), typeof) + + // invalid cases + CheckThrowsArgumentException(fun () ->FSharpType.MakeStructTupleType( [|null;null|]) |> ignore ) + CheckThrowsArgumentException(fun () ->FSharpType.MakeStructTupleType( null) |> ignore ) + CheckThrowsArgumentException(fun () ->FSharpType.MakeStructTupleType( [| |]) |> ignore ) + type UnionCaseInfoTests() = let singlenullarycaseunion = SingleNullaryCaseDiscUnion.SingleNullaryCaseTag diff --git a/tests/projects/SelfContained_Trimming_Test/check.ps1 b/tests/projects/SelfContained_Trimming_Test/check.ps1 index 388ed50ae7e..5269bd2b6f4 100644 --- a/tests/projects/SelfContained_Trimming_Test/check.ps1 +++ b/tests/projects/SelfContained_Trimming_Test/check.ps1 @@ -14,7 +14,7 @@ if (-not ($output -eq $expected)) } # Checking that FSharp.Core binary is of expected size (needs adjustments if test is updated). -$expected_len = 246272 # In bytes +$expected_len = 248320 # In bytes $file = Get-Item .\bin\Release\net7.0\win-x64\publish\FSharp.Core.dll $file_len = $file.Length if (-not ($file_len -eq $expected_len))