# `@compileError`

### `@compileError`

`@compileError` stops compilation with a custom error message.

It does not stop the program while it is running. It stops the program from being built.

```zig
@compileError("message");
```

This means:

```text
The code is invalid. Show this message during compilation.
```

#### A Simple Example

```zig
pub fn main() void {
    comptime {
        @compileError("this code is not ready yet");
    }
}
```

When you compile this program, Zig reports the message and refuses to build the executable.

#### Why This Is Useful

`@compileError` is useful when code can detect a problem before runtime.

For example, suppose a function only supports integer types:

```zig
fn requireInteger(comptime T: type) void {
    switch (@typeInfo(T)) {
        .int => {},
        else => @compileError("expected an integer type"),
    }
}
```

Now this works:

```zig
requireInteger(u32);
```

But this fails during compilation:

```zig
requireInteger([]const u8);
```

That is better than letting invalid code continue and fail later.

#### Compile-Time Checks

A common pattern is:

```zig
comptime {
    if (condition) {
        @compileError("explanation");
    }
}
```

Example:

```zig
comptime {
    if (@sizeOf(usize) != 8) {
        @compileError("this program requires a 64-bit target");
    }
}
```

This checks the target while compiling.

If the target does not match the program’s assumptions, the build fails immediately.

#### Better Error Messages for Generic Code

Generic code can produce confusing compiler errors if you do not check inputs clearly.

Example:

```zig
fn first(comptime T: type, values: []const T) T {
    return values[0];
}
```

This works for normal slices, but maybe your API only wants integer elements.

You can enforce that:

```zig
fn firstInteger(comptime T: type, values: []const T) T {
    switch (@typeInfo(T)) {
        .int => {},
        else => @compileError("firstInteger expects an integer element type"),
    }

    return values[0];
}
```

Now the error message explains the rule directly.

#### `@compileError` Runs at Compile Time

This is valid:

```zig
comptime {
    @compileError("stop here");
}
```

This is also common inside compile-time branches:

```zig
fn maxValue(comptime T: type) T {
    return switch (@typeInfo(T)) {
        .int => std.math.maxInt(T),
        else => @compileError("maxValue only supports integer types"),
    };
}
```

The `else` branch is used only when `T` is not an integer type.

#### It Is Not Runtime Error Handling

Do not use `@compileError` for user input, file errors, network errors, or data that is only known while the program runs.

This cannot work as intended:

```zig
fn parse(text: []const u8) void {
    if (text.len == 0) {
        @compileError("empty input");
    }
}
```

`text.len` is usually a runtime value. `@compileError` is for compile-time decisions.

Use an error instead:

```zig
fn parse(text: []const u8) !void {
    if (text.len == 0) {
        return error.EmptyInput;
    }
}
```

#### `@compileError` vs `@panic`

`@compileError` stops compilation.

```zig
@compileError("bad type");
```

`@panic` stops the running program.

```zig
@panic("bad state");
```

Use `@compileError` when the code itself is invalid.

Use `@panic` when the compiled program reaches an impossible or unrecoverable state.

#### A Practical Example

```zig
const std = @import("std");

fn printNumber(comptime T: type, value: T) void {
    switch (@typeInfo(T)) {
        .int, .float, .comptime_int, .comptime_float => {},
        else => @compileError("printNumber expects a numeric type"),
    }

    std.debug.print("{}\n", .{value});
}

pub fn main() void {
    printNumber(u32, 123);
    printNumber(f64, 3.14);
}
```

This function accepts only numeric types.

If someone tries:

```zig
printNumber([]const u8, "hello");
```

the build fails with the custom message.

#### Key Idea

`@compileError(message)` stops the build with a custom message.

Use it when compile-time code detects invalid types, unsupported targets, impossible configurations, or unfinished compile-time branches.

