Home Explore Blog CI



rustc

3rd chunk of `src/tests/ui.md`
629931508b0eb5e4c094240eb97ba21c8bc867aab30794890000000100000fa3
line/column information would be retained, but small changes to the source
causes large diffs, and more frequent merge conflicts and test errors.

Sometimes these built-in normalizations are not enough. In such cases, you may
provide custom normalization rules using `normalize-*` directives, e.g.

```rust,ignore
//@ normalize-stdout: "foo" -> "bar"
//@ normalize-stderr: "foo" -> "bar"
//@ normalize-stderr-32bit: "fn\(\) \(32 bits\)" -> "fn\(\) \($$PTR bits\)"
//@ normalize-stderr-64bit: "fn\(\) \(64 bits\)" -> "fn\(\) \($$PTR bits\)"
```

This tells the test, on 32-bit platforms, whenever the compiler writes `fn() (32
bits)` to stderr, it should be normalized to read `fn() ($PTR bits)` instead.
Similar for 64-bit. The replacement is performed by regexes using default regex
flavor provided by `regex` crate.

The corresponding reference file will use the normalized output to test both
32-bit and 64-bit platforms:

```text
...
   |
   = note: source type: fn() ($PTR bits)
   = note: target type: u16 (16 bits)
...
```

Please see [`ui/transmute/main.rs`][mrs] and [`main.stderr`] for a concrete
usage example.


## Error annotations

Error annotations specify the errors that the compiler is expected to emit. They
are "attached" to the line in source where the error is located.

```rust,ignore
fn main() {
    boom  //~ ERROR cannot find value `boom` in this scope [E0425]
}
```

Although UI tests have a `.stderr` file which contains the entire compiler
output, UI tests require that errors are also annotated within the source. This
redundancy helps avoid mistakes since the `.stderr` files are usually
auto-generated. It also helps to directly see where the error spans are expected
to point to by looking at one file instead of having to compare the `.stderr`
file with the source. Finally, they ensure that no additional unexpected errors
are generated.

They have several forms, but generally are a comment with the diagnostic level
(such as `ERROR`) and a substring of the expected error output. You don't have
to write out the entire message, just make sure to include the important part of
the message to make it self-documenting.

Most error annotations need to match with the line of the diagnostic. There are
several ways to match the message with the line (see the examples below):

* `~`: Associates the error level and message with the *current* line
* `~^`: Associates the error level and message with the *previous* error
  annotation line. Each caret (`^`) that you add adds a line to this, so `~^^^`
  is three lines above the error annotation line.
* `~|`: Associates the error level and message with the *same* line as the
  *previous comment*. This is more convenient than using multiple carets when
  there are multiple messages associated with the same line.
* `~v`: Associates the error level and message with the *next* error
  annotation line. Each symbol (`v`) that you add adds a line to this, so `~vvv`
  is three lines below the error annotation line.

Example:

```rust,ignore
let _ = same_line; //~ ERROR undeclared variable
fn meow(_: [u8]) {}
//~^ ERROR unsized
//~| ERROR anonymous parameters
```

The space character between `//~` (or other variants) and the subsequent text is
negligible (i.e. there is no semantic difference between `//~ ERROR` and
`//~ERROR` although the former is more common in the codebase).

`~? <diagnostic kind>` (example being `~? ERROR`)
is used to match diagnostics _without_ line info at all,
or where the line info is outside the main test file[^main test file].
These annotations can be placed on any line in the test file.

as distinct from aux files, or sources that we have no control over.

### Error annotation examples

Here are examples of error annotations on different lines of UI test source.

#### Positioned on error line

Use the `//~ ERROR` idiom:

```rust,ignore
fn main() {
    let x = (1, 2, 3);
    match x {
        (_a, _x @ ..) => {} //~ ERROR `_x @` is not allowed in a tuple
        _ => {}
    }

Title: Custom Normalization, Error Annotations in UI Tests
Summary
Custom normalization rules can be defined using `normalize-*` directives to handle specific cases, employing regular expressions for replacements. Error annotations are added to the source code to specify expected compiler errors, which helps avoid mistakes and ensures that no additional unexpected errors are generated. Annotations are linked to specific lines using `~`, `~^`, `~|`, and `~v` to indicate the relative position of the error. `~?` matches diagnostics without line info or outside the main test file. The example demonstrates error annotations on different lines of UI test source.