@@ -8,7 +8,9 @@ The tracking issue for this feature is: [#29628]
88
99The ` on_unimplemented ` feature provides the ` #[rustc_on_unimplemented] `
1010attribute, 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
1315For 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