Closed Lanayx closed 2 days ago
Thanks for this.
Since string
handles even null literal itself, it will be better to change it to return not-null.
Before NRTs, it was not visible that some types are actually capable of returning null in their .ToString().
Funnily enough, I have used "string" to convert a potentially-nullable string to a non-nullable string many times myself when applying nullness to the codebase.
I would like to treat it as a bugfix or a historical overlook (of people being capable of returning null from ToString()), because FSharp.Core does not return surprising nulls elsewhere either.
cc @vzarytovskii
Ideally, the string
function's return type would take the nullness annotation of the actual resolved ToString
implementation into account.
If someone writes this in C#:
public class C
{
public override string ToString() => null!;
}
we should (and do) respect the annotation (string
instead of string?
) on the F# side and infer string
instead of string | null
when ToString
is called directly:
let s = C().ToString() // Inferred as string.
Likewise, if someone wrote this in F#:
type C () =
override _.ToString () : string = nonNull null
let s = string (C ())
we should respect the annotation and infer string
, not string | null
. We currently (as of RC1 anyway) don't even respect the annotation (of string
instead of string | null
) when directly calling ToString
:
let s = C().ToString() // Inferred as string | null.
But I guess that's basically asking for the equivalent of https://github.com/dotnet/roslyn/issues/23268 in F#.
Since this would mean for inlined fslib code having different return type depending on the type argument (and not just in T-type-algrebra, but by inspecting its method's metadata), I think we can skip the "ideally" part of the proposal :)
The second part should have been done as part of https://github.com/dotnet/fsharp/pull/17547/files and did not make it to RC1 . Also, from that PR on, having a null-returnign ToString on an F# type will lead to a warning.
Issue description
This started in https://github.com/dotnet/fsharp/issues/17730, where I initially though that
string null
would return null, but then was corrected. However later it was found out thatstring
function still can return null, so current signature is incorrect. There are 3 ways to fix it: 1) Just make return typestring | null
2) Make return typestring | null
and fix cases likestring null
so they return null as expected 3) Leave return type to bestring
, but add more null checks so the result will be converted to empty string insteadOut of those three options while I like 2nd one, it seems to be impossible due to backwards compatibility, so I'd vote for the 3d option instead.
Choose one or more from the following categories of impact
null
constructs in code not using the checknulls switch.null
,not null
).Operating System
Windows (Default)
What .NET runtime/SDK kind are you seeing the issue on
.NET SDK (.NET Core, .NET 5+)
.NET Runtime/SDK version
.NET SDK 9.0.0-rc.1.24431.7
Reproducible code snippet and actual behavior
Possible workarounds
Leave as is, so if insightful user wants to do a null check, they should use `withNull: