Introducing Achronyme — a language for zero-knowledge proofs. Read the announcement

Diagnostics & Warnings

Compiler warnings, error output formats, and typo suggestions.

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).

Error Output

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: ...)

Compiler Warnings

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

W001: Unused Variable

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

W002: Unused Mutable

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.

W003: Unreachable Code

Triggers when statements follow a return in the same block:

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

W004: Variable Shadowing

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

W005: Unused Selective Import

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.

”Did You Mean?” Suggestions

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.

Output Formats

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

human (default)

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

ach run program.ach --error-format human

json

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

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

short

Compact one-line format, grep-friendly:

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

Format: file:line:col: severity: message

Error Recovery

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:

$ 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.

Navigation