use leo_errors::Formatted;
use leo_span::Span;
use std::fmt::Display;
const CODE_PREFIX: &str = "SAZ";
const CODE_MASK: i32 = 4000;
pub(crate) fn no_path_runs_all_finals_exactly_once(num_total_paths: impl Display, span: Span) -> Formatted {
Formatted::error(
CODE_PREFIX,
CODE_MASK,
format!("no path through this function runs every `Final` exactly once (checked {num_total_paths} path(s))"),
span,
)
.with_help("For a `Final` value `f`, call `f.run()` to run it. Remove duplicate `.run()` calls and add missing ones so every path consumes each `Final` exactly once.")
}
pub(crate) fn final_runs_missing(unawaited: impl Display, span: Span) -> Formatted {
Formatted::error(CODE_PREFIX, CODE_MASK + 1, format!("the following `Final`s were never run: {unawaited}"), span)
.with_help("For a `Final` value `f`, call `f.run()` to run it.")
}
pub(crate) fn invalid_run_call(span: Span) -> Formatted {
Formatted::error(CODE_PREFIX, CODE_MASK + 2, "not a valid `.run()` call", span)
.with_help("For a `Final` value `f`, call `f.run()` with no arguments to run it.")
}
pub(crate) fn expected_final(type_: impl Display, span: Span) -> Formatted {
Formatted::error(CODE_PREFIX, CODE_MASK + 3, format!("expected a `Final`, but found `{type_}`"), span)
.with_help("Only `Final` values can be run with `.run()`.")
}
pub(crate) fn misplaced_final(span: Span) -> Formatted {
Formatted::error(CODE_PREFIX, CODE_MASK + 5, "a `Final` cannot be used in this way", span)
.with_help("`Final`s must be created, bound to a variable, and consumed exactly once. They cannot be moved, reassigned, or stored.")
}
pub(crate) fn compile_time_cast(value: impl Display, type_: impl Display, span: Span) -> Formatted {
Formatted::error(CODE_PREFIX, CODE_MASK + 8, format!("compile-time cast `{value} as {type_}` would fail"), span)
.with_help(format!("The constant `{value}` does not fit into `{type_}`. Choose a value within the target type's range, or pick a wider target type."))
}
pub(crate) fn array_bounds(index: impl Display, len: impl Display, span: Span) -> Formatted {
Formatted::error(
CODE_PREFIX,
CODE_MASK + 10,
format!("array index {index} is out of bounds (array length is {len})"),
span,
)
.with_help(format!("Array indices are zero-based, so the valid range is `0` to `{len} - 1`."))
}
pub(crate) fn final_block_capturing_too_many_vars(size: impl Display, max: impl Display, span: Span) -> Formatted {
Formatted::error(
CODE_PREFIX,
CODE_MASK + 11,
format!(
"a `final` block cannot capture more than {max} variables, but this block captures {size}"
),
span,
)
.with_help(format!("Reduce the number of values captured into the `final` block to at most {max}, e.g. by computing intermediates inside the block instead of capturing them."))
}
pub(crate) fn custom_error(msg: impl Display, help: Option<impl Display>, span: Span) -> Formatted {
let result = Formatted::error(CODE_PREFIX, CODE_MASK + 12, format!("{msg}"), span);
if let Some(h) = help { result.with_help(h) } else { result }
}
pub(crate) fn some_paths_do_not_run_all_finals(
num_total_paths: impl Display,
num_unawaited_paths: impl Display,
span: Span,
) -> Formatted {
Formatted::warning(
CODE_PREFIX,
CODE_MASK,
format!("not all paths through the function run every `Final` ({num_unawaited_paths}/{num_total_paths} paths leave at least one `Final` un-run)"),
span,
)
.with_help("Add `.run()` calls so every path consumes each `Final` exactly once, or pass `--disable-conditional-branch-type-checking` to silence the warning.")
}
pub(crate) fn some_paths_contain_duplicate_final_runs(
num_total_paths: impl Display,
num_duplicate_await_paths: impl Display,
span: Span,
) -> Formatted {
Formatted::warning(
CODE_PREFIX,
CODE_MASK + 1,
format!("some paths through the function contain duplicate `Final` runs ({num_duplicate_await_paths}/{num_total_paths} paths run at least one `Final` more than once)"),
span,
)
.with_help("Remove the redundant `.run()` calls, or pass `--disable-conditional-branch-type-checking` to silence the warning.")
}
pub(crate) fn final_not_awaited_in_order(future_name: impl Display, span: Span) -> Formatted {
Formatted::warning(
CODE_PREFIX,
CODE_MASK + 3,
format!("the `Final` `{future_name}` is not run in the order it was passed to the function"),
span,
)
.with_help("Running `Final`s out of order is allowed but can change observable program semantics. See https://github.com/AleoNet/snarkVM/issues/2570 for context.")
}