favor return over return _ (void return); newline/closing terminates
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user