Account for generics when suggesting bound

Fix #81175.
This commit is contained in:
Esteban Küber 2021-01-19 12:44:49 -08:00
parent 1d0d76f8dd
commit 088c89d9ff
4 changed files with 156 additions and 15 deletions

View File

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

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
}
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
}
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 {
| ^^^^^^^^^^
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`.