about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs35
-rw-r--r--src/test/ui/bound-suggestions.fixed27
-rw-r--r--src/test/ui/bound-suggestions.rs27
-rw-r--r--src/test/ui/bound-suggestions.stderr82
4 files changed, 156 insertions, 15 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 1830aaa4471..0ab00fddfaf 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -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(
diff --git a/src/test/ui/bound-suggestions.fixed b/src/test/ui/bound-suggestions.fixed
index a3fe67a9595..be61b7dda25 100644
--- a/src/test/ui/bound-suggestions.fixed
+++ b/src/test/ui/bound-suggestions.fixed
@@ -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() { }
diff --git a/src/test/ui/bound-suggestions.rs b/src/test/ui/bound-suggestions.rs
index de6133d7f59..86f708d42f5 100644
--- a/src/test/ui/bound-suggestions.rs
+++ b/src/test/ui/bound-suggestions.rs
@@ -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() { }
diff --git a/src/test/ui/bound-suggestions.stderr b/src/test/ui/bound-suggestions.stderr
index 010f95d8ad6..12e67e90265 100644
--- a/src/test/ui/bound-suggestions.stderr
+++ b/src/test/ui/bound-suggestions.stderr
@@ -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`.