diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2018-08-15 19:20:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-15 19:20:22 +0200 |
| commit | 8e4f2d115ac5b3395c4f9b8b9bf89b63c35e8b14 (patch) | |
| tree | 26de7b4ecd8b6fea305d0d50f14e15567f10dd34 | |
| parent | b941c8e7fb5f4bea759ef0937c82fce3a1fd1220 (diff) | |
| parent | d35e2677fc11155d9ba197400b6bd9a3f022ed5c (diff) | |
| download | rust-8e4f2d115ac5b3395c4f9b8b9bf89b63c35e8b14.tar.gz rust-8e4f2d115ac5b3395c4f9b8b9bf89b63c35e8b14.zip | |
Rollup merge of #53279 - estebank:on-unimplemented-doc, r=GuillaumeGomez
Extend documentation of `rustc_on_unimplemented`
| -rw-r--r-- | src/doc/unstable-book/src/language-features/on-unimplemented.md | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/src/doc/unstable-book/src/language-features/on-unimplemented.md b/src/doc/unstable-book/src/language-features/on-unimplemented.md index 70c7c110b78..f787f629756 100644 --- a/src/doc/unstable-book/src/language-features/on-unimplemented.md +++ b/src/doc/unstable-book/src/language-features/on-unimplemented.md @@ -8,7 +8,9 @@ The tracking issue for this feature is: [#29628] The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]` attribute, which allows trait definitions to add specialized notes to error -messages when an implementation was expected but not found. +messages when an implementation was expected but not found. You can refer +to the trait's generic arguments by name and to the resolved type using +`Self`. For example: @@ -41,7 +43,98 @@ error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied | = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]` = note: required by `iterate_chars` +``` + +`on_unimplemented` also supports advanced filtering for better targeting +of messages, as well as modifying specific parts of the error message. You +target the text of: + + - the main error message (`message`) + - the label (`label`) + - an extra note (`note`) + +For example, the following attribute + +```rust,compile_fail +#[rustc_on_unimplemented( + message="message", + label="label", + note="note" +)] +trait MyIterator<A> { + fn next(&mut self) -> A; +} +``` + +Would generate the following output: + +```text +error[E0277]: message + --> <anon>:14:5 + | +14 | iterate_chars(&[1, 2, 3][..]); + | ^^^^^^^^^^^^^ label + | + = note: note + = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]` + = note: required by `iterate_chars` +``` + +To allow more targeted error messages, it is possible to filter the +application of these fields based on a variety of attributes when using +`on`: -error: aborting due to previous error + - `crate_local`: whether the code causing the trait bound to not be + fulfilled is part of the user's crate. This is used to avoid suggesting + code changes that would require modifying a dependency. + - Any of the generic arguments that can be substituted in the text can be + referred by name as well for filtering, like `Rhs="i32"`, except for + `Self`. + - `_Self`: to filter only on a particular calculated trait resolution, like + `Self="std::iter::Iterator<char>"`. This is needed because `Self` is a + keyword which cannot appear in attributes. + - `direct`: user-specified rather than derived obligation. + - `from_method`: usable both as boolean (whether the flag is present, like + `crate_local`) or matching against a particular method. Currently used + for `try`. + - `from_desugaring`: usable both as boolean (whether the flag is present) + or matching against a particular desugaring. + +For example, the `Iterator` trait can be annotated in the following way: + +```rust,compile_fail +#[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` +``` |
