about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs19
-rw-r--r--tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr18
-rw-r--r--tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr18
-rw-r--r--tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs25
4 files changed, 80 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index f7ec5f1ff32..2e6247b4640 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1776,6 +1776,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             true
         };
 
+        // we filter before checking if `impl_candidates` is empty
+        // to get the fallback solution if we filtered out any impls
+        let impl_candidates = impl_candidates
+            .into_iter()
+            .cloned()
+            .filter(|cand| {
+                !self.tcx.has_attrs_with_path(
+                    cand.impl_def_id,
+                    &[sym::diagnostic, sym::do_not_recommend],
+                )
+            })
+            .collect::<Vec<_>>();
+
         let def_id = trait_ref.def_id();
         if impl_candidates.is_empty() {
             if self.tcx.trait_is_auto(def_id)
@@ -1788,6 +1801,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             let mut impl_candidates: Vec<_> = self
                 .tcx
                 .all_impls(def_id)
+                // ignore `do_not_recommend` items
+                .filter(|def_id| {
+                    !self
+                        .tcx
+                        .has_attrs_with_path(*def_id, &[sym::diagnostic, sym::do_not_recommend])
+                })
                 // Ignore automatically derived impls and `!Trait` impls.
                 .filter_map(|def_id| self.tcx.impl_trait_header(def_id))
                 .filter_map(|header| {
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr
new file mode 100644
index 00000000000..629fc59361d
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/supress_suggestions_in_help.rs:23:11
+   |
+LL |     check(());
+   |     ----- ^^ the trait `Foo` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Foo` is implemented for `i32`
+note: required by a bound in `check`
+  --> $DIR/supress_suggestions_in_help.rs:20:18
+   |
+LL | fn check(a: impl Foo) {}
+   |                  ^^^ required by this bound in `check`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr
new file mode 100644
index 00000000000..629fc59361d
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/supress_suggestions_in_help.rs:23:11
+   |
+LL |     check(());
+   |     ----- ^^ the trait `Foo` is not implemented for `()`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Foo` is implemented for `i32`
+note: required by a bound in `check`
+  --> $DIR/supress_suggestions_in_help.rs:20:18
+   |
+LL | fn check(a: impl Foo) {}
+   |                  ^^^ required by this bound in `check`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs
new file mode 100644
index 00000000000..ef6f255c351
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+#![feature(do_not_recommend)]
+
+trait Foo {}
+
+#[diagnostic::do_not_recommend]
+impl<A> Foo for (A,) {}
+
+#[diagnostic::do_not_recommend]
+impl<A, B> Foo for (A, B) {}
+
+#[diagnostic::do_not_recommend]
+impl<A, B, C> Foo for (A, B, C) {}
+
+impl Foo for i32 {}
+
+fn check(a: impl Foo) {}
+
+fn main() {
+    check(());
+    //~^ ERROR the trait bound `(): Foo` is not satisfied
+}