Rollup merge of #81195 - estebank:suggest-bound-on-trait-with-params, r=oli-obk

Account for generics when suggesting bound

Fix #81175.
This commit is contained in:
Yuki Okushi 2021-01-27 04:43:20 +09:00 committed by GitHub
commit 644df2fd23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 156 additions and 15 deletions

View File

@ -286,21 +286,32 @@ fn suggest_restriction(
); );
} else { } else {
// Trivial case: `T` needs an extra bound: `T: Bound`. // Trivial case: `T` needs an extra bound: `T: Bound`.
let (sp, suggestion) = match super_traits { let (sp, suggestion) = match (
None => predicate_constraint( generics
.params
.iter()
.filter(
|p| !matches!(p.kind, hir::GenericParamKind::Type { synthetic: Some(_), ..}),
)
.next(),
super_traits,
) {
(_, None) => predicate_constraint(
generics, generics,
trait_ref.without_const().to_predicate(tcx).to_string(), trait_ref.without_const().to_predicate(tcx).to_string(),
), ),
Some((ident, bounds)) => match bounds { (None, Some((ident, []))) => (
[.., bound] => ( ident.span.shrink_to_hi(),
bound.span().shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path().to_string()),
format!(" + {}", trait_ref.print_only_trait_path().to_string()), ),
), (_, Some((_, [.., bounds]))) => (
[] => ( bounds.span().shrink_to_hi(),
ident.span.shrink_to_hi(), format!(" + {}", trait_ref.print_only_trait_path().to_string()),
format!(": {}", trait_ref.print_only_trait_path().to_string()), ),
), (Some(_), Some((_, []))) => (
}, generics.span.shrink_to_hi(),
format!(": {}", trait_ref.print_only_trait_path().to_string()),
),
}; };
err.span_suggestion_verbose( err.span_suggestion_verbose(

View File

@ -40,4 +40,29 @@ fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug {
//~^ ERROR doesn't implement //~^ ERROR doesn't implement
} }
pub fn main() { } trait Foo<T>: Sized {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Bar: std::fmt::Display + Sized {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Baz: Sized where Self: std::fmt::Display {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Qux<T>: Sized where Self: std::fmt::Display {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Bat<T>: std::fmt::Display + Sized {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
fn main() { }

View File

@ -40,4 +40,29 @@ fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized {
//~^ ERROR doesn't implement //~^ ERROR doesn't implement
} }
pub fn main() { } trait Foo<T> {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Bar: std::fmt::Display {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Baz where Self: std::fmt::Display {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Qux<T> where Self: std::fmt::Display {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
trait Bat<T>: std::fmt::Display {
const SIZE: usize = core::mem::size_of::<Self>();
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
}
fn main() { }

View File

@ -76,6 +76,86 @@ help: consider further restricting type parameter `X`
LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug { LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug {
| ^^^^^^^^^^ | ^^^^^^^^^^
error: aborting due to 6 previous errors error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/bound-suggestions.rs:44:46
|
LL | const SIZE: usize = core::mem::size_of::<Self>();
| ^^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub const fn size_of<T>() -> usize {
| - required by this bound in `std::mem::size_of`
|
help: consider further restricting `Self`
|
LL | trait Foo<T>: Sized {
| ^^^^^^^
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/bound-suggestions.rs:49:46
|
LL | const SIZE: usize = core::mem::size_of::<Self>();
| ^^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub const fn size_of<T>() -> usize {
| - required by this bound in `std::mem::size_of`
|
help: consider further restricting `Self`
|
LL | trait Bar: std::fmt::Display + Sized {
| ^^^^^^^
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/bound-suggestions.rs:54:46
|
LL | const SIZE: usize = core::mem::size_of::<Self>();
| ^^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub const fn size_of<T>() -> usize {
| - required by this bound in `std::mem::size_of`
|
help: consider further restricting `Self`
|
LL | trait Baz: Sized where Self: std::fmt::Display {
| ^^^^^^^
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/bound-suggestions.rs:59:46
|
LL | const SIZE: usize = core::mem::size_of::<Self>();
| ^^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub const fn size_of<T>() -> usize {
| - required by this bound in `std::mem::size_of`
|
help: consider further restricting `Self`
|
LL | trait Qux<T>: Sized where Self: std::fmt::Display {
| ^^^^^^^
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/bound-suggestions.rs:64:46
|
LL | const SIZE: usize = core::mem::size_of::<Self>();
| ^^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
LL | pub const fn size_of<T>() -> usize {
| - required by this bound in `std::mem::size_of`
|
help: consider further restricting `Self`
|
LL | trait Bat<T>: std::fmt::Display + Sized {
| ^^^^^^^
error: aborting due to 11 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.