-
Notifications
You must be signed in to change notification settings - Fork 802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NullReferenceException when calling a virtual Object method on a value type from inline function #8098
Comments
It's a bit of a guess, but I think this is by design. Your code doesn't do boxing, and the compiler doesn't automatically do that for statically resolved parameters. If you'd add |
By design or not, I believe that's a very bad idea to compile code in such a way that's guaranteed to fail in runtime. It should either compile well or generate a compile error, and should never do the strange thing. I'm okay with filing a language suggestion if it's preferred for this particular change. |
I agree, but there are a lot of cases where it's impossible for a compiler to find out at compile time that it will always fail, let alone to decide whether your code was intentional, or not. I mean, you can write Though it's pretty hard to know as a programmer that you need boxing when you use inline generics to mix both reference and value types. There are special extensions in the compiler code itself to deal with this, but these are not available to normal code. I believe there are several proposals underway, and SRTP itself gets a lot of attention for F# 5.0 at the moment, but I'm not sure any of those address this particular issue. Interestingly, F#'s own |
Is it really that hard to know which cases are "bad"? It seems they are simple (or at least let's say "straightforward"), if I understand correctly. We could issue a compilation error / warning each time a member constraint (e.g. a Does it sound right? Are there any nonproblematic uses of this pattern (I mean, will such an error break any good, working code)? Any other downsides I don't see? To me, it seems it's possible to detect all such uses of virtual methods on structs in compile time (because it's the compiler that emits the broken code), but I may be very wrong in this regard. |
Actually, I now think this is solvable, because virtual members on structs can only ever be the ones defined on object (and interfaces, but that's not possible without new language features). I believe they can be successfully run with a constrained callvirt, in which case no boxing takes place. But the compiler must issue the correct call. |
Tagging #4924 and using this as a canonical sub-problem of that issue #4924 (comment) for more information |
Like everything related to SRTP resolution we should assess w.r.t. to the overall work in #6805 |
Repro steps
Write the following F# program, and run it:
Expected behavior
This program should print a string
123
.Actual behavior
This program throws a
NullReferenceException
:It works on reference types though.
Known workarounds
Do not use an inline function there.
Related information
The text was updated successfully, but these errors were encountered: