Skip to content

Commit 088c89d

Browse files
committed
Account for generics when suggesting bound
Fix #81175.
1 parent 1d0d76f commit 088c89d

File tree

4 files changed

+156
-15
lines changed

4 files changed

+156
-15
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -286,21 +286,32 @@ fn suggest_restriction(
286286
);
287287
} else {
288288
// Trivial case: `T` needs an extra bound: `T: Bound`.
289-
let (sp, suggestion) = match super_traits {
290-
None => predicate_constraint(
289+
let (sp, suggestion) = match (
290+
generics
291+
.params
292+
.iter()
293+
.filter(
294+
|p| !matches!(p.kind, hir::GenericParamKind::Type { synthetic: Some(_), ..}),
295+
)
296+
.next(),
297+
super_traits,
298+
) {
299+
(_, None) => predicate_constraint(
291300
generics,
292301
trait_ref.without_const().to_predicate(tcx).to_string(),
293302
),
294-
Some((ident, bounds)) => match bounds {
295-
[.., bound] => (
296-
bound.span().shrink_to_hi(),
297-
format!(" + {}", trait_ref.print_only_trait_path().to_string()),
298-
),
299-
[] => (
300-
ident.span.shrink_to_hi(),
301-
format!(": {}", trait_ref.print_only_trait_path().to_string()),
302-
),
303-
},
303+
(None, Some((ident, []))) => (
304+
ident.span.shrink_to_hi(),
305+
format!(": {}", trait_ref.print_only_trait_path().to_string()),
306+
),
307+
(_, Some((_, [.., bounds]))) => (
308+
bounds.span().shrink_to_hi(),
309+
format!(" + {}", trait_ref.print_only_trait_path().to_string()),
310+
),
311+
(Some(_), Some((_, []))) => (
312+
generics.span.shrink_to_hi(),
313+
format!(": {}", trait_ref.print_only_trait_path().to_string()),
314+
),
304315
};
305316

306317
err.span_suggestion_verbose(

src/test/ui/bound-suggestions.fixed

+26-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,29 @@ fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug {
4040
//~^ ERROR doesn't implement
4141
}
4242

43-
pub fn main() { }
43+
trait Foo<T>: Sized {
44+
const SIZE: usize = core::mem::size_of::<Self>();
45+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
46+
}
47+
48+
trait Bar: std::fmt::Display + Sized {
49+
const SIZE: usize = core::mem::size_of::<Self>();
50+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
51+
}
52+
53+
trait Baz: Sized where Self: std::fmt::Display {
54+
const SIZE: usize = core::mem::size_of::<Self>();
55+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
56+
}
57+
58+
trait Qux<T>: Sized where Self: std::fmt::Display {
59+
const SIZE: usize = core::mem::size_of::<Self>();
60+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
61+
}
62+
63+
trait Bat<T>: std::fmt::Display + Sized {
64+
const SIZE: usize = core::mem::size_of::<Self>();
65+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
66+
}
67+
68+
fn main() { }

src/test/ui/bound-suggestions.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,29 @@ fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized {
4040
//~^ ERROR doesn't implement
4141
}
4242

43-
pub fn main() { }
43+
trait Foo<T> {
44+
const SIZE: usize = core::mem::size_of::<Self>();
45+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
46+
}
47+
48+
trait Bar: std::fmt::Display {
49+
const SIZE: usize = core::mem::size_of::<Self>();
50+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
51+
}
52+
53+
trait Baz where Self: std::fmt::Display {
54+
const SIZE: usize = core::mem::size_of::<Self>();
55+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
56+
}
57+
58+
trait Qux<T> where Self: std::fmt::Display {
59+
const SIZE: usize = core::mem::size_of::<Self>();
60+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
61+
}
62+
63+
trait Bat<T>: std::fmt::Display {
64+
const SIZE: usize = core::mem::size_of::<Self>();
65+
//~^ ERROR the size for values of type `Self` cannot be known at compilation time
66+
}
67+
68+
fn main() { }

src/test/ui/bound-suggestions.stderr

+81-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,86 @@ help: consider further restricting type parameter `X`
7676
LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: Debug {
7777
| ^^^^^^^^^^
7878

79-
error: aborting due to 6 previous errors
79+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
80+
--> $DIR/bound-suggestions.rs:44:46
81+
|
82+
LL | const SIZE: usize = core::mem::size_of::<Self>();
83+
| ^^^^ doesn't have a size known at compile-time
84+
|
85+
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
86+
|
87+
LL | pub const fn size_of<T>() -> usize {
88+
| - required by this bound in `std::mem::size_of`
89+
|
90+
help: consider further restricting `Self`
91+
|
92+
LL | trait Foo<T>: Sized {
93+
| ^^^^^^^
94+
95+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
96+
--> $DIR/bound-suggestions.rs:49:46
97+
|
98+
LL | const SIZE: usize = core::mem::size_of::<Self>();
99+
| ^^^^ doesn't have a size known at compile-time
100+
|
101+
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
102+
|
103+
LL | pub const fn size_of<T>() -> usize {
104+
| - required by this bound in `std::mem::size_of`
105+
|
106+
help: consider further restricting `Self`
107+
|
108+
LL | trait Bar: std::fmt::Display + Sized {
109+
| ^^^^^^^
110+
111+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
112+
--> $DIR/bound-suggestions.rs:54:46
113+
|
114+
LL | const SIZE: usize = core::mem::size_of::<Self>();
115+
| ^^^^ doesn't have a size known at compile-time
116+
|
117+
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
118+
|
119+
LL | pub const fn size_of<T>() -> usize {
120+
| - required by this bound in `std::mem::size_of`
121+
|
122+
help: consider further restricting `Self`
123+
|
124+
LL | trait Baz: Sized where Self: std::fmt::Display {
125+
| ^^^^^^^
126+
127+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
128+
--> $DIR/bound-suggestions.rs:59:46
129+
|
130+
LL | const SIZE: usize = core::mem::size_of::<Self>();
131+
| ^^^^ doesn't have a size known at compile-time
132+
|
133+
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
134+
|
135+
LL | pub const fn size_of<T>() -> usize {
136+
| - required by this bound in `std::mem::size_of`
137+
|
138+
help: consider further restricting `Self`
139+
|
140+
LL | trait Qux<T>: Sized where Self: std::fmt::Display {
141+
| ^^^^^^^
142+
143+
error[E0277]: the size for values of type `Self` cannot be known at compilation time
144+
--> $DIR/bound-suggestions.rs:64:46
145+
|
146+
LL | const SIZE: usize = core::mem::size_of::<Self>();
147+
| ^^^^ doesn't have a size known at compile-time
148+
|
149+
::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
150+
|
151+
LL | pub const fn size_of<T>() -> usize {
152+
| - required by this bound in `std::mem::size_of`
153+
|
154+
help: consider further restricting `Self`
155+
|
156+
LL | trait Bat<T>: std::fmt::Display + Sized {
157+
| ^^^^^^^
158+
159+
error: aborting due to 11 previous errors
80160

81161
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)