Skip to content

Commit

Permalink
Merge pull request #10553 from KevinRansom/issue10505
Browse files Browse the repository at this point in the history
Fix issue 10505 --- `string` function returns null on `null` parameter of type `string`.
  • Loading branch information
KevinRansom authored Nov 30, 2020
2 parents 6947689 + 15ca0d0 commit b203948
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/fsharp/FSharp.Core/prim-types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4509,7 +4509,10 @@ namespace Microsoft.FSharp.Core
[<CompiledName("ToString")>]
let inline string (value: 'T) =
anyToString "" value
when 'T : string = (# "" value : string #) // force no-op

when 'T : string =
if value = unsafeDefault<'T> then ""
else (# "" value : string #) // force no-op

// Using 'let x = (# ... #) in x.ToString()' leads to better IL, without it, an extra stloc and ldloca.s (get address-of)
// gets emitted, which are unnecessary. With it, the extra address-of-variable is not created
Expand Down
14 changes: 14 additions & 0 deletions tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,20 @@ type OperatorsModule2() =

[<Fact>]
member _.string() =

let result = Operators.string null
Assert.AreEqual("", result)

let nullStr:string = null
let result = Operators.string nullStr
Assert.AreEqual("", result)

let result = Operators.string null
Assert.AreEqual("", result)

let result = Operators.string (null:string)
Assert.AreEqual("", result)

// value type
let result = Operators.string 100
Assert.AreEqual("100", result)
Expand Down
2 changes: 1 addition & 1 deletion tests/service/ExprTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2792,7 +2792,7 @@ let ``Test Operator Declarations for String`` () =
[], "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality<Microsoft.FSharp.Core.string> (e1,dflt) then dflt else e1.Replace(\"_\",\"\")),167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (53,47--53,55)"
[], "let testStringToDecimalOperator(e1) = Decimal.Parse (e1,167,CultureInfo.get_InvariantCulture () :> System.IFormatProvider) @ (54,47--54,57)"
[], "let testStringToCharOperator(e1) = Char.Parse (e1) @ (55,47--55,54)"
[FC47; FC50], "let testStringToStringOperator(e1) = e1 @ (56,54--56,56)"
[FC47; FC50], """let testStringToStringOperator(e1) = (if String.Equals (e1,dflt) then "" else e1) @ (56,47--56,56)"""
]

testOperators "String" "string" excludedTests expectedUnoptimized expectedOptimized
Expand Down

0 comments on commit b203948

Please sign in to comment.