diff options
| author | Gurinder Singh <frederick.the.fool@gmail.com> | 2024-02-10 16:05:39 +0530 |
|---|---|---|
| committer | Gurinder Singh <frederick.the.fool@gmail.com> | 2024-02-10 16:05:39 +0530 |
| commit | 0815067796a653ac9dbf95ff651d74074a4b3788 (patch) | |
| tree | 2e5125b64d5aa6c417d9977064c8b917e8e7c8a3 | |
| parent | 98aa3624be70462d6a25ed5544333e3df62f4c66 (diff) | |
| download | rust-0815067796a653ac9dbf95ff651d74074a4b3788.tar.gz rust-0815067796a653ac9dbf95ff651d74074a4b3788.zip | |
Take empty `where` into account when suggesting predicates
| -rw-r--r-- | compiler/rustc_middle/src/ty/diagnostics.rs | 8 | ||||
| -rw-r--r-- | tests/ui/trait-impl-bound-suggestions.fixed | 9 | ||||
| -rw-r--r-- | tests/ui/trait-impl-bound-suggestions.rs | 9 | ||||
| -rw-r--r-- | tests/ui/trait-impl-bound-suggestions.stderr | 18 |
4 files changed, 42 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 13cc5cbed44..7cb326ce696 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -358,11 +358,17 @@ pub fn suggest_constraining_type_params<'a>( // trait Foo<T=()> {... } // - insert: `where T: Zar` if matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. }) { + // If we are here and the where clause span is of non-zero length + // it means we're dealing with an empty where clause like this: + // fn foo<X>(x: X) where { ... } + // In that case we don't want to add another "where" (Fixes #120838) + let where_prefix = if generics.where_clause_span.is_empty() { " where" } else { "" }; + // Suggest a bound, but there is no existing `where` clause *and* the type param has a // default (`<T=Foo>`), so we suggest adding `where T: Bar`. suggestions.push(( generics.tail_span_for_predicate_suggestion(), - format!(" where {param_name}: {constraint}"), + format!("{where_prefix} {param_name}: {constraint}"), SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name }, )); continue; diff --git a/tests/ui/trait-impl-bound-suggestions.fixed b/tests/ui/trait-impl-bound-suggestions.fixed index 744e7bef04e..fb11286a175 100644 --- a/tests/ui/trait-impl-bound-suggestions.fixed +++ b/tests/ui/trait-impl-bound-suggestions.fixed @@ -17,4 +17,13 @@ trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy { } } +// Regression test for #120838 +#[allow(dead_code)] +trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where X: std::marker::Copy { + fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { + //~^ ERROR the trait bound `X: Copy` is not satisfied + ConstrainedStruct { x } + } +} + pub fn main() { } diff --git a/tests/ui/trait-impl-bound-suggestions.rs b/tests/ui/trait-impl-bound-suggestions.rs index bf75175179e..46130a5e766 100644 --- a/tests/ui/trait-impl-bound-suggestions.rs +++ b/tests/ui/trait-impl-bound-suggestions.rs @@ -17,4 +17,13 @@ trait InsufficientlyConstrainedGeneric<X=()> { } } +// Regression test for #120838 +#[allow(dead_code)] +trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where { + fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { + //~^ ERROR the trait bound `X: Copy` is not satisfied + ConstrainedStruct { x } + } +} + pub fn main() { } diff --git a/tests/ui/trait-impl-bound-suggestions.stderr b/tests/ui/trait-impl-bound-suggestions.stderr index c1f31e2b32e..9883c5bda01 100644 --- a/tests/ui/trait-impl-bound-suggestions.stderr +++ b/tests/ui/trait-impl-bound-suggestions.stderr @@ -14,6 +14,22 @@ help: consider further restricting type parameter `X` LL | trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy { | ++++++++++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `X: Copy` is not satisfied + --> $DIR/trait-impl-bound-suggestions.rs:23:52 + | +LL | fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct<X> { + | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `X` + | +note: required by a bound in `ConstrainedStruct` + --> $DIR/trait-impl-bound-suggestions.rs:8:29 + | +LL | struct ConstrainedStruct<X: Copy> { + | ^^^^ required by this bound in `ConstrainedStruct` +help: consider further restricting type parameter `X` + | +LL | trait InsufficientlyConstrainedGenericWithEmptyWhere<X=()> where X: std::marker::Copy { + | ++++++++++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. |
