Rollup merge of #127598 - weiznich:diagnostic_do_not_recommend_also_s… · rust-lang/rust@a10b4d1

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 numberDiff line numberDiff line change

@@ -1776,6 +1776,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {

17761776

true

17771777

};

17781778
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+
17791792

let def_id = trait_ref.def_id();

17801793

if impl_candidates.is_empty() {

17811794

if self.tcx.trait_is_auto(def_id)

@@ -1788,6 +1801,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {

17881801

let mut impl_candidates: Vec<_> = self

17891802

.tcx

17901803

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

})

17911810

// Ignore automatically derived impls and `!Trait` impls.

17921811

.filter_map(|def_id| self.tcx.impl_trait_header(def_id))

17931812

.filter_map(|header| {

Original file line numberDiff line numberDiff 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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+

}