Skip to content

Diagnostics & Warnings

Achronyme reports errors and warnings with source snippets, underline carets, and actionable suggestions — similar to rustc. The diagnostic system works across all commands (run, compile, circuit, disassemble).

By default, errors render with source context:

error: undefined variable: `conuter`
--> 3:9
|
3 | let y = conuter + 1
| ^^^^^^^
|
= help: did you mean `counter`?

The output includes:

  • Severityerror or warning, with an optional code like [W001]
  • Locationfile:line:col (or line:col for stdin)
  • Source snippet — the offending line with underline carets (^^^)
  • Labels — secondary spans pointing to related locations
  • Notes — additional context (= note: ...)
  • Suggestions — actionable fixes (= help: ...)

The compiler emits warnings for code that is valid but likely incorrect. Warnings never prevent compilation.

Triggers when a local variable or function parameter is never read:

let count = 42
// warning[W001]: unused variable: `count`

Prefix with _ to silence the warning:

let _count = 42 // no warning

Triggers when a variable is declared with mut but never reassigned:

let mut total = 0
print(total)
// warning[W002]: variable `total` declared as mutable but never mutated

Remove the mut keyword if the variable doesn’t need to change.

Triggers when statements follow a return in the same block:

fn foo() {
return 1
let x = 2 // warning[W003]: unreachable code
}

Triggers when a new binding shadows an existing variable in the same scope:

let x = 1
let x = 2 // warning[W004]: variable `x` shadows a previous binding in the same scope

Triggers when a name brought in by a selective import is never used:

import { add, PI } from "./math.ach"
print(add(1, 2))
// warning[W005]: imported name `PI` is never used

Prefix with _ to silence the warning:

import { add, _PI } from "./math.ach"
print(add(1, 2)) // no warning for _PI

This warning only applies to selective imports (import { ... } from). Namespace imports (import "..." as alias) are not checked because the alias is a single binding.

When the compiler encounters an undefined variable, it searches all in-scope names (locals, globals, upvalues) for similar identifiers using Levenshtein distance. If a close match is found, it suggests the correction:

error: undefined variable: `prnt`
--> 2:1
|
2 | prnt("hello")
| ^^^^
|
= help: did you mean `print`?

The suggestion threshold scales with name length — short names (3 characters or fewer) require a closer match to avoid false suggestions.

The --error-format flag controls how diagnostics are rendered. It applies globally to all subcommands.

Rich output with source snippets, underline carets, and ANSI colors (when stderr is a terminal):

Terminal window
ach run program.ach --error-format human

One JSON object per diagnostic (JSON Lines format), suitable for editor integrations and CI pipelines:

Terminal window
ach run program.ach --error-format json
{"code":"W001","level":"warning","message":"unused variable: `x`","notes":["if this is intentional, prefix with underscore: `_x`"],"spans":[{"byte_end":5,"byte_start":4,"column_end":6,"column_start":5,"file_name":null,"label":"primary","line_end":1,"line_start":1}],"suggestions":[]}

Each JSON object contains:

FieldTypeDescription
messagestringThe diagnostic message
codestring|nullWarning/error code (e.g., "W001")
levelstring"error", "warning", "note", or "help"
spansarraySource locations with byte offsets, line/col, and labels
notesarrayAdditional context strings
suggestionsarraySuggested code replacements with spans

Compact one-line format, grep-friendly:

Terminal window
ach run program.ach --error-format short
<stdin>:3:9: error: undefined variable: `x`

Format: file:line:col: severity: message

The parser collects multiple errors per compilation instead of stopping at the first one. Failed regions appear as Error nodes in the AST, allowing the parser to continue and report additional issues:

Terminal window
$ ach compile broken.ach
error: expected expression
--> 1:9
|
1 | let x =
| ^
|
error: unexpected token `}`
--> 3:1
|
3 | }
| ^
|

This means a single compilation run can surface multiple problems at once, reducing the edit-compile-fix cycle.