diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 4bf22337991..f479b18c7c4 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -271,6 +271,19 @@ pub fn suggest_constraining_type_params<'a>( } } + // in the scenario like impl has stricter requirements than trait, + // we should not suggest restrict bound on the impl, here we double check + // the whether the param already has the constraint by checking `def_id` + let bound_trait_defs: Vec = generics + .bounds_for_param(param.def_id) + .flat_map(|bound| { + bound.bounds.iter().flat_map(|b| b.trait_ref().and_then(|t| t.trait_def_id())) + }) + .collect(); + + constraints + .retain(|(_, def_id)| def_id.map_or(true, |def| !bound_trait_defs.contains(&def))); + if constraints.is_empty() { continue; } @@ -332,6 +345,7 @@ pub fn suggest_constraining_type_params<'a>( // -- // | // replace with: `T: Bar +` + if let Some((span, open_paren_sp)) = generics.bounds_span_for_suggestions(param.def_id) { suggest_restrict(span, true, open_paren_sp); continue; diff --git a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr index adde31b4a32..b4012d2a5b9 100644 --- a/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr +++ b/tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr @@ -3,11 +3,6 @@ error[E0277]: the trait bound `T: Foo` is not satisfied | LL | let u: >::Bar = t.get_bar(); | ^ the trait `Foo` is not implemented for `T` - | -help: consider further restricting this bound - | -LL | fn f + Foo>(t: &T) { - | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.rs b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.rs new file mode 100644 index 00000000000..6083cc7d96d --- /dev/null +++ b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.rs @@ -0,0 +1,23 @@ +//@ edition:2021 +// issue: rust-lang/rust#127555 + +pub trait Foo { + fn bar(&mut self, func: F) -> impl std::future::Future + Send + where + F: FnMut(); +} + +struct Baz {} + +impl Foo for Baz { + async fn bar(&mut self, _func: F) -> () + //~^ ERROR `F` cannot be sent between threads safely + where + F: FnMut() + Send, + //~^ ERROR impl has stricter requirements than trait + { + () + } +} + +fn main() {} diff --git a/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.stderr b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.stderr new file mode 100644 index 00000000000..7f3cd2a5900 --- /dev/null +++ b/tests/ui/associated-types/remove-invalid-type-bound-suggest-issue-127555.stderr @@ -0,0 +1,33 @@ +error[E0277]: `F` cannot be sent between threads safely + --> $DIR/remove-invalid-type-bound-suggest-issue-127555.rs:13:5 + | +LL | / async fn bar(&mut self, _func: F) -> () +LL | | +LL | | where +LL | | F: FnMut() + Send, + | |__________________________^ `F` cannot be sent between threads safely + | +note: required by a bound in `::bar` + --> $DIR/remove-invalid-type-bound-suggest-issue-127555.rs:16:22 + | +LL | async fn bar(&mut self, _func: F) -> () + | --- required by a bound in this associated function +... +LL | F: FnMut() + Send, + | ^^^^ required by this bound in `::bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/remove-invalid-type-bound-suggest-issue-127555.rs:16:22 + | +LL | / fn bar(&mut self, func: F) -> impl std::future::Future + Send +LL | | where +LL | | F: FnMut(); + | |___________________- definition of `bar` from trait +... +LL | F: FnMut() + Send, + | ^^^^ impl has extra requirement `F: Send` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0276, E0277. +For more information about an error, try `rustc --explain E0276`. diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr index 66819d1fcf7..80dc5fdc747 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr @@ -9,10 +9,6 @@ note: required by a bound in `<() as Actor>::on_mount` | LL | async fn on_mount(self, _: impl Inbox<&'a ()>) {} | ^^^^^^^^^^^^^ required by this bound in `<() as Actor>::on_mount` -help: consider further restricting this bound - | -LL | async fn on_mount(self, _: impl Inbox<&'a ()> + Inbox<&'a ()>) {} - | +++++++++++++++ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained-impl-region.rs:13:6 diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr index 8771de85c19..3697bd9cf02 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr @@ -9,10 +9,6 @@ note: required by a bound in `impl_hr` | LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr` -help: consider further restricting this bound - | -LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static> + for<'a> Trait<'a, '_>>() { - | +++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr index 90df487c07e..6e0ec5620da 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr @@ -9,10 +9,6 @@ note: required by a bound in `trait_bound` | LL | fn trait_bound Trait<'a>>() {} | ^^^^^^^^^^^^^^^^^ required by this bound in `trait_bound` -help: consider further restricting this bound - | -LL | fn function1 + for<'a> Trait<'a>>() { - | +++++++++++++++++++ error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied --> $DIR/candidate-from-env-universe-err-project.rs:38:24 @@ -25,10 +21,6 @@ note: required by a bound in `projection_bound` | LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound` -help: consider further restricting this bound - | -LL | fn function2 + for<'a> Trait<'a>>() { - | +++++++++++++++++++ error[E0271]: type mismatch resolving `>::Assoc == usize` --> $DIR/candidate-from-env-universe-err-project.rs:38:24 diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr index af76377de85..dc1a4c9b983 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr @@ -11,10 +11,6 @@ note: required by a bound in `want_foo_for_any_tcx` | LL | fn want_foo_for_any_tcx Foo<'tcx>>(f: &F) { | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` -help: consider further restricting this bound - | -LL | fn want_foo_for_some_tcx<'x, F: Foo<'x> + for<'tcx> Foo<'tcx>>(f: &'x F) { - | +++++++++++++++++++++ error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied --> $DIR/hrtb-higher-ranker-supertraits.rs:28:26 @@ -29,10 +25,6 @@ note: required by a bound in `want_bar_for_any_ccx` | LL | fn want_bar_for_any_ccx Bar<'ccx>>(b: &B) { | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` -help: consider further restricting this bound - | -LL | fn want_bar_for_some_ccx<'x, B: Bar<'x> + for<'ccx> Bar<'ccx>>(b: &B) { - | +++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index fbf82a24b50..ae449099987 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -22,10 +22,6 @@ note: required by a bound in `>::foo` | LL | fn foo>(self) -> impl Foo { | ^^^^^^^ required by this bound in `>::foo` -help: consider further restricting this bound - | -LL | fn foo + Foo>(self) -> impl Foo { - | +++++++++ error[E0276]: impl has stricter requirements than trait --> $DIR/return-dont-satisfy-bounds.rs:8:16