add noreturn and unreachable

This commit is contained in:
2026-07-22 00:27:13 +02:00
parent 402871ef7a
commit 17508ff751
21 changed files with 286673 additions and 279245 deletions
+24 -3
View File
@@ -716,6 +716,13 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
diagnostic=source.INVALID_DIAGNOSTIC,
})
_ = pop(&stack)
case .Unreachable:
last = append_instruction(state, ir.Instruction{
op=.Trap, span=expr.span, type=types.NORETURN, integer=1,
target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION,
diagnostic=source.INVALID_DIAGNOSTIC,
})
_ = pop(&stack)
case .String, .Array, .Struct, .Range, .Null, .Optional_Some, .Address, .Deref,
.Index, .Slice, .Field, .Union_Tag, .Length, .Slice_Ptr, .Unwrap, .Orelse,
.Try, .Catch, .Not, .Eq, .Ne, .Lt, .Le, .Gt, .Ge, .And, .Or:
@@ -1037,6 +1044,9 @@ lower_statements :: proc(state: ^State, statements: []hir.Stmt_Id) {
})
} else {
value := lower_expr(state, statement.expr)
if types.is_noreturn(state.hir_module.exprs[statement.expr].type) {
continue
}
append_instruction(state, ir.Instruction{
op=.Return,
span=statement.span,
@@ -1680,11 +1690,22 @@ lower_body :: proc(hir_module: ^hir.Module, function: hir.Function, allocator: m
}
lower_statements(&state, function.body)
if len(state.instructions) == 0 ||
(state.instructions[len(state.instructions)-1].op != .Return &&
state.instructions[len(state.instructions)-1].op != .Return_Void) {
last_terminates := false
if len(state.instructions) > 0 {
last_instruction := state.instructions[len(state.instructions)-1]
last_terminates = last_instruction.op == .Return || last_instruction.op == .Return_Void ||
last_instruction.op == .Trap ||
last_instruction.op == .Call && types.is_noreturn(last_instruction.type)
}
if !last_terminates {
if types.is_void(function.result) {
append_instruction(&state, ir.Instruction{op=.Return_Void, type=types.VOID, target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION, diagnostic=source.INVALID_DIAGNOSTIC})
} else if types.is_noreturn(function.result) {
append_instruction(&state, ir.Instruction{
op=.Trap, type=types.NORETURN, integer=1,
target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION,
diagnostic=source.INVALID_DIAGNOSTIC,
})
} else {
value := append_instruction(&state, ir.Instruction{
op=.Const,