Repository navigation
A synchronize { yield } on a boxed Mutex answers each caller's block value - #8463
Conversation
…value A method that runs its block in synchronize on a Mutex read from a Hash did not compile when its callers' blocks return different types: the result slot took the first caller's type. Each inlined caller's value has to be boxed, as it already is for a block handed to a program method. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Gate: green tree d0642e8 master 55aa88e (linux-x86_64 gcc-13.3.0) tests 6772/0
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to The inference change is narrowly scoped, and the added regression test covers the reported synchronized-yield behavior. No actionable merge-blocking issue is evident. Pre-merge checks |
|
What this changes
A method that answers
synchronize { yield }on a Mutex read out of a Hash (a boxed Mutex) did not compile when its callers' blocks answer values of different types. The method is inlined at each caller, and the type of thesynchronizecall on a boxed receiver is the type of its block's last expression, here theyield. The yield took the first caller's block type, so the result slot was declared as that type (ansp_StrStrHash *for a Hash block), and another caller's Boolean was assigned into it: gcc stopped withint-conversion. A Mutex in an instance variable compiles, becauseMutex#synchronizeon a typed receiver already answers a boxed value.The yield is now typed poly when it is the value of a
synchronizeblock with a receiver, as it already is when it is the value of a block handed to a method the program defines (the block's value goes into the lock frame's result slot, the same position as a yield at the end of abegin/ensure). Each caller then boxes its own block's value. This applies only where the callers' block values differ in type (yield_value_diverges).Reproducer
CRuby 4.0.6 prints
{"a" => "b"}andtrue. master 090969e does not build the C:error: assignment to ‘sp_StrStrHash *’ from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion].spinel difffrom masterOn master:
On this branch:
spinel diff: same.Generated C: of the 33 programs in
test/,packages/*/test/,benchmark/andexamples/(outsidetest/reject/) that callsynchronize, none gets different C. optcarrot's C is unchanged.make gate(on this branch merged with current master).expectedfiles that match CRuby 4.0 run with--enable-frozen-string-literal# spinel: int64(the test has none)Test:
test/mutex_boxed_synchronize_yield_values.rbcalls one method that answerssynchronize { yield }on a Mutex read out of a Hash from callers whose blocks answer a Hash, a Boolean (true and false), nil, an Integer, a String and the Mutex's ownlocked?, and the same method's second path through a Mutex in an instance variable; the Integer and the Hash are then used as values. It fails to compile on master and passes withSPINEL_GC_STRESS=1.Not in this PR: a
synchronizeblock whose last expression is not a yield takes one type per block, as before; only a value shared by several inlined callers needed the change.Summary by CodeRabbit