ReviewOS

also looking at this

home-lang/home

fix(types): free for-loop and capture scopes after checking them

#939
Open mkantautas wants to merge fix/types-free-loop-scopes into main
2 files +22 -0
packages/types/src/type_system.zigmodified+4-0
Changes to packages/types/src/type_system.zig
@@ -2012,6 +2012,7 @@ pub const TypeChecker = struct {
20122012 for (if_let_stmt.then_block.statements) |then_stmt| {
20132013 self.checkStatement(then_stmt) catch |err| {
20142014 if (err != error.TypeMismatch and err != error.UndefinedVariable) {
2015 self.env.deinit();
20152016 self.env = saved_env_ptr.*;
20162017 self.allocator.destroy(saved_env_ptr);
20172018 return err;
@@ -2019,6 +2020,7 @@ pub const TypeChecker = struct {
20192020 };
20202021 }
20212022
2023 self.env.deinit();
20222024 self.env = saved_env_ptr.*;
20232025 self.allocator.destroy(saved_env_ptr);
20242026
@@ -2087,6 +2089,7 @@ pub const TypeChecker = struct {
20872089 for (for_stmt.body.statements) |body_stmt| {
20882090 self.checkStatement(body_stmt) catch |err| {
20892091 if (err != error.TypeMismatch and err != error.UndefinedVariable) {
2092 self.env.deinit();
20902093 self.env = saved_env_ptr.*;
20912094 self.allocator.destroy(saved_env_ptr);
20922095 return err;
@@ -2094,6 +2097,7 @@ pub const TypeChecker = struct {
20942097 };
20952098 }
20962099
2100 self.env.deinit();
20972101 self.env = saved_env_ptr.*;
20982102 self.allocator.destroy(saved_env_ptr);
20992103 },
packages/types/tests/control_flow_checker_test.zigmodified+18-0
Changes to packages/types/tests/control_flow_checker_test.zig
@@ -141,6 +141,24 @@ test "checker recognizes never as the bottom type" {
141141 ));
142142}
143143
144test "checker frees for-loop and capture scopes" {
145 try std.testing.expect(try checkSource(
146 \\fn run() {
147 \\ for x in [10, 20] {
148 \\ let next = x + 1
149 \\ }
150 \\}
151 ));
152 try std.testing.expect(try checkSource(
153 \\fn run() {
154 \\ let value = 1
155 \\ if (value) |v| {
156 \\ let next = v + 1
157 \\ }
158 \\}
159 ));
160}
161
144162test "checker types panic as a string-taking bottom expression" {
145163 try std.testing.expect(try checkSource(
146164 \\fn fail(): string {