Skip to content

Commit 1850946

Browse files
committed
Preserve loop call-boundary errors for property setters
1 parent 23f6af8 commit 1850946

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

vibes/execution.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,14 @@ func (exec *Execution) assignToMember(obj Value, property string, value Value, p
382382
return exec.errorAt(pos, "private method %s", setterName)
383383
}
384384
_, err := exec.callFunction(fn, obj, []Value{value}, nil, NewNil(), pos)
385+
if err != nil {
386+
if errors.Is(err, errLoopBreak) {
387+
return exec.errorAt(pos, "break cannot cross call boundary")
388+
}
389+
if errors.Is(err, errLoopNext) {
390+
return exec.errorAt(pos, "next cannot cross call boundary")
391+
}
392+
}
385393
return err
386394
}
387395

vibes/runtime_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,20 @@ func TestLoopControlBreakAndNext(t *testing.T) {
10071007

10081008
func TestLoopControlNestedAndBlockBoundaryBehavior(t *testing.T) {
10091009
script := compileScript(t, `
1010+
class SetterBoundary
1011+
def break_set=(n)
1012+
if n == 2
1013+
break
1014+
end
1015+
end
1016+
1017+
def next_set=(n)
1018+
if n == 2
1019+
next
1020+
end
1021+
end
1022+
end
1023+
10101024
def nested_break()
10111025
out = []
10121026
for i in [1, 2]
@@ -1060,6 +1074,22 @@ func TestLoopControlNestedAndBlockBoundaryBehavior(t *testing.T) {
10601074
end
10611075
out
10621076
end
1077+
1078+
def break_from_setter_boundary()
1079+
target = SetterBoundary.new
1080+
for n in [1, 2, 3]
1081+
target.break_set = n
1082+
end
1083+
true
1084+
end
1085+
1086+
def next_from_setter_boundary()
1087+
target = SetterBoundary.new
1088+
for n in [1, 2, 3]
1089+
target.next_set = n
1090+
end
1091+
true
1092+
end
10631093
`)
10641094

10651095
nestedBreak := callFunc(t, script, "nested_break", nil)
@@ -1077,6 +1107,16 @@ func TestLoopControlNestedAndBlockBoundaryBehavior(t *testing.T) {
10771107
if err == nil || !strings.Contains(err.Error(), "next cannot cross call boundary") {
10781108
t.Fatalf("expected block-boundary next error, got %v", err)
10791109
}
1110+
1111+
_, err = script.Call(context.Background(), "break_from_setter_boundary", nil, CallOptions{})
1112+
if err == nil || !strings.Contains(err.Error(), "break cannot cross call boundary") {
1113+
t.Fatalf("expected setter-boundary break error, got %v", err)
1114+
}
1115+
1116+
_, err = script.Call(context.Background(), "next_from_setter_boundary", nil, CallOptions{})
1117+
if err == nil || !strings.Contains(err.Error(), "next cannot cross call boundary") {
1118+
t.Fatalf("expected setter-boundary next error, got %v", err)
1119+
}
10801120
}
10811121

10821122
func TestLoopControlInsideClassMethods(t *testing.T) {

0 commit comments

Comments
 (0)