Skip to content

Commit 8e4f2d1

Browse files
Rollup merge of #53279 - estebank:on-unimplemented-doc, r=GuillaumeGomez
Extend documentation of `rustc_on_unimplemented`
2 parents b941c8e + d35e267 commit 8e4f2d1

File tree

1 file changed

+95
-2
lines changed

1 file changed

+95
-2
lines changed

src/doc/unstable-book/src/language-features/on-unimplemented.md

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ The tracking issue for this feature is: [#29628]
88

99
The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]`
1010
attribute, which allows trait definitions to add specialized notes to error
11-
messages when an implementation was expected but not found.
11+
messages when an implementation was expected but not found. You can refer
12+
to the trait's generic arguments by name and to the resolved type using
13+
`Self`.
1214

1315
For example:
1416

@@ -41,7 +43,98 @@ error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
4143
|
4244
= help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
4345
= note: required by `iterate_chars`
46+
```
47+
48+
`on_unimplemented` also supports advanced filtering for better targeting
49+
of messages, as well as modifying specific parts of the error message. You
50+
target the text of:
51+
52+
- the main error message (`message`)
53+
- the label (`label`)
54+
- an extra note (`note`)
55+
56+
For example, the following attribute
57+
58+
```rust,compile_fail
59+
#[rustc_on_unimplemented(
60+
message="message",
61+
label="label",
62+
note="note"
63+
)]
64+
trait MyIterator<A> {
65+
fn next(&mut self) -> A;
66+
}
67+
```
68+
69+
Would generate the following output:
70+
71+
```text
72+
error[E0277]: message
73+
--> <anon>:14:5
74+
|
75+
14 | iterate_chars(&[1, 2, 3][..]);
76+
| ^^^^^^^^^^^^^ label
77+
|
78+
= note: note
79+
= help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
80+
= note: required by `iterate_chars`
81+
```
82+
83+
To allow more targeted error messages, it is possible to filter the
84+
application of these fields based on a variety of attributes when using
85+
`on`:
4486

45-
error: aborting due to previous error
87+
- `crate_local`: whether the code causing the trait bound to not be
88+
fulfilled is part of the user's crate. This is used to avoid suggesting
89+
code changes that would require modifying a dependency.
90+
- Any of the generic arguments that can be substituted in the text can be
91+
referred by name as well for filtering, like `Rhs="i32"`, except for
92+
`Self`.
93+
- `_Self`: to filter only on a particular calculated trait resolution, like
94+
`Self="std::iter::Iterator<char>"`. This is needed because `Self` is a
95+
keyword which cannot appear in attributes.
96+
- `direct`: user-specified rather than derived obligation.
97+
- `from_method`: usable both as boolean (whether the flag is present, like
98+
`crate_local`) or matching against a particular method. Currently used
99+
for `try`.
100+
- `from_desugaring`: usable both as boolean (whether the flag is present)
101+
or matching against a particular desugaring.
102+
103+
For example, the `Iterator` trait can be annotated in the following way:
104+
105+
```rust,compile_fail
106+
#[rustc_on_unimplemented(
107+
on(
108+
_Self="&str",
109+
note="call `.chars()` or `.as_bytes()` on `{Self}"
110+
),
111+
message="`{Self}` is not an iterator",
112+
label="`{Self}` is not an iterator",
113+
note="maybe try calling `.iter()` or a similar method"
114+
)]
115+
pub trait Iterator {}
46116
```
47117

118+
Which would produce the following outputs:
119+
120+
```text
121+
error[E0277]: `Foo` is not an iterator
122+
--> src/main.rs:4:16
123+
|
124+
4 | for foo in Foo {}
125+
| ^^^ `Foo` is not an iterator
126+
|
127+
= note: maybe try calling `.iter()` or a similar method
128+
= help: the trait `std::iter::Iterator` is not implemented for `Foo`
129+
= note: required by `std::iter::IntoIterator::into_iter`
130+
131+
error[E0277]: `&str` is not an iterator
132+
--> src/main.rs:5:16
133+
|
134+
5 | for foo in "" {}
135+
| ^^ `&str` is not an iterator
136+
|
137+
= note: call `.chars()` or `.bytes() on `&str`
138+
= help: the trait `std::iter::Iterator` is not implemented for `&str`
139+
= note: required by `std::iter::IntoIterator::into_iter`
140+
```

0 commit comments

Comments
 (0)