Fix anonymous-type lambda early-return emitting unresolvable cast#3752
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a decompiler edge case where lambdas/anonymous methods with an inferred return type involving an anonymous type could emit an explicit cast on null (e.g., return (<>f__AnonymousType0<int>)null;), which is not valid C# syntax. The change prevents emitting such casts when the expected type contains an anonymous type, and adds a regression test for the reported scenario.
Changes:
- Adjusted
StatementBuilder.IsPossibleLossOfTypeInformation()to not treatnullas requiring an explicit cast when the expected type contains an anonymous type. - Added a new pretty test case reproducing Issue #3751.
- Registered the new Issue3751 test in
PrettyTestRunner.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| ICSharpCode.Decompiler/CSharp/StatementBuilder.cs | Skips explicit casts for null returns when the expected type contains an anonymous type, preventing unnameable cast emission. |
| ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3751.cs | Adds a regression test source that would previously decompile to an invalid cast to an anonymous type. |
| ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs | Registers the new Issue3751 pretty test to run across the default compiler option matrix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
CI seems to have failed during |
|
CI seems to be green now, although |
Sorry, that was a blast from the past - I enabled branch protection for master and missed that there was an old status check gating merges to master (we have moved on from AppVeyor for ages) |
When a lambda's inferred return type contains an anonymous type and one branch returns null, the decompiler emitted an explicit cast such as `return (IEnumerable<<>f__AnonymousType0<int>>)null;`, which is invalid C#. Skip the cast in IsPossibleLossOfTypeInformation for null literals whenever the expected type contains an anonymous type: null is implicitly convertible to any reference type, so no cast is needed, and the anonymous type has no nameable form to cast to anyway. Fixes icsharpcode#3751
95b5fb0 to
9e4c7a4
Compare
|
Thank you for your contribution! |
Fixes #3751
Problem
When a lambda's inferred return type contains an anonymous type and one branch returns null, the decompiler emitted an explicit cast such as
return (IEnumerable<<>f__AnonymousType0<int>>)null;, which is invalid C#.Solution
Skip the cast in IsPossibleLossOfTypeInformation for null literals whenever the expected type contains an anonymous type:
null is implicitly convertible to any reference type, so no cast is needed, and the anonymous type has no nameable form to cast to anyway.