# Error codes

Every C+ diagnostic carries a numbered code, a source span, and often a machine-applicable suggestion. `cpc --diagnostics=json` emits the same information in a machine-readable shape for editors and agents. Codes prefixed with **W** are non-fatal warnings; the build continues.

These are the codes you will see most often. The full set lives in the compiler's `sema` and `borrowck` passes.

## Names, types, and items

| Code | Meaning | Typical fix |
|---|---|---|
| E0300 | Undefined name | Typo, missing import, or forgotten `pub` |
| E0301 | Duplicate definition | Two items share the same name |
| E0302 | Type mismatch | Insert an `as` cast or change the declared type |
| E0303 | Unknown type | Typo, missing import, or a generic param not in scope |
| E0312 | Function used as value | Assign to a `fn(...)`-typed binding to take the address |
| E0315 | Invalid cast | Some pairs are forbidden (for example `int` to `bool`, `*T` to `i32`) |
| E0319–0322 | Struct field issues (duplicate / unknown / missing / extra) | Match the declaration |
| E0325 | `impl` on an unknown or non-struct type | The target must be a declared struct or enum in scope |
| E0327 | Wrong call form | `Type::method()` for associated, `value.method()` for instance |

## Control flow and matching

| Code | Meaning | Typical fix |
|---|---|---|
| E0333 | Implicit return | Add an explicit `return EXPR;` |
| E0335 | Use of a moved value | Do not read after a `move` |
| E0340 | Non-exhaustive match | Add the missing arm or a `_ =>` catch-all |
| E0345 | Use of a possibly-unassigned binding | Initialize on every control-flow path |
| E0353 | `break` / `continue` outside a loop | Move it into a loop body |
| E0354 | Unknown attribute | Typo (the compiler suggests a fix) |
| E0356 | Wrong attribute target | Some attributes are function-only, others struct-only |

## Ownership and borrowing

| Code | Meaning | Typical fix |
|---|---|---|
| E0370–0386 | Borrow checker conflicts | Each variant has a specific message; read it |
| E0411 | `restrict` on a non-pointer param | Only `*T` accepts `restrict`; remove it or change the type |
| E0509 | Move of a field out of a `Drop` type | Clone the field, or restructure so it is not owned by a `Drop` type |
| E0510 | Unaccounted raw-pointer field in a `Drop` type (no releasing `drop`, not `opaque`) | Release it in `drop` (`free(self.f)`), or mark the field `opaque` if another owner frees it |
| E0511 | Return type names a borrow region no parameter declares | Add a same-region parameter, or drop the region |
| E0512 | Returned borrow's region differs from the declared return region | Return a borrow from a same-region parameter |
| E0513 | Returning a `str` / `T[]` view of a local that drops | Return an owned value, or borrow from a parameter |

## Generics and bounds

| Code | Meaning | Typical fix |
|---|---|---|
| E0500 | Cannot infer a type parameter | Use the `name::[T1, T2](...)` turbofish |
| E0501 | Wrong type-argument count | Match the generic parameter list |
| E0502 | Bound not satisfied | `T: Ord` requires `impl Ord for T` (also fired for `!Send` / `!Sync` across threads) |

## Unsafe, FFI, and intrinsics

| Code | Meaning | Typical fix |
|---|---|---|
| E0801 | Operation requires `unsafe` | Wrap it in `unsafe { ... }` |
| E0821 | Cannot take the address of a generic function | Specify the type parameters at the take-address site |
| E0876 | `#env("X")`: env var not set at compile time | Set the variable when invoking `cpc`, or pick a different default |
| E0905 | Unknown compiler intrinsic `#name` | Typo; check the [intrinsics](/docs/intrinsics) list |

## Real-time contracts

| Code | Meaning | Typical fix |
|---|---|---|
| E0900 | Borrow-shaped param in an `async fn` | Use `string` / `Vec[T]` instead of `str` / `T[]` |
| E0901 | `#[no_alloc]` violation | A function or callee heap-allocates or interpolates a string; remove it or drop the contract |
| E0906 | `#[bounded_recursion]` violation | The call graph cycles back to the function; break the recursion |
| E0907 | `#[no_block]` violation | A function or callee calls a blocking primitive; use a non-blocking API |
| E0908 | `#[max_stack(N)]` exceeded | The estimated frame is over `N` bytes; shrink locals or raise the budget |

## Warnings

| Code | Meaning | Typical fix |
|---|---|---|
| W0001 | `sum()` / `product()` over narrow integer SIMD lanes silently wraps | `.widen()` the lanes first, or use [`simd/integer::dot_i32`](/docs/packages/simd) |
| W0002 | A raw-pointer field in a `Drop` type is freed only conditionally, so it cannot be proven to always run | Confirm it frees on every owning path (expected for refcounted types) |
