From adf6bfd579f6c27a23f5c81fdf145ed6ecb201e8 Mon Sep 17 00:00:00 2001 From: KevinRansom Date: Thu, 26 Nov 2020 15:01:30 -0800 Subject: [PATCH 1/3] Fix issue 10505 --- `string` function returns null on `null` parameter of type `string`. --- src/fsharp/FSharp.Core/prim-types.fs | 5 ++++- .../FSharp.Core/OperatorsModule2.fs | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index 6f619b045b3..0aba6593b02 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -4509,7 +4509,10 @@ namespace Microsoft.FSharp.Core [] 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 diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs index e821b4b8835..3a7cc87778d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/OperatorsModule2.fs @@ -740,6 +740,20 @@ type OperatorsModule2() = [] 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) From 74c84aa06a12954d8db2933119d4e22ac2e7c6bd Mon Sep 17 00:00:00 2001 From: KevinRansom Date: Thu, 26 Nov 2020 16:40:03 -0800 Subject: [PATCH 2/3] Expr tests --- tests/service/ExprTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 05164371137..b669bf20331 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -2792,7 +2792,7 @@ let ``Test Operator Declarations for String`` () = [], "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality (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 From 15ca0d0de8323ed183ab9ca6c19abdd0b872d8c2 Mon Sep 17 00:00:00 2001 From: KevinRansom Date: Thu, 26 Nov 2020 20:55:21 -0800 Subject: [PATCH 3/3] typo --- tests/service/ExprTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index b669bf20331..5077986015a 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -2792,7 +2792,7 @@ let ``Test Operator Declarations for String`` () = [], "let testStringToDoubleOperator(e1) = Double.Parse ((if Operators.op_Equality (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) = (if String.Equals (e1,dflt) then "" else e1) @ (56,47--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