fallible ergonomics
This commit is contained in:
@@ -412,12 +412,60 @@ lower_compound_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instructi
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
if expr.kind == .Try {
|
||||
result := channel
|
||||
if !types.equal(channel_type, state.func_result) {
|
||||
error_type := types.fallible_error(channel_type, &state.hir_module.types)
|
||||
enclosing_error := types.fallible_error(state.func_result, &state.hir_module.types)
|
||||
error_value := append_instruction(state, ir.Instruction{
|
||||
op=.Fallible_Error, span=expr.span, type=error_type,
|
||||
target=ir.INVALID_REF, a=channel_slot, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
if !types.equal(error_type, enclosing_error) {
|
||||
error_value = append_instruction(state, ir.Instruction{
|
||||
op=.Sum_Widen, span=expr.span, type=enclosing_error,
|
||||
target=ir.INVALID_REF, a=error_value, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
}
|
||||
args := make([]ir.Instruction_Id, 1, state.allocator)
|
||||
args[0] = error_value
|
||||
result = append_instruction(state, ir.Instruction{
|
||||
op=.Aggregate, span=expr.span, type=state.func_result, integer=1,
|
||||
args=args, target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION,
|
||||
b=ir.INVALID_INSTRUCTION, diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
}
|
||||
append_instruction(state, ir.Instruction{
|
||||
op=.Return, span=expr.span, type=state.func_result,
|
||||
target=ir.INVALID_REF, a=channel, b=ir.INVALID_INSTRUCTION,
|
||||
target=ir.INVALID_REF, a=result, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
} else {
|
||||
if expr.integer != 0 {
|
||||
capture := hir.as_local(expr.target)
|
||||
if capture != hir.INVALID_LOCAL && int(capture) < len(state.func_locals) {
|
||||
error_type := state.func_locals[capture].type
|
||||
error_value := append_instruction(state, ir.Instruction{
|
||||
op=.Fallible_Error, span=expr.span, type=error_type,
|
||||
target=ir.INVALID_REF, a=channel_slot, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
capture_slot := append_instruction(state, ir.Instruction{
|
||||
op=.Alloca, span=expr.span, type=error_type,
|
||||
target=ir.local_ref(ir.Local_Id(capture)),
|
||||
a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
state.local_slots[capture] = capture_slot
|
||||
append_instruction(state, ir.Instruction{
|
||||
op=.Store, span=expr.span, type=error_type,
|
||||
target=ir.INVALID_REF, a=capture_slot, b=error_value,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
}
|
||||
lower_statements(state, expr.body)
|
||||
}
|
||||
fallback := lower_nested_expr(state, expr.right)
|
||||
append_instruction(state, ir.Instruction{
|
||||
op=.Store, span=expr.span, type=success,
|
||||
|
||||
Reference in New Issue
Block a user