Allows #[diagnostic::do_not_recommend] to supress trait impls in su… · rust-lang/rust@27d5db1 (original) (raw)
File tree
4 files changed
lines changed
- compiler/rustc_trait_selection/src/error_reporting/traits
- tests/ui/diagnostic_namespace/do_not_recommend
4 files changed
lines changed
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1776,6 +1776,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ||
| 1776 | 1776 | true |
| 1777 | 1777 | }; |
| 1778 | 1778 | |
| 1779 | +// we filter before checking if `impl_candidates` is empty | |
| 1780 | +// to get the fallback solution if we filtered out any impls | |
| 1781 | +let impl_candidates = impl_candidates | |
| 1782 | +.into_iter() | |
| 1783 | +.cloned() | |
| 1784 | +.filter(|cand | |
| 1785 | + !self.tcx.has_attrs_with_path( | |
| 1786 | + cand.impl_def_id, | |
| 1787 | +&[sym::diagnostic, sym::do_not_recommend], | |
| 1788 | +) | |
| 1789 | +}) | |
| 1790 | +.collect::<Vec<_>>(); | |
| 1791 | + | |
| 1779 | 1792 | let def_id = trait_ref.def_id(); |
| 1780 | 1793 | if impl_candidates.is_empty() { |
| 1781 | 1794 | if self.tcx.trait_is_auto(def_id) |
| @@ -1788,6 +1801,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ||
| 1788 | 1801 | let mut impl_candidates: Vec<_> = self |
| 1789 | 1802 | .tcx |
| 1790 | 1803 | .all_impls(def_id) |
| 1804 | +// ignore `do_not_recommend` items | |
| 1805 | +.filter(|def_id | |
| 1806 | + !self | |
| 1807 | +.tcx | |
| 1808 | +.has_attrs_with_path(*def_id, &[sym::diagnostic, sym::do_not_recommend]) | |
| 1809 | +}) | |
| 1791 | 1810 | // Ignore automatically derived impls and `!Trait` impls. |
| 1792 | 1811 | .filter_map(|def_id |
| 1793 | 1812 | .filter_map(|header |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| 1 | +error[E0277]: the trait bound `(): Foo` is not satisfied | |
| 2 | + --> $DIR/supress_suggestions_in_help.rs:23:11 | |
| 3 | + | | |
| 4 | +LL | check(()); | |
| 5 | + | ----- ^^ the trait `Foo` is not implemented for `()` | |
| 6 | + | | |
| 7 | + | required by a bound introduced by this call | |
| 8 | + | | |
| 9 | + = help: the trait `Foo` is implemented for `i32` | |
| 10 | +note: required by a bound in `check` | |
| 11 | + --> $DIR/supress_suggestions_in_help.rs:20:18 | |
| 12 | + | | |
| 13 | +LL | fn check(a: impl Foo) {} | |
| 14 | + | ^^^ required by this bound in `check` | |
| 15 | + | |
| 16 | +error: aborting due to 1 previous error | |
| 17 | + | |
| 18 | +For more information about this error, try `rustc --explain E0277`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| 1 | +error[E0277]: the trait bound `(): Foo` is not satisfied | |
| 2 | + --> $DIR/supress_suggestions_in_help.rs:23:11 | |
| 3 | + | | |
| 4 | +LL | check(()); | |
| 5 | + | ----- ^^ the trait `Foo` is not implemented for `()` | |
| 6 | + | | |
| 7 | + | required by a bound introduced by this call | |
| 8 | + | | |
| 9 | + = help: the trait `Foo` is implemented for `i32` | |
| 10 | +note: required by a bound in `check` | |
| 11 | + --> $DIR/supress_suggestions_in_help.rs:20:18 | |
| 12 | + | | |
| 13 | +LL | fn check(a: impl Foo) {} | |
| 14 | + | ^^^ required by this bound in `check` | |
| 15 | + | |
| 16 | +error: aborting due to 1 previous error | |
| 17 | + | |
| 18 | +For more information about this error, try `rustc --explain E0277`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| 1 | +//@ revisions: current next | |
| 2 | +//@ ignore-compare-mode-next-solver (explicit revisions) | |
| 3 | +//@[next] compile-flags: -Znext-solver | |
| 4 | + | |
| 5 | +#![feature(do_not_recommend)] | |
| 6 | + | |
| 7 | +trait Foo {} | |
| 8 | + | |
| 9 | +#[diagnostic::do_not_recommend] | |
| 10 | +impl<A> Foo for (A,) {} | |
| 11 | + | |
| 12 | +#[diagnostic::do_not_recommend] | |
| 13 | +impl<A, B> Foo for (A, B) {} | |
| 14 | + | |
| 15 | +#[diagnostic::do_not_recommend] | |
| 16 | +impl<A, B, C> Foo for (A, B, C) {} | |
| 17 | + | |
| 18 | +impl Foo for i32 {} | |
| 19 | + | |
| 20 | +fn check(a: impl Foo) {} | |
| 21 | + | |
| 22 | +fn main() { | |
| 23 | +check(()); | |
| 24 | +//~^ ERROR the trait bound `(): Foo` is not satisfied | |
| 25 | +} |