Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Diagnostics and lints

Errors

Every error points at the source that caused it, with a file, line and column, the line itself, and a label:

error: shift amount must be 0 to 31
  --> prog.basm:2:5
  |
2 |     @assert n >= 0 && n < 32, "shift amount must be 0 to 31"
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error occurs here

--diagnostic-format picks the output: terminal (the default), plain, or json for editors and build tools. --color auto|always|never controls color; auto also respects the NO_COLOR environment variable.

Lints

Warnings are lints. Each has a name, and a level that decides what happens when it fires.

LintFires when
unused_importAn imported name is never used.
unused_parameterA macro parameter is never used. Start its name with _ to mark it unused on purpose.
unused_doc_commentsA ## or #! doc comment doesn’t document anything. See Doc comments.
unreachable_codeA statement comes after a @return or @next that always runs.
fold_without_nextA @fold body has no @next, so its accumulators never change.
generated_declarationsMacros generated declarations. See Generating declarations.
unfulfilled_lint_expectationAn expect facet’s lint didn’t fire.
missing_docsA pub item has no ## doc comment, or a file has no #! block. Allowed by default, and not part of all. See Generating docs.

Two groups name several at once: unused (unused_import, unused_parameter and unused_doc_comments) and all.

Levels

LevelEffect
allowSilent.
expectSilent, but unfulfilled_lint_expectation fires if the lint doesn’t occur.
warnA warning. The default for every lint.
denyAn error.
forbidAn error, and no declaration can lower it.

Setting levels

On a declaration, with facets named after the level. Give one lint, or several in parentheses:

macro compatibility(value: int)
    | allow unused_parameter
    | deny(unreachable_code, generated_declarations)
{
}

expect documents a lint you know about, and tells you once it’s gone:

macro uses_it(x: int)
    | expect unused_parameter
{
    @emit x
}

uses_it 3
expected `unused_parameter` warning was not produced

(Warnings count as errors in this book’s examples.)

For a project, in bitterasm.toml:

[lints]
unused = "warn"
unreachable_code = "deny"

On the command line, which overrides the project file:

bitterasm compile program.basm -A unused_parameter
bitterasm compile program.basm -D unreachable_code

-A, -W, -D and -F set allow, warn, deny and forbid. They apply left to right, so a later flag overrides an earlier one: -D all -A unused denies every lint except the unused group. A forbidden lint can’t be lowered again, by a later flag or by a facet.

Checking without compiling

bitterasm check runs every check compile does, including lints, but writes no .em file. It takes the same options.