From 54e11c96a6687898527587654a9aeeddd302b4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 11 Aug 2018 14:54:45 -0700 Subject: [PATCH 1/2] Extend documentation of `rustc_on_unimplemented` --- .../src/language-features/on-unimplemented.md | 97 ++++++++++++++++++- 1 file 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 70c7c110b786a..52969c9b896bb 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` is not satisfied | = help: the trait `MyIterator` 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 { + fn next(&mut self) -> A; +} +``` + +Would generate the following output: + +```text +error[E0277]: message + --> :14:5 + | +14 | iterate_chars(&[1, 2, 3][..]); + | ^^^^^^^^^^^^^ label + | + = note: note + = help: the trait `MyIterator` is not implemented for `&[{integer}]` + = note: required by `iterate_chars` +``` + +To allow for 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"`. 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` +``` From d35e2677fc11155d9ba197400b6bd9a3f022ed5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Aug 2018 12:57:21 -0700 Subject: [PATCH 2/2] review comment --- src/doc/unstable-book/src/language-features/on-unimplemented.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 52969c9b896bb..f787f629756f3 100644 --- a/src/doc/unstable-book/src/language-features/on-unimplemented.md +++ b/src/doc/unstable-book/src/language-features/on-unimplemented.md @@ -80,7 +80,7 @@ error[E0277]: message = note: required by `iterate_chars` ``` -To allow for more targeted error messages, it is possible to filter the +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`: