Allows #[diagnostic::do_not_recommend] to supress trait impls in su… · rust-lang/rust@27d5db1 (original) (raw)

File tree

4 files changed

lines changed

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 +}