Skip to content

Commit 485c8dc

Browse files
committed
Add static optimizations for string, char, and bool
For culture-independent types (string, char, bool), bypass the `string` operator and call the appropriate TextWriter.Write/WriteLine overload directly. Numeric types (int, float, etc.) must still go through `string` to ensure InvariantCulture formatting, since TextWriter.Write(int/float) uses the writer's FormatProvider which is CurrentCulture for Console.Out. Add IL tests verifying char and bool use their direct overloads.
1 parent 0641484 commit 485c8dc

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

src/FSharp.Core/fslib-extra-pervasives.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,19 @@ module ExtraTopLevelOperators =
280280
[<CompiledName("PrintValue")>]
281281
let inline print (value: 'T) =
282282
Console.Out.Write(string value)
283+
// Culture-independent types can bypass 'string' and use TextWriter overloads directly.
284+
// Numeric types must go through 'string' to ensure InvariantCulture formatting,
285+
// since TextWriter.Write(int/float/...) uses the writer's FormatProvider (CurrentCulture).
286+
when 'T : string = Console.Out.Write((# "" value : string #))
287+
when 'T : char = Console.Out.Write((# "" value : char #))
288+
when 'T : bool = Console.Out.Write((# "" value : bool #))
283289

284290
[<CompiledName("PrintValueLine")>]
285291
let inline println (value: 'T) =
286292
Console.Out.WriteLine(string value)
293+
when 'T : string = Console.Out.WriteLine((# "" value : string #))
294+
when 'T : char = Console.Out.WriteLine((# "" value : char #))
295+
when 'T : bool = Console.Out.WriteLine((# "" value : bool #))
287296

288297
[<CompiledName("DefaultAsyncBuilder")>]
289298
let async = AsyncBuilder()

tests/FSharp.Compiler.ComponentTests/EmittedIL/PrintFunction.fs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ let printlnInt () = println 42
4040
"""callvirt instance void [netstandard]System.IO.TextWriter::WriteLine(string)"""]
4141

4242
[<Fact>]
43-
let ``print with string writes to Console Out``() =
43+
let ``print with string calls Write directly``() =
4444
FSharp """
4545
module PrintString
4646
@@ -53,6 +53,34 @@ let printStr () = print "hello"
5353
"""call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out()"""
5454
"""callvirt instance void [netstandard]System.IO.TextWriter::Write(string)"""]
5555

56+
[<Fact>]
57+
let ``print with char calls Write char overload``() =
58+
FSharp """
59+
module PrintChar
60+
61+
let printChar () = print 'A'
62+
"""
63+
|> withOptimize
64+
|> compile
65+
|> shouldSucceed
66+
|> verifyIL [
67+
"""call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out()"""
68+
"""callvirt instance void [netstandard]System.IO.TextWriter::Write(char)"""]
69+
70+
[<Fact>]
71+
let ``print with bool calls Write bool overload``() =
72+
FSharp """
73+
module PrintBool
74+
75+
let printBool () = print true
76+
"""
77+
|> withOptimize
78+
|> compile
79+
|> shouldSucceed
80+
|> verifyIL [
81+
"""call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out()"""
82+
"""callvirt instance void [netstandard]System.IO.TextWriter::Write(bool)"""]
83+
5684
[<Fact>]
5785
let ``println with float specializes to Double ToString with InvariantCulture``() =
5886
FSharp """

0 commit comments

Comments
 (0)