diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
index 093ff46d163..c4dca3879ee 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
@@ -3,3 +3,7 @@
* Allow `let!` and `use!` type annotations without requiring parentheses ([PR #18508](https://github.com/dotnet/fsharp/pull/18508))
* Fix find all references for F# exceptions ([PR #18565](https://github.com/dotnet/fsharp/pull/18565))
* Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560))
+
+### Added
+
+* Add support for `when 'T : Enum` library-only library-only static optimization constraint. ([PR #18546](https://github.com/dotnet/fsharp/pull/18546))
diff --git a/docs/release-notes/.FSharp.Core/10.0.100.md b/docs/release-notes/.FSharp.Core/10.0.100.md
index 1dc471ef118..c065515762c 100644
--- a/docs/release-notes/.FSharp.Core/10.0.100.md
+++ b/docs/release-notes/.FSharp.Core/10.0.100.md
@@ -5,5 +5,7 @@
### Changed
* Random functions support for zero element chosen/sampled ([PR #18568](https://github.com/dotnet/fsharp/pull/18568))
+* Enable more `string` optimizations by adding `when 'T : Enum` library-only library-only static optimization constraint. ([PR #18546](https://github.com/dotnet/fsharp/pull/18546))
+
+### Breaking Changes
-### Breaking Changes
\ No newline at end of file
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index 93dd8905553..8f82eebc078 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -1278,6 +1278,8 @@ type TcGlobals(
member val ArrayCollector_tcr = mk_MFCompilerServices_tcref fslibCcu "ArrayCollector`1"
+ member val SupportsWhenTEnum_tcr = mk_MFCompilerServices_tcref fslibCcu "SupportsWhenTEnum"
+
member _.TryEmbedILType(tref: ILTypeRef, mkEmbeddableType: unit -> ILTypeDef) =
if tref.Scope = ILScopeRef.Local && not(embeddedILTypeDefs.ContainsKey(tref.Name)) then
embeddedILTypeDefs.TryAdd(tref.Name, mkEmbeddableType()) |> ignore
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index b8c3610ef91..f7a3ca11e0c 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -276,6 +276,8 @@ type internal TcGlobals =
member ListCollector_tcr: FSharp.Compiler.TypedTree.EntityRef
+ member SupportsWhenTEnum_tcr: FSharp.Compiler.TypedTree.EntityRef
+
member MatchFailureException_tcr: FSharp.Compiler.TypedTree.EntityRef
member ResumableCode_tcr: FSharp.Compiler.TypedTree.EntityRef
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index a1258657e78..b14dbd753b1 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -5801,11 +5801,23 @@ type StaticOptimizationAnswer =
// ^T : ^T --> used in (+), (-) etc. to guard witness-invoking implementations added in F# 5
// 'T : 'T --> used in FastGenericEqualityComparer, FastGenericComparer to guard struct/tuple implementations
//
+// For performance and compatibility reasons, 'T when 'T is an enum is handled with its own special hack.
+// Unlike for other 'T : tycon constraints, 'T can be any enum; it need not (and indeed must not) be identical to System.Enum itself.
+// 'T : Enum
+//
+// In order to add this hack in a backwards-compatible way, we must hide this capability behind a marker type
+// which we use solely as an indicator of whether the compiler understands `when 'T : Enum`.
+// 'T : SupportsWhenTEnum
+//
// canDecideTyparEqn is set to true in IlxGen when the witness-invoking implementation can be used.
let decideStaticOptimizationConstraint g c canDecideTyparEqn =
match c with
| TTyconEqualsTycon (a, b) when canDecideTyparEqn && typeEquiv g a b && isTyparTy g a ->
- StaticOptimizationAnswer.Yes
+ StaticOptimizationAnswer.Yes
+ | TTyconEqualsTycon (_, b) when tryTcrefOfAppTy g b |> ValueOption.exists (tyconRefEq g g.SupportsWhenTEnum_tcr) ->
+ StaticOptimizationAnswer.Yes
+ | TTyconEqualsTycon (a, b) when isEnumTy g a && not (typeEquiv g a g.system_Enum_ty) && typeEquiv g b g.system_Enum_ty ->
+ StaticOptimizationAnswer.Yes
| TTyconEqualsTycon (a, b) ->
// Both types must be nominal for a definite result
let rec checkTypes a b =
@@ -5815,7 +5827,7 @@ let decideStaticOptimizationConstraint g c canDecideTyparEqn =
let b = normalizeEnumTy g (stripTyEqnsAndMeasureEqns g b)
match b with
| AppTy g (tcref2, _) ->
- if tyconRefEq g tcref1 tcref2 then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No
+ if tyconRefEq g tcref1 tcref2 && not (typeEquiv g a g.system_Enum_ty) then StaticOptimizationAnswer.Yes else StaticOptimizationAnswer.No
| RefTupleTy g _ | FunTy g _ -> StaticOptimizationAnswer.No
| _ -> StaticOptimizationAnswer.Unknown
diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs
index d9a7e41bf55..0fb2b87a06d 100644
--- a/src/FSharp.Core/prim-types.fs
+++ b/src/FSharp.Core/prim-types.fs
@@ -391,6 +391,20 @@ namespace Microsoft.FSharp.Core
type TailCallAttribute() =
inherit System.Attribute()
+namespace Microsoft.FSharp.Core.CompilerServices
+
+ open System.ComponentModel
+ open Microsoft.FSharp.Core
+
+ ///
+ /// A marker type that only compilers that support the when 'T : Enum
+ /// library-only static optimization constraint will recognize.
+ ///
+ []
+ []
+ []
+ type SupportsWhenTEnum = class end
+
#if !NET5_0_OR_GREATER
namespace System.Diagnostics.CodeAnalysis
@@ -5149,11 +5163,10 @@ namespace Microsoft.FSharp.Core
when ^T : decimal = (# "conv.i" (int64 (# "" value : decimal #)) : unativeint #)
when ^T : ^T = (^T : (static member op_Explicit: ^T -> nativeint) (value))
- []
- let inline string (value: 'T) =
- anyToString "" value
+ let inline defaultString (value : 'T) =
+ anyToString "" value
- when 'T : string =
+ when 'T : string =
if value = unsafeDefault<'T> then ""
else (# "" value : string #) // force no-op
@@ -5170,10 +5183,9 @@ namespace Microsoft.FSharp.Core
when 'T : nativeint = let x = (# "" value : nativeint #) in x.ToString()
when 'T : unativeint = let x = (# "" value : unativeint #) in x.ToString()
- // Integral types can be enum:
- // It is not possible to distinguish statically between Enum and (any type of) int. For signed types we have
- // to use IFormattable::ToString, as the minus sign can be overridden. Using boxing we'll print their symbolic
- // value if it's an enum, e.g.: 'ConsoleKey.Backspace' gives "Backspace", rather than "8")
+ // These rules for signed integer types will no longer be used when built with a compiler version that
+ // supports `when 'T : Enum`, but we must keep them to remain compatible with compiler versions that do not.
+ // Once all compiler versions that do not understand `when 'T : Enum` are out of support, these four rules can be removed.
when 'T : sbyte = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture)
when 'T : int16 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture)
when 'T : int32 = (box value :?> IFormattable).ToString(null, CultureInfo.InvariantCulture)
@@ -5186,7 +5198,6 @@ namespace Microsoft.FSharp.Core
when 'T : uint32 = let x = (# "" value : 'T #) in x.ToString()
when 'T : uint64 = let x = (# "" value : 'T #) in x.ToString()
-
// other common mscorlib System struct types
when 'T : DateTime = let x = (# "" value : DateTime #) in x.ToString(null, CultureInfo.InvariantCulture)
when 'T : DateTimeOffset = let x = (# "" value : DateTimeOffset #) in x.ToString(null, CultureInfo.InvariantCulture)
@@ -5206,6 +5217,38 @@ namespace Microsoft.FSharp.Core
if value = unsafeDefault<'T> then ""
else let x = (# "" value : IFormattable #) in defaultIfNull "" (x.ToString(null, CultureInfo.InvariantCulture))
+ []
+ let inline string (value: 'T) =
+ defaultString value
+
+ // Only compilers that understand `when 'T : SupportsWhenTEnum` will understand `when 'T : Enum`.
+ when 'T : CompilerServices.SupportsWhenTEnum =
+ (
+ let inline string (value : 'T) =
+ defaultString value
+
+ // Special handling is required for enums, since:
+ //
+ // - The runtime value may be outside the defined members of the enum.
+ // - Their underlying type may be a signed integral type.
+ // - The negative sign may be overridden.
+ //
+ // For example:
+ //
+ // string DayOfWeek.Wednesday → "Wednesday"
+ // string (enum -3) → "-3" // The negative sign is culture-dependent.
+ // string (enum -3) → "⁒3" // E.g., the negative sign for the current culture could be overridden to "⁒".
+ when 'T : Enum = let x = (# "" value : 'T #) in x.ToString() // Use 'T to constrain the call to the specific enum type.
+
+ // For compilers that understand `when 'T : Enum`, we can safely make a constrained call on the integral type itself here.
+ when 'T : sbyte = let x = (# "" value : sbyte #) in x.ToString(null, CultureInfo.InvariantCulture)
+ when 'T : int16 = let x = (# "" value : int16 #) in x.ToString(null, CultureInfo.InvariantCulture)
+ when 'T : int32 = let x = (# "" value : int32 #) in x.ToString(null, CultureInfo.InvariantCulture)
+ when 'T : int64 = let x = (# "" value : int64 #) in x.ToString(null, CultureInfo.InvariantCulture)
+
+ string value
+ )
+
[]
[]
let inline char (value: ^T) =
diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi
index 7c2f171a600..6697e108d2c 100644
--- a/src/FSharp.Core/prim-types.fsi
+++ b/src/FSharp.Core/prim-types.fsi
@@ -994,6 +994,20 @@ namespace Microsoft.FSharp.Core
inherit System.Attribute
new : unit -> TailCallAttribute
+namespace Microsoft.FSharp.Core.CompilerServices
+
+ open System.ComponentModel
+ open Microsoft.FSharp.Core
+
+ ///
+ /// A marker type that only compilers that support the when 'T : Enum
+ /// library-only static optimization constraint will recognize.
+ ///
+ []
+ []
+ []
+ type SupportsWhenTEnum = class end
+
namespace System.Diagnostics.CodeAnalysis
open System
@@ -4772,7 +4786,7 @@ namespace Microsoft.FSharp.Core
/// Converts the argument to a string using ToString.
///
- /// For standard integer and floating point values and any type that implements IFormattable
+ /// For standard integer and floating point values and any type that implements IFormattable,
/// ToString conversion uses CultureInfo.InvariantCulture.
/// The input value.
///
diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1
index 50a8a9e6422..f0aece70cd3 100644
--- a/tests/AheadOfTime/Trimming/check.ps1
+++ b/tests/AheadOfTime/Trimming/check.ps1
@@ -46,4 +46,4 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) {
CheckTrim -root "SelfContained_Trimming_Test" -tfm "net9.0" -outputfile "FSharp.Core.dll" -expected_len 300032
# Check net8.0 trimmed assemblies
-CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net9.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 9150976
+CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net9.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 9154048
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl
index fbb185005e8..63458b70509 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.net472.bsl
@@ -662,8 +662,9 @@
class MyTestModule/MyDu/JustInt V_2,
int32 V_3,
int32 V_4,
- class MyTestModule/MyDu/MaybeString V_5,
- string V_6)
+ int32 V_5,
+ class MyTestModule/MyDu/MaybeString V_6,
+ string V_7)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloc.0
@@ -677,7 +678,7 @@
IL_000f: ldloc.1
IL_0010: isinst MyTestModule/MyDu/MaybeString
- IL_0015: brtrue.s IL_0048
+ IL_0015: brtrue.s IL_0040
IL_0017: br.s IL_001b
@@ -696,23 +697,22 @@
IL_002b: ldloc.3
IL_002c: stloc.s V_4
IL_002e: ldloc.s V_4
- IL_0030: box [runtime]System.Int32
- IL_0035: unbox.any [runtime]System.IFormattable
- IL_003a: ldnull
- IL_003b: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
- IL_0040: tail.
- IL_0042: callvirt instance string [netstandard]System.IFormattable::ToString(string,
- class [netstandard]System.IFormatProvider)
- IL_0047: ret
-
- IL_0048: ldloc.0
- IL_0049: castclass MyTestModule/MyDu/MaybeString
- IL_004e: stloc.s V_5
- IL_0050: ldloc.s V_5
- IL_0052: ldfld string MyTestModule/MyDu/MaybeString::_nullableString
- IL_0057: stloc.s V_6
- IL_0059: ldloc.s V_6
- IL_005b: ret
+ IL_0030: stloc.s V_5
+ IL_0032: ldloca.s V_5
+ IL_0034: ldnull
+ IL_0035: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_003a: call instance string [netstandard]System.Int32::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_003f: ret
+
+ IL_0040: ldloc.0
+ IL_0041: castclass MyTestModule/MyDu/MaybeString
+ IL_0046: stloc.s V_6
+ IL_0048: ldloc.s V_6
+ IL_004a: ldfld string MyTestModule/MyDu/MaybeString::_nullableString
+ IL_004f: stloc.s V_7
+ IL_0051: ldloc.s V_7
+ IL_0053: ret
}
}
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl
index 44ee6d4e2c8..423360aff64 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Nullness/ReferenceDU.fs.il.netcore.bsl
@@ -662,8 +662,9 @@
class MyTestModule/MyDu/JustInt V_2,
int32 V_3,
int32 V_4,
- class MyTestModule/MyDu/MaybeString V_5,
- string V_6)
+ int32 V_5,
+ class MyTestModule/MyDu/MaybeString V_6,
+ string V_7)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldloc.0
@@ -677,7 +678,7 @@
IL_000f: ldloc.1
IL_0010: isinst MyTestModule/MyDu/MaybeString
- IL_0015: brtrue.s IL_0048
+ IL_0015: brtrue.s IL_0040
IL_0017: br.s IL_001b
@@ -696,23 +697,22 @@
IL_002b: ldloc.3
IL_002c: stloc.s V_4
IL_002e: ldloc.s V_4
- IL_0030: box [runtime]System.Int32
- IL_0035: unbox.any [runtime]System.IFormattable
- IL_003a: ldnull
- IL_003b: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
- IL_0040: tail.
- IL_0042: callvirt instance string [netstandard]System.IFormattable::ToString(string,
- class [netstandard]System.IFormatProvider)
- IL_0047: ret
-
- IL_0048: ldloc.0
- IL_0049: castclass MyTestModule/MyDu/MaybeString
- IL_004e: stloc.s V_5
- IL_0050: ldloc.s V_5
- IL_0052: ldfld string MyTestModule/MyDu/MaybeString::_nullableString
- IL_0057: stloc.s V_6
- IL_0059: ldloc.s V_6
- IL_005b: ret
+ IL_0030: stloc.s V_5
+ IL_0032: ldloca.s V_5
+ IL_0034: ldnull
+ IL_0035: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_003a: call instance string [netstandard]System.Int32::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_003f: ret
+
+ IL_0040: ldloc.0
+ IL_0041: castclass MyTestModule/MyDu/MaybeString
+ IL_0046: stloc.s V_6
+ IL_0048: ldloc.s V_6
+ IL_004a: ldfld string MyTestModule/MyDu/MaybeString::_nullableString
+ IL_004f: stloc.s V_7
+ IL_0051: ldloc.s V_7
+ IL_0053: ret
}
}
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/StaticOptimizations.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/StaticOptimizations.fs
new file mode 100644
index 00000000000..d1099c27c20
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/StaticOptimizations.fs
@@ -0,0 +1,26 @@
+namespace EmittedIL
+
+open FSharp.Test
+open FSharp.Test.Compiler
+open Xunit
+
+module StaticOptimizations =
+ let verifyCompilation compilation =
+ compilation
+ |> asExe
+ |> withEmbeddedPdb
+ |> withEmbedAllSource
+ |> ignoreWarnings
+ |> verifyILBaseline
+
+ []
+ let String_Enum_fs compilation =
+ compilation
+ |> getCompilation
+ |> verifyCompilation
+
+ []
+ let String_SignedIntegralTypes_fs compilation =
+ compilation
+ |> getCompilation
+ |> verifyCompilation
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_Enum.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_Enum.fs
new file mode 100644
index 00000000000..ca952d71132
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_Enum.fs
@@ -0,0 +1,32 @@
+open System
+
+module String =
+ type CharEnum = Char = 'a'
+ type SByteEnum = SByte = 1y
+ type Int16Enum = Int16 = 1s
+ type Int32Enum = Int32 = 1
+ type Int64Enum = Int64 = 1L
+
+ type ByteEnum = Byte = 1uy
+ type UInt16Enum = UInt16 = 1us
+ type UInt32Enum = UInt32 = 1u
+ type UInt64Enum = UInt64 = 1UL
+
+ let ``string`` (enum : CharEnum) = string enum
+ let ``string`` (enum : SByteEnum) = string enum
+ let ``string`` (enum : Int16Enum) = string enum
+ let ``string`` (enum : Int32Enum) = string enum
+ let ``string`` (enum : Int64Enum) = string enum
+
+ let ``string`` (enum : ByteEnum) = string enum
+ let ``string`` (enum : UInt16Enum) = string enum
+ let ``string`` (enum : UInt32Enum) = string enum
+ let ``string`` (enum : UInt64Enum) = string enum
+
+ let ``string<#Enum>`` (enum : #Enum) = string enum
+ let ``string<'T :> Enum>`` (enum : 'T :> Enum) = string enum
+
+ let ``string<'T when 'T : enum<'U>>`` (enum : 'T when 'T : enum<'U>) = string enum
+ let ``string<'T when 'T : enum>`` (enum : 'T when 'T : enum) = string enum
+
+ let ``string Unchecked.defaultof`` () = string Unchecked.defaultof
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_Enum.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_Enum.fs.il.bsl
new file mode 100644
index 00000000000..740505ce6a7
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_Enum.fs.il.bsl
@@ -0,0 +1,543 @@
+
+
+
+
+
+.assembly extern runtime { }
+.assembly extern FSharp.Core { }
+.assembly extern netstandard
+{
+ .publickeytoken = (CC 7B 13 FF CD 2D DD 51 )
+ .ver 2:1:0:0
+}
+.assembly assembly
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32,
+ int32,
+ int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 )
+
+
+
+
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module assembly.exe
+
+.imagebase {value}
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+
+
+
+
+.class public abstract auto ansi sealed assembly
+ extends [runtime]System.Object
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .class abstract auto ansi sealed nested public String
+ extends [runtime]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .class auto ansi serializable sealed nested public CharEnum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname char value__
+ .field public static literal valuetype assembly/String/CharEnum Char = char(0x0061)
+ }
+
+ .class auto ansi serializable sealed nested public SByteEnum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname int8 value__
+ .field public static literal valuetype assembly/String/SByteEnum SByte = int8(0x01)
+ }
+
+ .class auto ansi serializable sealed nested public Int16Enum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname int16 value__
+ .field public static literal valuetype assembly/String/Int16Enum Int16 = int16(0x0001)
+ }
+
+ .class auto ansi serializable sealed nested public Int32Enum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname int32 value__
+ .field public static literal valuetype assembly/String/Int32Enum Int32 = int32(0x00000001)
+ }
+
+ .class auto ansi serializable sealed nested public Int64Enum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname int64 value__
+ .field public static literal valuetype assembly/String/Int64Enum Int64 = int64(0x1)
+ }
+
+ .class auto ansi serializable sealed nested public ByteEnum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname uint8 value__
+ .field public static literal valuetype assembly/String/ByteEnum Byte = uint8(0x01)
+ }
+
+ .class auto ansi serializable sealed nested public UInt16Enum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname uint16 value__
+ .field public static literal valuetype assembly/String/UInt16Enum UInt16 = uint16(0x0001)
+ }
+
+ .class auto ansi serializable sealed nested public UInt32Enum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname uint32 value__
+ .field public static literal valuetype assembly/String/UInt32Enum UInt32 = uint32(0x00000001)
+ }
+
+ .class auto ansi serializable sealed nested public UInt64Enum
+ extends [runtime]System.Enum
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 )
+ .field public specialname rtspecialname uint64 value__
+ .field public static literal valuetype assembly/String/UInt64Enum UInt64 = uint64(0x1)
+ }
+
+ .method public static string 'string'(valuetype assembly/String/CharEnum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/CharEnum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/CharEnum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/SByteEnum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/SByteEnum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/SByteEnum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/Int16Enum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/Int16Enum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/Int16Enum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/Int32Enum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/Int32Enum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/Int32Enum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/Int64Enum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/Int64Enum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/Int64Enum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/ByteEnum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/ByteEnum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/ByteEnum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/UInt16Enum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/UInt16Enum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/UInt16Enum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/UInt32Enum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/UInt32Enum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/UInt32Enum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string'(valuetype assembly/String/UInt64Enum 'enum') cil managed
+ {
+
+ .maxstack 3
+ .locals init (valuetype assembly/String/UInt64Enum V_0)
+ IL_0000: ldarg.0
+ IL_0001: stloc.0
+ IL_0002: ldloca.s V_0
+ IL_0004: constrained. assembly/String/UInt64Enum
+ IL_000a: callvirt instance string [netstandard]System.Object::ToString()
+ IL_000f: ret
+ }
+
+ .method public static string 'string<#Enum>'<([runtime]System.Enum) a>(!!a 'enum') cil managed
+ {
+
+ .maxstack 5
+ .locals init (object V_0,
+ class [runtime]System.IFormattable V_1,
+ string V_2,
+ !!a V_3)
+ IL_0000: ldarg.0
+ IL_0001: box !!a
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: isinst [runtime]System.IFormattable
+ IL_000d: brtrue.s IL_0014
+
+ IL_000f: ldloc.0
+ IL_0010: brfalse.s IL_0033
+
+ IL_0012: br.s IL_0039
+
+ IL_0014: ldloc.0
+ IL_0015: unbox.any [runtime]System.IFormattable
+ IL_001a: stloc.1
+ IL_001b: ldloc.1
+ IL_001c: ldnull
+ IL_001d: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0022: callvirt instance string [netstandard]System.IFormattable::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_0027: stloc.2
+ IL_0028: ldloc.2
+ IL_0029: brtrue.s IL_0031
+
+ IL_002b: ldstr ""
+ IL_0030: ret
+
+ IL_0031: ldloc.2
+ IL_0032: ret
+
+ IL_0033: ldstr ""
+ IL_0038: ret
+
+ IL_0039: ldarg.0
+ IL_003a: stloc.3
+ IL_003b: ldloca.s V_3
+ IL_003d: constrained. !!a
+ IL_0043: callvirt instance string [netstandard]System.Object::ToString()
+ IL_0048: stloc.2
+ IL_0049: ldloc.2
+ IL_004a: brtrue.s IL_0052
+
+ IL_004c: ldstr ""
+ IL_0051: ret
+
+ IL_0052: ldloc.2
+ IL_0053: ret
+ }
+
+ .method public static string 'string<\'T :> Enum>'<([runtime]System.Enum) T>(!!T 'enum') cil managed
+ {
+
+ .maxstack 5
+ .locals init (object V_0,
+ class [runtime]System.IFormattable V_1,
+ string V_2,
+ !!T V_3)
+ IL_0000: ldarg.0
+ IL_0001: box !!T
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: isinst [runtime]System.IFormattable
+ IL_000d: brtrue.s IL_0014
+
+ IL_000f: ldloc.0
+ IL_0010: brfalse.s IL_0033
+
+ IL_0012: br.s IL_0039
+
+ IL_0014: ldloc.0
+ IL_0015: unbox.any [runtime]System.IFormattable
+ IL_001a: stloc.1
+ IL_001b: ldloc.1
+ IL_001c: ldnull
+ IL_001d: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0022: callvirt instance string [netstandard]System.IFormattable::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_0027: stloc.2
+ IL_0028: ldloc.2
+ IL_0029: brtrue.s IL_0031
+
+ IL_002b: ldstr ""
+ IL_0030: ret
+
+ IL_0031: ldloc.2
+ IL_0032: ret
+
+ IL_0033: ldstr ""
+ IL_0038: ret
+
+ IL_0039: ldarg.0
+ IL_003a: stloc.3
+ IL_003b: ldloca.s V_3
+ IL_003d: constrained. !!T
+ IL_0043: callvirt instance string [netstandard]System.Object::ToString()
+ IL_0048: stloc.2
+ IL_0049: ldloc.2
+ IL_004a: brtrue.s IL_0052
+
+ IL_004c: ldstr ""
+ IL_0051: ret
+
+ IL_0052: ldloc.2
+ IL_0053: ret
+ }
+
+ .method public static string 'string<\'T when \'T : enum<\'U>>'(!!T 'enum') cil managed
+ {
+
+ .maxstack 5
+ .locals init (object V_0,
+ class [runtime]System.IFormattable V_1,
+ string V_2,
+ !!T V_3)
+ IL_0000: ldarg.0
+ IL_0001: box !!T
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: isinst [runtime]System.IFormattable
+ IL_000d: brtrue.s IL_0014
+
+ IL_000f: ldloc.0
+ IL_0010: brfalse.s IL_0033
+
+ IL_0012: br.s IL_0039
+
+ IL_0014: ldloc.0
+ IL_0015: unbox.any [runtime]System.IFormattable
+ IL_001a: stloc.1
+ IL_001b: ldloc.1
+ IL_001c: ldnull
+ IL_001d: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0022: callvirt instance string [netstandard]System.IFormattable::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_0027: stloc.2
+ IL_0028: ldloc.2
+ IL_0029: brtrue.s IL_0031
+
+ IL_002b: ldstr ""
+ IL_0030: ret
+
+ IL_0031: ldloc.2
+ IL_0032: ret
+
+ IL_0033: ldstr ""
+ IL_0038: ret
+
+ IL_0039: ldarg.0
+ IL_003a: stloc.3
+ IL_003b: ldloca.s V_3
+ IL_003d: constrained. !!T
+ IL_0043: callvirt instance string [netstandard]System.Object::ToString()
+ IL_0048: stloc.2
+ IL_0049: ldloc.2
+ IL_004a: brtrue.s IL_0052
+
+ IL_004c: ldstr ""
+ IL_0051: ret
+
+ IL_0052: ldloc.2
+ IL_0053: ret
+ }
+
+ .method public static string 'string<\'T when \'T : enum>'(!!T 'enum') cil managed
+ {
+
+ .maxstack 5
+ .locals init (object V_0,
+ class [runtime]System.IFormattable V_1,
+ string V_2,
+ !!T V_3)
+ IL_0000: ldarg.0
+ IL_0001: box !!T
+ IL_0006: stloc.0
+ IL_0007: ldloc.0
+ IL_0008: isinst [runtime]System.IFormattable
+ IL_000d: brtrue.s IL_0014
+
+ IL_000f: ldloc.0
+ IL_0010: brfalse.s IL_0033
+
+ IL_0012: br.s IL_0039
+
+ IL_0014: ldloc.0
+ IL_0015: unbox.any [runtime]System.IFormattable
+ IL_001a: stloc.1
+ IL_001b: ldloc.1
+ IL_001c: ldnull
+ IL_001d: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0022: callvirt instance string [netstandard]System.IFormattable::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_0027: stloc.2
+ IL_0028: ldloc.2
+ IL_0029: brtrue.s IL_0031
+
+ IL_002b: ldstr ""
+ IL_0030: ret
+
+ IL_0031: ldloc.2
+ IL_0032: ret
+
+ IL_0033: ldstr ""
+ IL_0038: ret
+
+ IL_0039: ldarg.0
+ IL_003a: stloc.3
+ IL_003b: ldloca.s V_3
+ IL_003d: constrained. !!T
+ IL_0043: callvirt instance string [netstandard]System.Object::ToString()
+ IL_0048: stloc.2
+ IL_0049: ldloc.2
+ IL_004a: brtrue.s IL_0052
+
+ IL_004c: ldstr ""
+ IL_0051: ret
+
+ IL_0052: ldloc.2
+ IL_0053: ret
+ }
+
+ .method public static string 'string Unchecked.defaultof'() cil managed
+ {
+
+ .maxstack 5
+ .locals init (class [runtime]System.Enum V_0,
+ object V_1,
+ class [runtime]System.IFormattable V_2,
+ string V_3,
+ class [runtime]System.Enum V_4)
+ IL_0000: ldnull
+ IL_0001: stloc.0
+ IL_0002: ldloc.0
+ IL_0003: box [runtime]System.Enum
+ IL_0008: stloc.1
+ IL_0009: ldloc.1
+ IL_000a: isinst [runtime]System.IFormattable
+ IL_000f: brtrue.s IL_0016
+
+ IL_0011: ldloc.1
+ IL_0012: brfalse.s IL_0035
+
+ IL_0014: br.s IL_003b
+
+ IL_0016: ldloc.1
+ IL_0017: unbox.any [runtime]System.IFormattable
+ IL_001c: stloc.2
+ IL_001d: ldloc.2
+ IL_001e: ldnull
+ IL_001f: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0024: callvirt instance string [netstandard]System.IFormattable::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_0029: stloc.3
+ IL_002a: ldloc.3
+ IL_002b: brtrue.s IL_0033
+
+ IL_002d: ldstr ""
+ IL_0032: ret
+
+ IL_0033: ldloc.3
+ IL_0034: ret
+
+ IL_0035: ldstr ""
+ IL_003a: ret
+
+ IL_003b: ldloc.0
+ IL_003c: stloc.s V_4
+ IL_003e: ldloca.s V_4
+ IL_0040: constrained. [runtime]System.Enum
+ IL_0046: callvirt instance string [netstandard]System.Object::ToString()
+ IL_004b: stloc.3
+ IL_004c: ldloc.3
+ IL_004d: brtrue.s IL_0055
+
+ IL_004f: ldstr ""
+ IL_0054: ret
+
+ IL_0055: ldloc.3
+ IL_0056: ret
+ }
+
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$assembly
+ extends [runtime]System.Object
+{
+ .method public static void main@() cil managed
+ {
+ .entrypoint
+
+ .maxstack 8
+ IL_0000: ret
+ }
+
+}
+
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_SignedIntegralTypes.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_SignedIntegralTypes.fs
new file mode 100644
index 00000000000..984bc4a99f2
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_SignedIntegralTypes.fs
@@ -0,0 +1,7 @@
+open System
+
+module String =
+ let ``string sbyte`` (value : sbyte) = string value
+ let ``string int16`` (value : int16) = string value
+ let ``string int32`` (value : int32) = string value
+ let ``string int64`` (value : int64) = string value
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_SignedIntegralTypes.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_SignedIntegralTypes.fs.il.bsl
new file mode 100644
index 00000000000..c1470054a4d
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/StaticOptimizations/String_SignedIntegralTypes.fs.il.bsl
@@ -0,0 +1,114 @@
+
+
+
+
+
+.assembly extern runtime { }
+.assembly extern FSharp.Core { }
+.assembly extern netstandard
+{
+ .publickeytoken = (CC 7B 13 FF CD 2D DD 51 )
+ .ver 2:1:0:0
+}
+.assembly assembly
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32,
+ int32,
+ int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 )
+
+
+
+
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module assembly.exe
+
+.imagebase {value}
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+
+
+
+
+.class public abstract auto ansi sealed assembly
+ extends [runtime]System.Object
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .class abstract auto ansi sealed nested public String
+ extends [runtime]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .method public static string 'string sbyte'(int8 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarga.s 'value'
+ IL_0002: ldnull
+ IL_0003: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0008: call instance string [netstandard]System.SByte::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_000d: ret
+ }
+
+ .method public static string 'string int16'(int16 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarga.s 'value'
+ IL_0002: ldnull
+ IL_0003: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0008: call instance string [netstandard]System.Int16::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_000d: ret
+ }
+
+ .method public static string 'string int32'(int32 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarga.s 'value'
+ IL_0002: ldnull
+ IL_0003: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0008: call instance string [netstandard]System.Int32::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_000d: ret
+ }
+
+ .method public static string 'string int64'(int64 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarga.s 'value'
+ IL_0002: ldnull
+ IL_0003: call class [netstandard]System.Globalization.CultureInfo [netstandard]System.Globalization.CultureInfo::get_InvariantCulture()
+ IL_0008: call instance string [netstandard]System.Int64::ToString(string,
+ class [netstandard]System.IFormatProvider)
+ IL_000d: ret
+ }
+
+ }
+
+}
+
+.class private abstract auto ansi sealed ''.$assembly
+ extends [runtime]System.Object
+{
+ .method public static void main@() cil managed
+ {
+ .entrypoint
+
+ .maxstack 8
+ IL_0000: ret
+ }
+
+}
+
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 36754f92217..221e00be9b8 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -185,6 +185,7 @@
+
diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
index 3e0ea652746..358c155a3a8 100644
--- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
+++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
@@ -33,6 +33,11 @@ type TestFs0670Error<'T> =
// See: https://github.com/dotnet/fsharp/issues/7958
Operators.string x
+type CultureWithDifferentNegativeSign () as this =
+ inherit CultureInfo ""
+ do this.NumberFormat.NegativeSign <- "🙃"
+ override _.DisplayName = nameof CultureWithDifferentNegativeSign
+
type OperatorsModule2() =
[]
@@ -833,7 +838,6 @@ type OperatorsModule2() =
[]
member _.string() =
-
let result = Operators.string null
Assert.AreEqual("", result)
@@ -884,32 +888,36 @@ type OperatorsModule2() =
Assert.AreEqual("", result)
// Following tests ensure that InvariantCulture is used if type implements IFormattable
-
- // safe current culture, then switch culture
- let currentCI = Thread.CurrentThread.CurrentCulture
- Thread.CurrentThread.CurrentCulture <- CultureInfo.GetCultureInfo("de-DE")
- // make sure the culture switch happened, and verify
- let wrongResult = 123.456M.ToString()
- Assert.AreEqual("123,456", wrongResult)
+ let runWithCulture culture f =
+ let currentCulture = Thread.CurrentThread.CurrentCulture
+ Thread.CurrentThread.CurrentCulture <- culture
+ try f () finally Thread.CurrentThread.CurrentCulture <- currentCulture
- // test that culture has no influence on decimals with `string`
- let correctResult = Operators.string 123.456M
- Assert.AreEqual("123.456", correctResult)
+ let numbersAndDates () =
+ // make sure the culture switch happened, and verify
+ let wrongResult = 123.456M.ToString()
+ Assert.AreEqual("123,456", wrongResult)
- // make sure that the German culture is indeed selected for DateTime
- let dttm = DateTime(2020, 6, 23)
- let wrongResult = dttm.ToString()
- Assert.AreEqual("23.06.2020 00:00:00", wrongResult)
+ // test that culture has no influence on decimals with `string`
+ let correctResult = Operators.string 123.456M
+ Assert.AreEqual("123.456", correctResult)
- // test that culture has no influence on DateTime types when used with `string`
- let correctResult = Operators.string dttm
- Assert.AreEqual("06/23/2020 00:00:00", correctResult)
+ // make sure that the German culture is indeed selected for DateTime
+ let dttm = DateTime(2020, 6, 23)
+ let wrongResult = dttm.ToString()
+ Assert.AreEqual("23.06.2020 00:00:00", wrongResult)
- // reset the culture
- Thread.CurrentThread.CurrentCulture <- currentCI
+ // test that culture has no influence on DateTime types when used with `string`
+ let correctResult = Operators.string dttm
+ Assert.AreEqual("06/23/2020 00:00:00", correctResult)
+ let enums () =
+ Assert.AreEqual("Wednesday", Operators.string DayOfWeek.Wednesday)
+ Assert.AreEqual($"%s{Thread.CurrentThread.CurrentCulture.NumberFormat.NegativeSign}1", Operators.string (enum -1))
+ numbersAndDates |> runWithCulture (CultureInfo.GetCultureInfo "de-DE")
+ enums |> runWithCulture (CultureWithDifferentNegativeSign ())
[]
member _.``string: don't raise FS0670 anymore``() =
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
index 897dd2ac22a..74547d9fef8 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_net9.0.bsl
@@ -21,14 +21,14 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x00000082][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3494-805::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3494-811::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack.
[IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@106::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
[IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::getCompilerOption([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)][offset 0x000000E6][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::AddPathMapping([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, string)][offset 0x0000000B][found Char] Unexpected type on the stack.
@@ -54,7 +54,7 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILPdbWriter+PortablePdbGenerator::serializeDocumentName(string)][offset 0x00000090][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILPdbWriter+pushShadowedLocals@959::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000232][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::seekReadUntaggedIdx([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.BinaryConstants+TableName, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+ILMetadataReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, int32&)][offset 0x0000000D][found Byte] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x00000799][found Boolean] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x000007A3][found Boolean] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+rowKindSize@4445::Invoke([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+RowKind)][offset 0x00000128][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x00000021][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 5475f43bdc1..8771cafafc0 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -28,18 +28,18 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CodeAnalysis.Hosted.CompilerHelpers::fscCompile([FSharp.Compiler.Service]FSharp.Compiler.CodeAnalysis.LegacyReferenceResolver, string, string[])][offset 0x0000008B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiStdinSyphon::GetLine(string, int32)][offset 0x00000039][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+MagicAssemblyResolution::ResolveAssemblyCore([FSharp.Compiler.Service]Internal.Utilities.Library.CompilationThreadToken, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, [FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, [FSharp.Compiler.Service]FSharp.Compiler.CompilerImports+TcImports, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompiler, [FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiConsoleOutput, string)][offset 0x00000015][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3494-805::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+clo@3494-811::Invoke([S.P.CoreLib]System.Tuple`3)][offset 0x000001E5][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Interactive.Shell+FsiInteractionProcessor::CompletionsForPartialLID([FSharp.Compiler.Service]FSharp.Compiler.Interactive.Shell+FsiDynamicCompilerState, string)][offset 0x0000001B][found Char] Unexpected type on the stack.
[IL]: Error [UnmanagedPointer]: : FSharp.Compiler.Interactive.Shell+Utilities+pointerToNativeInt@106::Invoke(object)][offset 0x00000007] Unmanaged pointers are not a verifiable type.
[IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x00000059][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000DA][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1431-6::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000605][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-515::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2496-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000011][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack.
@@ -74,7 +74,7 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILPdbWriter+PortablePdbGenerator::serializeDocumentName(string)][offset 0x00000090][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILPdbWriter+pushShadowedLocals@959::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000232][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::seekReadUntaggedIdx([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.BinaryConstants+TableName, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+ILMetadataReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, int32&)][offset 0x0000000D][found Byte] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x00000799][found Boolean] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x000007A3][found Boolean] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+rowKindSize@4445::Invoke([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+RowKind)][offset 0x00000128][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.NativeRes+VersionHelper::TryParse(string, bool, uint16, bool, [S.P.CoreLib]System.Version&)][offset 0x0000003D][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.IL::parseILVersion(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
index 9821dc3dc1a..5ec5ff6c37f 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_net9.0.bsl
@@ -75,7 +75,7 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::seekReadNestedRowUncached([FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1>, int32)][offset 0x00000058][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::seekReadGenericParamConstraintIdx([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+ILMetadataReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, int32)][offset 0x00000025][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::rowKindSize$cont@4446(bool, bool, bool, bool[], bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x000000E5][found Byte] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x000006BF][found Boolean] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x000006B6][found Boolean] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+seekReadInterfaceImpls@2263-3::Invoke(int32)][offset 0x0000002F][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+seekReadGenericParamConstraints@2328-2::Invoke(int32)][offset 0x0000002F][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+enclIdx@2357-2::Invoke(int32)][offset 0x0000002F][found Byte] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index 7a78ab1999a..a0d93965647 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -96,7 +96,7 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::seekReadNestedRowUncached([FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1>, int32)][offset 0x00000058][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::seekReadGenericParamConstraintIdx([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+ILMetadataReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, int32)][offset 0x00000025][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::rowKindSize$cont@4446(bool, bool, bool, bool[], bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x000000E5][found Byte] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x000006BF][found Boolean] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader::openMetadataReader(string, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+BinaryFile, int32, [S.P.CoreLib]System.Tuple`8,bool,bool,bool,bool,bool,System.Tuple`5,bool,int32,int32,int32>>, [FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.ILBinaryReader+PEReader, [FSharp.Compiler.Service]FSharp.Compiler.IO.ReadOnlyByteMemory, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1, bool)][offset 0x000006B6][found Boolean] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+seekReadInterfaceImpls@2263-3::Invoke(int32)][offset 0x0000002F][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+seekReadGenericParamConstraints@2328-2::Invoke(int32)][offset 0x0000002F][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.AbstractIL.ILBinaryReader+enclIdx@2357-2::Invoke(int32)][offset 0x0000002F][found Byte] Unexpected type on the stack.