Skip to content

analysis: infer for-loop type from break when else is noreturn - #3275

Open
tasodoufu wants to merge 1 commit into
zigtools:masterfrom
tasodoufu:fix/3272-for-break-type
Open

tasodoufu wants to merge 1 commit into
zigtools:masterfrom
tasodoufu:fix/3272-for-break-type

Conversation

@tasodoufu

Copy link
Copy Markdown

Summary

Fixes #3272.

Reproduction

With Zig 0.16.0 / ZLS 0.16.0:

const S = struct { x: u32 };
const ses: []const S = &.{ .{ .x = 1 }, .{ .x = 2 } };

const x = for (ses) |s| {
    if (s.x == 2) break s.x;
} else {
    return;
};

ZLS reports x as noreturn, while Zig resolves the loop expression to u32. The same issue occurs when the else clause is a concrete value: its type is used without considering the typed break value.

Cause

The loop analysis returned the else expression's type before inspecting break <value> operands. A non-returning else clause therefore prevented the loop body's result from being considered.

Fix

Only use the else type as the immediate result when it is not noreturn. Otherwise, continue through the existing BreakIterator path and infer the result from the break operand.

Verification

  • Added tests/analysis/loop_expr_type.zig regression coverage for a noreturn else clause and a value-returning else clause.
  • zig build test-analysis -Dtest-filter=loop_expr_type passed.
  • zig build test-analysis passed.
  • zig fmt --check src/analysis.zig tests/analysis/loop_expr_type.zig passed.
  • git diff --check passed.

Unverified

The full LSP client matrix and platform-specific builds were not run.

AI disclosure

This patch and PR description were prepared with AI assistance. The reproduction, code inspection, implementation, and tests were performed locally against the current default branch.

Signed-off-by: masachika shiotsuka <n2655f@labs.aizu.ac.jp>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

for with break wrongly typed as noreturn

1 participant