-
Notifications
You must be signed in to change notification settings - Fork 832
Description
I was refactoring some old code, replacing x.ToString() with string x for readability and, let's face it, best practices. But much to my surprise, this didn't work in a number of cases, though I always thought the two were interchangeable (with the exception of null, which is treated as "" for string null and as NRE for null.ToString(), hence the preference for string vs .ToString()).
It can lead to this:
But I don't think anything is "escaping its scope" here...
Repro steps
It is thrown by this code:
type Foo<'T> =
| Bar of 'T
override this.ToString() = // FS0670
match this with
| Bar x -> string xExpected behavior
It should compile. The string function is so basic to the language, it should be used whenever x.ToString() can be used.
Actual behavior
Using string can raise the following compile error:
FS0670 This code is not sufficiently generic. The type variable ^T could not be generalized because it would escape its scope.
Known workarounds
I found two workarounds:
- Don't use
stringand stick toToString(), but that's a PITA - Write your own function (inline or not) that doesn't expose this problem:
/// Shadowing Core.string function. /// Uses obj.ReferenceEquals instead of isNull to prevent null-constraint let string x = if obj.ReferenceEquals(x, null) then "" else x.ToString()
Related information
Seen on any recent F# version. I did not (yet) test whether this is a regression.
