@@ -4340,6 +4340,46 @@ pub mod hir_build_tests {
43404340 Return v34
43414341 " ) ;
43424342 }
4343+
4344+ #[ test]
4345+ fn reload_block_param_read_in_nested_block ( ) {
4346+ // getblockparam writes to the local slot (materializes the Proc),
4347+ // so reading &block in a nested block is effectively a write
4348+ // that locals_written_in_block must detect.
4349+ eval ( r#"
4350+ def test(&block)
4351+ tap { block }
4352+ block
4353+ end
4354+ "# ) ;
4355+ assert_contains_opcode ( "test" , YARVINSN_send ) ;
4356+ assert_snapshot ! ( hir_string( "test" ) , @r"
4357+ fn test@<compiled>:3:
4358+ bb0():
4359+ EntryPoint interpreter
4360+ v1:BasicObject = LoadSelf
4361+ v2:BasicObject = GetLocal :block, l0, SP@4
4362+ Jump bb2(v1, v2)
4363+ bb1(v5:BasicObject, v6:BasicObject):
4364+ EntryPoint JIT(0)
4365+ Jump bb2(v5, v6)
4366+ bb2(v8:BasicObject, v9:BasicObject):
4367+ v14:BasicObject = Send v8, 0x1000, :tap # SendFallbackReason: Uncategorized(send)
4368+ v15:BasicObject = GetLocal :block, l0, EP@3
4369+ v19:CBool = IsBlockParamModified l0
4370+ IfTrue v19, bb3(v8, v15)
4371+ Jump bb4(v8, v15)
4372+ bb3(v20:BasicObject, v21:BasicObject):
4373+ v28:BasicObject = GetLocal :block, l0, EP@3
4374+ Jump bb5(v20, v28, v28)
4375+ bb4(v23:BasicObject, v24:BasicObject):
4376+ v30:BasicObject = GetBlockParam :block, l0, EP@3
4377+ Jump bb5(v23, v30, v30)
4378+ bb5(v32:BasicObject, v33:BasicObject, v34:BasicObject):
4379+ CheckInterrupts
4380+ Return v34
4381+ " ) ;
4382+ }
43434383 }
43444384
43454385 /// Test successor and predecessor set computations.
0 commit comments