Skip to content

Handle unresolved value-type call targets - #4053

Open
sonyps5201314 wants to merge 1 commit into
icsharpcode:masterfrom
sonyps5201314:split/unresolved-value-type-call-targets
Open

Handle unresolved value-type call targets#4053
sonyps5201314 wants to merge 1 commit into
icsharpcode:masterfrom
sonyps5201314:split/unresolved-value-type-call-targets

Conversation

@sonyps5201314

Copy link
Copy Markdown
Contributor

Related to #4049.

Problem

When an instance method belongs to a value type from a missing assembly, its declaring type has unknown stack semantics. ILReader inserts an invalid Ref -> Unknown conversion around the managed-reference receiver.

ExpressionBuilder.TranslateTarget then treats the conversion as a value receiver and emits invalid C# such as:

((MyEnumerator)(ref value)).MoveNext();
((IDisposable)(*(MyEnumerator*)(&value))).Dispose();

Solution

For the narrowly defined Invalid, Ref -> Unknown conversion on an unresolved call target:

  • use the existing UnwrapConv helper to recover the original managed-reference receiver;
  • infer managed-reference target semantics from the IL argument when the unresolved declaring type cannot provide them;
  • treat same-named unresolved by-reference element types as the same receiver type.

This PR contains only this call-target fix and its Issue3729 regression case. It does not include constructor-initializer, primary-constructor, collection-expression, resolver, project export, or backing-field changes from #4049.

Test

The ILPretty case was added first. Before the implementation it failed with an unsafe method, a (MyEnumerator)(ref value) cast, and a pointer dereference for the constrained IDisposable.Dispose call.

After the implementation:

  • ILPrettyTestRunner.Issue3729: passed.
  • Complete ILPrettyTestRunner fixture: 63 total, 62 passed, 1 pre-existing ignored, 0 failed.
  • Full Release|Any CPU solution build: 16 succeeded, 0 failed.
  • BuildTools/format.ps1: clean.
  • At least one test covering the code changed

A missing value-type definition makes ILReader insert a Ref-to-Unknown conversion before instance calls. Preserve the managed-reference receiver so C# output does not fall back to invalid ref casts or unsafe pointers.

Assisted-by: Codex:gpt-5.6-sol:Codex
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant