Skip to content

Commit

Permalink
Rollup merge of rust-lang#81195 - estebank:suggest-bound-on-trait-wit…
Browse files Browse the repository at this point in the history
…h-params, r=oli-obk

Account for generics when suggesting bound

Fix rust-lang#81175.
  • Loading branch information
JohnTitor committed Jan 26, 2021
2 parents 5e28acc + 088c89d commit b78f52d
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
27 changes: 26 additions & 1 deletion src/test/ui/bound-suggestions.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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() { }
27 changes: 26 additions & 1 deletion src/test/ui/bound-suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() { }
82 changes: 81 additions & 1 deletion src/test/ui/bound-suggestions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

0 comments on commit b78f52d

Please sign in to comment.