@@ -8,7 +8,9 @@ The tracking issue for this feature is: [#29628]
8
8
9
9
The ` on_unimplemented ` feature provides the ` #[rustc_on_unimplemented] `
10
10
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 ` .
12
14
13
15
For example:
14
16
@@ -41,7 +43,98 @@ error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
41
43
|
42
44
= help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
43
45
= 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 ` :
44
86
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 {}
46
116
```
47
117
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