Rollup merge of #120874 - gurry:120838-extra-where-in-suggestion, r=fmease
Take empty `where` bounds into account when suggesting predicates Fixes #120838
This commit is contained in:
commit
0171057e66
4 changed files with 42 additions and 2 deletions
|
@ -358,11 +358,17 @@ pub fn suggest_constraining_type_params<'a>(
|
||||||
// trait Foo<T=()> {... }
|
// trait Foo<T=()> {... }
|
||||||
// - insert: `where T: Zar`
|
// - insert: `where T: Zar`
|
||||||
if matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. }) {
|
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
|
// 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`.
|
// default (`<T=Foo>`), so we suggest adding `where T: Bar`.
|
||||||
suggestions.push((
|
suggestions.push((
|
||||||
generics.tail_span_for_predicate_suggestion(),
|
generics.tail_span_for_predicate_suggestion(),
|
||||||
format!(" where {param_name}: {constraint}"),
|
format!("{where_prefix} {param_name}: {constraint}"),
|
||||||
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name },
|
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name },
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -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() { }
|
pub fn main() { }
|
||||||
|
|
|
@ -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() { }
|
pub fn main() { }
|
||||||
|
|
|
@ -14,6 +14,22 @@ help: consider further restricting type parameter `X`
|
||||||
LL | trait InsufficientlyConstrainedGeneric<X=()> where X: std::marker::Copy {
|
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`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue