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
BadImageFormatException on calling generic local function #29340
Comments
CC @agocke for investigation |
In one case with lambdas capturing a type parameter without capturing a variable of that type, we were incorrectly dropping a closure frame because we didn't think it was necessary (there were no captured variables). This would be true, except for delegate caching, which acts like a captured variable. Since the delegate caching field must live in a closure frame and the delegate caching field could have the type of the captured type parameter, we have to include the type parameter as a captured variable if the delegate type of a lambda contains a captured type parameter. This case only appears with an intervening closure, since otherwise a lambda will always generate at least one closure class and the type parameter would be captured anyway. Fixes dotnet#29340
Here is another slightly different example of reproducing the bug as well as some counter examples that do not reproduce the bug.
|
This turns out to be an interesting bug that happens because we introduce a field of the delegate type for delegate caching, but we only do that after checking for captured variables (but not captured types). The right fix here is track captured types as well as captured variables, but it's a change that will need to be applied carefully as it's likely to cause change in unrelated closures. Some of that change will probably make things more efficient, while some code may need more work to re-enable a valid optimization. |
Why does |
Ah, that's because one of the triggers for delegate caching is if the lambda is inside a loop. Note, not necessarily in the body of a loop, we just have a coarse check to see if the parent syntax is a loop, which it is. By lifting the expression into a local, you avoided the optimization. |
Version Used:
current Visual Studio 2017 15.8.0
tested with:
Steps to Reproduce:
Compile and run following code:
Expected Behavior:
Compile and run without errors.
Actual Behavior:
Program compiles without error but throws BadImageFormatException when run.
The text was updated successfully, but these errors were encountered: