Home Explore Blog CI



rustc

15th chunk of `src/diagnostics.md`
1c25aedc3a56946e5d5acd90fafd52137f36b4ae3411700a0000000100000d36
 - `cause`: Match against one variant of the `ObligationCauseCode`
   enum. Only `"MainFunctionType"` is supported.
 - `from_desugaring`: Match against a particular variant of the `DesugaringKind`
   enum. The desugaring is identified by its variant name, for example
   `"QuestionMark"` for `?` desugaring or `"TryBlock"` for `try` blocks.
 - `Self` and any generic arguments of the trait, like `Self = "alloc::string::String"`
   or `Rhs="i32"`.
   
The compiler can provide several values to match on, for example:
  - the self_ty, pretty printed with and without type arguments resolved.
  - `"{integral}"`, if self_ty is an integral of which the type is known.
  - `"[]"`, `"[{ty}]"`, `"[{ty}; _]"`, `"[{ty}; $N]"` when applicable.
  - references to said slices and arrays.
  - `"fn"`, `"unsafe fn"` or `"#[target_feature] fn"` when self is a function.
  - `"{integer}"` and `"{float}"` if the type is a number but we haven't inferred it yet.
  - combinations of the above, like `"[{integral}; _]"`.

For example, the `Iterator` trait can be filtered in the following way:

```rust,ignore
#[rustc_on_unimplemented(
    on(Self = "&str", note = "call `.chars()` or `.as_bytes()` on `{Self}`"),
    message = "`{Self}` is not an iterator",
    label = "`{Self}` is not an iterator",
    note = "maybe try calling `.iter()` or a similar method"
)]
pub trait Iterator {}
```

Which would produce the following outputs:

```text
error[E0277]: `Foo` is not an iterator
 --> src/main.rs:4:16
  |
4 |     for foo in Foo {}
  |                ^^^ `Foo` is not an iterator
  |
  = note: maybe try calling `.iter()` or a similar method
  = help: the trait `std::iter::Iterator` is not implemented for `Foo`
  = note: required by `std::iter::IntoIterator::into_iter`

error[E0277]: `&str` is not an iterator
 --> src/main.rs:5:16
  |
5 |     for foo in "" {}
  |                ^^ `&str` is not an iterator
  |
  = note: call `.chars()` or `.bytes() on `&str`
  = help: the trait `std::iter::Iterator` is not implemented for `&str`
  = note: required by `std::iter::IntoIterator::into_iter`
```

The `on` filter accepts `all`, `any` and `not` predicates similar to the `cfg` attribute:

```rust,ignore
#[rustc_on_unimplemented(on(
    all(Self = "&str", T = "alloc::string::String"),
    note = "you can coerce a `{T}` into a `{Self}` by writing `&*variable`"
))]
pub trait From<T>: Sized {
    /* ... */
}
```

### Formatting 

The string literals are format strings that accept parameters wrapped in braces
but positional and listed parameters and format specifiers are not accepted.
The following parameter names are valid:
- `Self` and all generic parameters of the trait.
- `This`: the name of the trait the attribute is on, without generics.
- `Trait`: the name of the "sugared" trait. See `TraitRefPrintSugared`.
- `ItemContext`: the kind of `hir::Node` we're in, things like `"an async block"`,
   `"a function"`, `"an async function"`, etc.

Something like:

```rust,ignore
#![feature(rustc_attrs)]

#[rustc_on_unimplemented(message = "Self = `{Self}`, \
    T = `{T}`, this = `{This}`, trait = `{Trait}`, \
    context = `{ItemContext}`")]
pub trait From<T>: Sized {
    fn from(x: T) -> Self;
}

fn main() {
    let x: i8 = From::from(42_i32);
}
```

Will format the message into 
```text
"Self = `i8`, T = `i32`, this = `From`, trait = `From<i32>`, context = `a function`"
```

Title: `#[rustc_on_unimplemented]` Filtering Examples and Formatting Options
Summary
This section provides examples of using the `on` filter in `#[rustc_on_unimplemented]` with the `Iterator` and `From` traits, demonstrating how to create targeted error messages based on the type `Self` and other generic parameters. It also covers the use of `all`, `any`, and `not` predicates for complex filtering. Additionally, it explains the formatting options for the message string, allowing the inclusion of parameters like `Self`, `T`, `This`, `Trait`, and `ItemContext` to provide more informative error messages.