Skip to content

Commit 6fc4148

Browse files
committed
Some more elaboration on do_not_recommend
This adds some more explanation about the use of `diagnostic::do_not_recommend`, with the intent of helping the reader to understand how to use it. This also breaks that discussion out into a note. This also adds a before/after to the example to better show how it changes.
1 parent f28b8e8 commit 6fc4148

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

src/attributes/diagnostics.md

+32-12
Original file line numberDiff line numberDiff line change
@@ -564,50 +564,70 @@ error[E0277]: My Message for `ImportantTrait<i32>` implemented for `String`
564564
r[attributes.diagnostic.do_not_recommend]
565565

566566
r[attributes.diagnostic.do_not_recommend.intro]
567-
The `#[diagnostic::do_not_recommend]` attribute is a hint to the compiler to not show the annotated trait implementation as part of a diagnostic message. For example, in an error message about a type not implementing a required trait, the compiler may indicate that an unsatisfied trait bound is a result of the given trait implementation. The `#[diagnostic::do_not_recommend]` attribute can be used to prevent those annotations about the trait implementation from being included in the diagnostic when they are unlikely to be useful.
567+
The `#[diagnostic::do_not_recommend]` attribute is a hint to the compiler to not show the annotated trait implementation as part of a diagnostic message.
568+
569+
> **Note**: Suppressing the recommendation can be useful if you know that the recommendation would not be useful to the programmer. This often occurs with broad, blanket impls. The recommendation may send the programmer down the wrong path, or the trait implementation may be an internal detail that you don't want to expose, or the bounds may not be able to be satisfied by the programmer.
570+
>
571+
> For example, in an error message about a type not implementing a required trait, the compiler may find a trait implementation that would satisfy the requirements if it weren't for specific bounds in the trait implementation. The compiler may tell the user that there is an impl, but the problem is the bounds in the trait implementation. The `#[diagnostic::do_not_recommend]` attribute can be used to tell the compiler to *not* tell the user about the trait implementation, and instead simply tell the user the type doesn't implement the required trait.
568572
569573
r[attributes.diagnostic.do_not_recommend.allowed-positions]
570574
The attribute should be placed on a [trait implementation item][trait-impl], though it is not an error to be located in other positions.
571575

572576
r[attributes.diagnostic.do_not_recommend.syntax]
573577
The attribute does not accept any arguments, though unexpected arguments are not considered as an error.
574578

575-
In this example:
579+
In this example,
576580

577581
```rust,compile_fail,E0277
578582
trait Foo {}
579583
580-
#[diagnostic::do_not_recommend]
581584
impl<T> Foo for T where T: Send {}
582585
583586
fn needs_foo<T: Foo>() {}
584587
585588
fn main() {
589+
// Mutable pointers do not implement `Send`, so this will not work.
586590
needs_foo::<*mut ()>();
587591
}
592+
```
593+
594+
the compiler may generate an error message about the `Send` bound in the impl which looks like this:
588595

596+
```text
597+
error[E0277]: the trait bound `*mut (): Foo` is not satisfied
598+
--> src/main.rs:9:17
599+
|
600+
9 | needs_foo::<*mut ()>();
601+
| ^^^^^^^ the trait `Send` is not implemented for `*mut ()`
602+
|
603+
note: required for `*mut ()` to implement `Foo`
604+
--> src/main.rs:3:9
605+
|
606+
3 | impl<T> Foo for T where T: Send {}
607+
| ^^^ ^ ---- unsatisfied trait bound introduced here
608+
note: required by a bound in `needs_foo`
609+
--> src/main.rs:5:17
610+
|
611+
5 | fn needs_foo<T: Foo>() {}
612+
| ^^^ required by this bound in `needs_foo`
589613
```
590614

591-
the compiler may generate an error message which looks like this:
615+
By adding the `#[diagnostic::do_no_recommend]` attribute to the `impl`, the message would no longer suggest it:
592616

593617
```text
594618
error[E0277]: the trait bound `*mut (): Foo` is not satisfied
595-
--> $DIR/simple.rs:15:17
619+
--> src/main.rs:11:17
596620
|
597-
LL | needs_foo::<*mut ()>();
621+
11 | needs_foo::<*mut ()>();
598622
| ^^^^^^^ the trait `Foo` is not implemented for `*mut ()`
599623
|
600624
note: required by a bound in `needs_foo`
601-
--> $DIR/simple.rs:10:17
625+
--> src/main.rs:7:17
602626
|
603-
LL | fn needs_foo<T: Foo>() {}
627+
7 | fn needs_foo<T: Foo>() {}
604628
| ^^^ required by this bound in `needs_foo`
605-
606-
error: aborting due to 1 previous error
607629
```
608630

609-
Without the attribute the compiler would complain about `Send` not being implemented for `*mut ()` due to the required bounds in the implementation.
610-
611631
[Clippy]: https://github.com/rust-lang/rust-clippy
612632
[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
613633
[_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax

0 commit comments

Comments
 (0)