favor return over return _ (void return); newline/closing terminates

This commit is contained in:
2026-07-14 19:07:37 +02:00
parent eac5b32738
commit 471896b48a
19 changed files with 92266 additions and 94923 deletions
+32 -3
View File
@@ -7516,7 +7516,7 @@ build_block :: proc(
local = hir.INVALID_LOCAL, diagnostic = source.INVALID_DIAGNOSTIC,
})
} else if !types.is_void(ctx.result) {
id := source.add(checker.diagnostics, statement.span, "'return _' is only valid in a void function")
id := source.add(checker.diagnostics, statement.span, "non-void function must return a value")
append(&body, hir.stmt_id(len(checker.module.statements)))
append(&checker.module.statements, hir.Stmt{
kind = .Trap, span = statement.span, expr = hir.INVALID_EXPR,
@@ -8118,6 +8118,16 @@ build_block :: proc(
} else {
yielded = build_expr(checker, statement.expr, ctx.locals^[:], ctx.global_reads, ctx.calls, target.slot_type, ctx.pkg, ctx.file)
}
if yielded != hir.INVALID_EXPR && types.is_void(checker.module.exprs[yielded].type) {
id := source.add(checker.diagnostics, statement.span, "'yield' expression must produce a non-void value")
append(&body, hir.stmt_id(len(checker.module.statements)))
append(&checker.module.statements, hir.Stmt{
kind = .Trap, span = statement.span, expr = hir.INVALID_EXPR,
local = hir.INVALID_LOCAL, diagnostic = id,
})
ctx.problematic^ = true
continue
}
yielded = resolve_loop_slot(ctx, target, yielded, checker.module.exprs[yielded].type if yielded != hir.INVALID_EXPR else types.INVALID, statement.span)
if target.slot == hir.INVALID_LOCAL || yielded == hir.INVALID_EXPR {
id := source.add(checker.diagnostics, statement.span,
@@ -8291,9 +8301,19 @@ build_value_block :: proc(
checker, yield_stmt.expr, ctx.locals^[:], ctx.global_reads, ctx.calls,
expected, ctx.pkg, ctx.file,
)
value_type = checker.module.exprs[value].type
}
value_type = checker.module.exprs[value].type
if is_runtime_type(checker, expected) {
if types.is_void(value_type) {
id := source.add(checker.diagnostics, yield_stmt.span, "'yield' expression must produce a non-void value")
value = invalid_hir_expr(checker, yield_stmt.span, id)
value_type = types.INVALID
ctx.problematic^ = true
} else if types.is_void(expected) {
id := source.add(checker.diagnostics, yield_stmt.span, "void value context must fall through instead of yielding")
value = invalid_hir_expr(checker, yield_stmt.span, id)
value_type = types.INVALID
ctx.problematic^ = true
} else if is_runtime_type(checker, expected) {
value = coerce_expr(checker, value, expected, yield_stmt.span)
value_type = checker.module.exprs[value].type
}
@@ -9521,6 +9541,15 @@ build_value_loop :: proc(
// The fall-through value initializes the slot before the loop (loop captures are
// out of scope here), so the loop completing leaves it as the result.
fall_value := build_expr(checker, fall_stmt.expr, ctx.locals^[:], ctx.global_reads, ctx.calls, target.slot_type, ctx.pkg, ctx.file)
if fall_value != hir.INVALID_EXPR && types.is_void(checker.module.exprs[fall_value].type) {
for s in loop_block {
append(body, s)
}
delete(loop_block, checker.allocator)
id := source.add(checker.diagnostics, fall_stmt.span, "'yield' expression must produce a non-void value")
ctx.problematic^ = true
return invalid_hir_expr(checker, fall_stmt.span, id), types.INVALID
}
fall_value = resolve_loop_slot(ctx, &target, fall_value, checker.module.exprs[fall_value].type if fall_value != hir.INVALID_EXPR else types.INVALID, fall_stmt.span)
if target.slot == hir.INVALID_LOCAL || fall_value == hir.INVALID_EXPR {
for s in loop_block {
+8 -1
View File
@@ -2463,12 +2463,19 @@ ct_exec_statements :: proc(
ok = ct_fail(state, .Not_Comptime, statement.span, "'yield' is only valid in a comptime value block")
} else if statement.value_control_flow {
flow, ok = ct_exec_statements(state, statement.body, true, depth+1)
if ok && flow.kind == .Yield && types.is_void(state.values[flow.value].type) {
ok = ct_fail(state, .Not_Comptime, statement.span, "'yield' expression must produce a non-void value")
}
} else {
value, expr_flow, expr_ok := ct_eval_expr(state, statement.expr, types.INVALID, depth+1)
ok = expr_ok
flow = expr_flow
if ok && flow.kind == .Normal {
flow = ct_flow(.Yield, value, statement.label)
if types.is_void(state.values[value].type) {
ok = ct_fail(state, .Not_Comptime, statement.span, "'yield' expression must produce a non-void value")
} else {
flow = ct_flow(.Yield, value, statement.label)
}
}
}
case .If: