Skip to content

tstypes: the adoption tie arm can land one owner's resolution on another owner's edge #730

Description

@zzet

Follow-up from the review of #722.

#722's tie arm exists to make one thing impossible — "the engine can then never land a resolution on a different node than extraction chose". It does not fully deliver that, and the test written to pin it cannot detect the gap.

The gap

The len(owners) > 1 arm picks enclosingCallable when it is any tied owner, then upgradeExistingCall claims that owner's same-line same-name stub — regardless of which owner authored the fact currently being applied. When two tied owners call the same name on different types, the first fact applied retargets the method's stub to the other owner's target, and the method's own correct target is then unreachable because the edge is no longer claimable.

Repro

Core/Engine.cs with class Engine { Fire, Halt }, Core/Other.cs with class Other { Fire }, and Use/Rig.cs:

private Engine motor; private Other pal;
public int Level { get { motor.Fire(); return 7; } } public void Busy() { pal.Fire(); }

Observed at 6be528ef:

Use/Rig.cs::Rig.Busy  -> Core/Engine.cs::Engine.Fire  line=5 conf=0.95 origin=ast_resolved
Use/Rig.cs::Rig.Level -> unresolved::*.Fire

Busy calls pal.Fire(), i.e. Other.Fire. It carries a confident 0.95 edge to a type it never calls, and its real call is lost. Expected: Busy -> Other.Fire, with the property's own site either resolved to Engine.Fire or left untouched.

Why the existing pin misses it

TestCSharp_SameNameTieMethodKeepsOwnCall uses a fixture where both owners call the same target, so the assertion passes no matter which fact produced the edge. The test is not wrong, it just cannot discriminate. A fixture with two different targets is what is needed.

Scope

This is not a regression903b520b behaves identically, because containment picked the method there too. Filing it because the tie arm was introduced specifically to close this class, and because the PR body states the stronger guarantee. Either the arm should carry the authored fact's owner through to the claim, or the body's claim should be narrowed to what the arm actually provides.

Related shape from the same review, same arm: when a property and a method both call a same-named method on one shared line, both call facts hit the tie arm and both resolve onto the method, so the property's own call is not independently resolved. Also not a regression, and also not what the body's framing implies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions