From 3a5440e4eddea3735b26689e576ba4e1102a6a3a Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Mon, 23 Dec 2024 14:15:59 +0900 Subject: [PATCH] base/runtime: Add `ensure` and `ensure_contextless` This provides an equivalent to `assert` and `assert_contextless` that are always evaluated, ignoring `ODIN_DISABLE_ASSERT`, which is useful for enforcing API contracts or "asserting" on conditionals with side-effects. --- base/runtime/core_builtin.odin | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index d28dadd02..f06dcb478 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -964,6 +964,24 @@ assert :: proc(condition: bool, message := #caller_expression(condition), loc := } } +// Evaluates the condition and aborts the program iff the condition is +// false. This routine ignores `ODIN_DISABLE_ASSERT`, and will always +// execute. +@builtin +ensure :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) { + if !condition { + @(cold) + internal :: proc(message: string, loc: Source_Code_Location) { + p := context.assertion_failure_proc + if p == nil { + p = default_assertion_failure_proc + } + p("unsatisfied ensure", message, loc) + } + internal(message, loc) + } +} + @builtin panic :: proc(message: string, loc := #caller_location) -> ! { p := context.assertion_failure_proc @@ -999,6 +1017,17 @@ assert_contextless :: proc "contextless" (condition: bool, message := #caller_ex } } +@builtin +ensure_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) { + if !condition { + @(cold) + internal :: proc "contextless" (message: string, loc: Source_Code_Location) { + default_assertion_contextless_failure_proc("unsatisfied ensure", message, loc) + } + internal(message, loc) + } +} + @builtin panic_contextless :: proc "contextless" (message: string, loc := #caller_location) -> ! { default_assertion_contextless_failure_proc("panic", message, loc)