Repository navigation
Assert failure extraParamArgLocation == INT_MAX in interpreter for async covariant return tests #130351
Description
Activity
- addeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jul 8, 2026 dotnet-policy-service commented
on Jul 8, 2026 ContributorMore actionsTagging subscribers to this area: @vitek-karas, @BrzVlad, @kotlarmilos
See info in area-owners.md if you want to be subscribed.I was just looking into this and thinking about what the best fix would be. So the problem is that,
getCallInforeturns a sig thathasTypeArg, butCORINFO_VIRTUALCALL_LDVIRTFTNcalls never require to pass the arg, since the target does all the instantiating. JIT doesn't check forhasTypeArgin its path forCORINFO_VIRTUALCALL_LDVIRTFTNso it doesn't get tripped by it. So the least invasive fix would be to make the interpreter do the same. I believe a more rigorous approach would be to makegetCallInfonot havehasTypeArgset for these types of calls in the first place.Looking even deeper than this, normal virtual calls don't get tripped up by this because token resolving ends up calling
MethodDesc::FindOrCreateAssociatedMethodDescwithallowInstParamfalse. This ends up having as the target of a virtual call anInstantiatedMethodDescwith the instantiation beingCanon, and the call info gets marked as not requiring a type arg because the method desc is flagged as carrying the insantiation. It seems like this could also be fixed by tweaking the token inEmitReturnDroppingThunkto point similarly to a Canon instantiated method, but I didn't look much into this approach and I'm not familiar enough with the area to tell whether this would be a better solutionLooking even deeper than this, normal virtual calls don't get tripped up by this because token resolving ends up calling MethodDesc::FindOrCreateAssociatedMethodDesc with allowInstParam false. This ends up having as the target of a virtual call an InstantiatedMethodDesc with the instantiation being Canon, and the call info gets marked as not requiring a type arg because the method desc is flagged as carrying the insantiation. It seems like this could also be fixed by tweaking the token in EmitReturnDroppingThunk to point similarly to a Canon instantiated method, but I didn't look much into this approach and I'm not familiar enough with the area to tell whether this would be a better solution
We should try as much as possible to match what happens with normal user IL. The call we're trying to encode in
EmitReturnDroppingThunkis similar to theBar<T>()call inclass C { virtual void Foo<T>() { Bar<T>(); } virtual string Bar<T>() { } }
So if that's represented internally with a call to
Bar<__Canon>withallowInstParam=false, then that's probably the right way to do that here as well. Other places in asyncthunks.cpp also callFindOrCreateAssociatedMethodDescwithallowInstParam=falsebefore they synthesize tokens.Reacted by Vlad Brezae- removeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jul 9, 2026 - locked and limited conversation to collaborators
on Aug 10, 2026
Example test run: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1495258
Example console log: https://helixr1107v0xdcypoyl9e7f.blob.core.windows.net/dotnet-runtime-refs-heads-main-e6056bcae0584738bd/async/1/console.f4560e10.log?helixlogtype=result
Reproduces consistently under
DOTNET_InterpMode=3when running the async tests.Looks caused by #129442, cc @VSadov. It looks like the VM is returning
CORINFO_VIRTUALCALL_LDVIRTFTNbut also that the call has a generic type argument, which is an unexpected combination for the interpreter.