@@ -783,6 +783,16 @@ local function assert_is_a(ctx: Context, w: Where, t1: Type, t2: Type, ectx?: No
783783 return ok
784784end
785785
786+ local function count_scope_vars (self: Context ): integer
787+ local n = 0
788+ for i = 1 , # self .st do
789+ for _, _ in pairs (self .st [i].vars ) do
790+ n = n + 1
791+ end
792+ end
793+ return n
794+ end
795+
786796visit_node.cbs = {
787797 [" statements" ] = {
788798 before = function (self: Context , node: Node )
@@ -1052,14 +1062,17 @@ visit_node.cbs = {
10521062 end
10531063 end
10541064
1055- --for i = #self.st, 1, -1 do
1056- local scope = self .st [# self .st ]
1057- if scope.pending_labels and scope.pending_labels [label_id] then
1058- node.used_label = true
1059- scope.pending_labels [label_id] = nil
1060- --break
1065+ local scope = self .st [# self .st ]
1066+ if scope.pending_labels and scope.pending_labels [label_id] then
1067+ local n_scope_vars = count_scope_vars (self )
1068+ for _, goto_node in ipairs (scope.pending_labels [label_id]) do
1069+ if n_scope_vars > goto_node.n_scope_vars then
1070+ self .errs :add (goto_node, " goto jumps into scope of a local variable" )
1071+ end
10611072 end
1062- --end
1073+ node.used_label = true
1074+ scope.pending_labels [label_id] = nil
1075+ end
10631076 end ,
10641077 after = function (): Type
10651078 return NONE
@@ -1084,6 +1097,7 @@ visit_node.cbs = {
10841097 scope.pending_labels = scope.pending_labels or {}
10851098 scope.pending_labels [label_id] = scope.pending_labels [label_id] or {}
10861099 table.insert (scope.pending_labels [label_id], node)
1100+ node.n_scope_vars = count_scope_vars (self )
10871101 end
10881102
10891103 return NONE
0 commit comments