Skip to content

Commit cf7a036

Browse files
committed
Fix tuple element tys returned from sized_conditions()
Instead of returning the type of only the last element we return the types of all elements. Without it in some situations we were allowing typeck to succeed for tuples which have an unsized element at a non-last position.
1 parent dc00e8c commit cf7a036

File tree

11 files changed

+228
-52
lines changed

11 files changed

+228
-52
lines changed

compiler/rustc_trait_selection/src/traits/select/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2116,9 +2116,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
21162116

21172117
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
21182118

2119-
ty::Tuple(tys) => Where(
2120-
obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
2121-
),
2119+
ty::Tuple(tys) => Where(obligation.predicate.rebind(tys.to_vec())),
21222120

21232121
ty::Adt(def, args) => {
21242122
let sized_crit = def.sized_constraint(self.tcx());

tests/ui/dst/dst-bad-deep-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ pub fn main() {
99
let f: ([isize; 3],) = ([5, 6, 7],);
1010
let g: &([isize],) = &f;
1111
let h: &(([isize],),) = &(*g,);
12-
//~^ ERROR the size for values of type
12+
//~^ ERROR the size for values of type `[isize]` cannot be known at compilation time
1313
}

tests/ui/layout/issue-84108.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42);
1111

1212
static BAZ: ([u8], usize) = ([], 0);
1313
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
14+
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
1415
//~| ERROR mismatched types

tests/ui/layout/issue-84108.stderr

+11-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ LL | static BAZ: ([u8], usize) = ([], 0);
2929
= help: the trait `Sized` is not implemented for `[u8]`
3030
= note: only the last element of a tuple may have a dynamically sized type
3131

32+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
33+
--> $DIR/issue-84108.rs:12:29
34+
|
35+
LL | static BAZ: ([u8], usize) = ([], 0);
36+
| ^^^^^^^ doesn't have a size known at compile-time
37+
|
38+
= help: within `([u8], usize)`, the trait `Sized` is not implemented for `[u8]`, which is required by `([u8], usize): Sized`
39+
= note: required because it appears within the type `([u8], usize)`
40+
= note: constant expressions must have a statically known size
41+
3242
error[E0308]: mismatched types
3343
--> $DIR/issue-84108.rs:12:30
3444
|
@@ -38,7 +48,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
3848
= note: expected slice `[u8]`
3949
found array `[_; 0]`
4050

41-
error: aborting due to 4 previous errors
51+
error: aborting due to 5 previous errors
4252

4353
Some errors have detailed explanations: E0277, E0308, E0412.
4454
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Regression test for #121443
2+
// Checks that no ICE occurs upon encountering
3+
// a tuple with unsized element that is not
4+
// the last element
5+
6+
type Fn = dyn FnOnce() -> u8;
7+
8+
const TEST: Fn = some_fn;
9+
//~^ ERROR cannot find value `some_fn` in this scope
10+
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
11+
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
12+
const TEST2: (Fn, u8) = (TEST, 0);
13+
//~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
14+
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
error[E0425]: cannot find value `some_fn` in this scope
2+
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
3+
|
4+
LL | const TEST: Fn = some_fn;
5+
| ^^^^^^^ not found in this scope
6+
7+
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
8+
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:13
9+
|
10+
LL | const TEST: Fn = some_fn;
11+
| ^^ doesn't have a size known at compile-time
12+
|
13+
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
14+
15+
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
16+
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
17+
|
18+
LL | const TEST: Fn = some_fn;
19+
| ^^^^^^^ doesn't have a size known at compile-time
20+
|
21+
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
22+
= note: constant expressions must have a statically known size
23+
24+
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
25+
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:14
26+
|
27+
LL | const TEST2: (Fn, u8) = (TEST, 0);
28+
| ^^^^^^^^ doesn't have a size known at compile-time
29+
|
30+
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
31+
= note: only the last element of a tuple may have a dynamically sized type
32+
33+
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
34+
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:25
35+
|
36+
LL | const TEST2: (Fn, u8) = (TEST, 0);
37+
| ^^^^^^^^^ doesn't have a size known at compile-time
38+
|
39+
= help: within `((dyn FnOnce() -> u8 + 'static), u8)`, the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`, which is required by `((dyn FnOnce() -> u8 + 'static), u8): Sized`
40+
= note: required because it appears within the type `((dyn FnOnce() -> u8 + 'static), u8)`
41+
= note: constant expressions must have a statically known size
42+
43+
error: aborting due to 5 previous errors
44+
45+
Some errors have detailed explanations: E0277, E0425.
46+
For more information about an error, try `rustc --explain E0277`.

tests/ui/trait-bounds/unsized-bound.stderr

+71-35
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0277]: the size for values of type `B` cannot be known at compilation time
1+
error[E0277]: the size for values of type `A` cannot be known at compilation time
22
--> $DIR/unsized-bound.rs:2:30
33
|
44
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
5-
| - ^^^^^^ doesn't have a size known at compile-time
6-
| |
7-
| this type parameter needs to be `Sized`
5+
| - ^^^^^^ doesn't have a size known at compile-time
6+
| |
7+
| this type parameter needs to be `Sized`
88
|
99
= note: required because it appears within the type `(A, B)`
1010
note: required by an implicit `Sized` bound in `Trait`
@@ -15,35 +15,42 @@ LL | trait Trait<A> {}
1515
help: consider removing the `?Sized` bound to make the type parameter `Sized`
1616
|
1717
LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
18-
LL + impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {}
18+
LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
1919
|
2020
help: consider relaxing the implicit `Sized` restriction
2121
|
2222
LL | trait Trait<A: ?Sized> {}
2323
| ++++++++
2424

25-
error[E0277]: the size for values of type `A` cannot be known at compilation time
25+
error[E0277]: the size for values of type `B` cannot be known at compilation time
2626
--> $DIR/unsized-bound.rs:2:30
2727
|
2828
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
29-
| - ^^^^^^ doesn't have a size known at compile-time
30-
| |
31-
| this type parameter needs to be `Sized`
29+
| - ^^^^^^ doesn't have a size known at compile-time
30+
| |
31+
| this type parameter needs to be `Sized`
3232
|
33-
= note: only the last element of a tuple may have a dynamically sized type
33+
= note: required because it appears within the type `(A, B)`
34+
note: required by an implicit `Sized` bound in `Trait`
35+
--> $DIR/unsized-bound.rs:1:13
36+
|
37+
LL | trait Trait<A> {}
38+
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait`
3439
help: consider removing the `?Sized` bound to make the type parameter `Sized`
3540
|
3641
LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
37-
LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
42+
LL + impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {}
3843
|
44+
help: consider relaxing the implicit `Sized` restriction
45+
|
46+
LL | trait Trait<A: ?Sized> {}
47+
| ++++++++
3948

40-
error[E0277]: the size for values of type `C` cannot be known at compilation time
49+
error[E0277]: the size for values of type `A` cannot be known at compilation time
4150
--> $DIR/unsized-bound.rs:5:52
4251
|
4352
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
44-
| - ^^^^^^^^^ doesn't have a size known at compile-time
45-
| |
46-
| this type parameter needs to be `Sized`
53+
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
4754
|
4855
= note: required because it appears within the type `(A, B, C)`
4956
note: required by an implicit `Sized` bound in `Trait`
@@ -54,46 +61,66 @@ LL | trait Trait<A> {}
5461
help: consider removing the `?Sized` bound to make the type parameter `Sized`
5562
|
5663
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
57-
LL + impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
64+
LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
5865
|
5966
help: consider relaxing the implicit `Sized` restriction
6067
|
6168
LL | trait Trait<A: ?Sized> {}
6269
| ++++++++
6370

64-
error[E0277]: the size for values of type `A` cannot be known at compilation time
71+
error[E0277]: the size for values of type `B` cannot be known at compilation time
6572
--> $DIR/unsized-bound.rs:5:52
6673
|
6774
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
68-
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
75+
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
76+
|
77+
= note: required because it appears within the type `(A, B, C)`
78+
note: required by an implicit `Sized` bound in `Trait`
79+
--> $DIR/unsized-bound.rs:1:13
6980
|
70-
= note: only the last element of a tuple may have a dynamically sized type
81+
LL | trait Trait<A> {}
82+
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait`
7183
help: consider removing the `?Sized` bound to make the type parameter `Sized`
7284
|
7385
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
74-
LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
86+
LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
87+
|
88+
help: consider relaxing the implicit `Sized` restriction
7589
|
90+
LL | trait Trait<A: ?Sized> {}
91+
| ++++++++
7692

77-
error[E0277]: the size for values of type `B` cannot be known at compilation time
93+
error[E0277]: the size for values of type `C` cannot be known at compilation time
7894
--> $DIR/unsized-bound.rs:5:52
7995
|
8096
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
81-
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
97+
| - ^^^^^^^^^ doesn't have a size known at compile-time
98+
| |
99+
| this type parameter needs to be `Sized`
100+
|
101+
= note: required because it appears within the type `(A, B, C)`
102+
note: required by an implicit `Sized` bound in `Trait`
103+
--> $DIR/unsized-bound.rs:1:13
82104
|
83-
= note: only the last element of a tuple may have a dynamically sized type
105+
LL | trait Trait<A> {}
106+
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait`
84107
help: consider removing the `?Sized` bound to make the type parameter `Sized`
85108
|
86109
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
87-
LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
110+
LL + impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
88111
|
112+
help: consider relaxing the implicit `Sized` restriction
113+
|
114+
LL | trait Trait<A: ?Sized> {}
115+
| ++++++++
89116

90-
error[E0277]: the size for values of type `B` cannot be known at compilation time
117+
error[E0277]: the size for values of type `A` cannot be known at compilation time
91118
--> $DIR/unsized-bound.rs:10:47
92119
|
93120
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
94-
| - ^^^^^^ doesn't have a size known at compile-time
95-
| |
96-
| this type parameter needs to be `Sized`
121+
| - ^^^^^^ doesn't have a size known at compile-time
122+
| |
123+
| this type parameter needs to be `Sized`
97124
|
98125
= note: required because it appears within the type `(A, B)`
99126
note: required by an implicit `Sized` bound in `Trait2`
@@ -104,27 +131,36 @@ LL | trait Trait2<A> {}
104131
help: consider removing the `?Sized` bound to make the type parameter `Sized`
105132
|
106133
LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
107-
LL + impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {}
134+
LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
108135
|
109136
help: consider relaxing the implicit `Sized` restriction
110137
|
111138
LL | trait Trait2<A: ?Sized> {}
112139
| ++++++++
113140

114-
error[E0277]: the size for values of type `A` cannot be known at compilation time
141+
error[E0277]: the size for values of type `B` cannot be known at compilation time
115142
--> $DIR/unsized-bound.rs:10:47
116143
|
117144
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
118-
| - ^^^^^^ doesn't have a size known at compile-time
119-
| |
120-
| this type parameter needs to be `Sized`
145+
| - ^^^^^^ doesn't have a size known at compile-time
146+
| |
147+
| this type parameter needs to be `Sized`
121148
|
122-
= note: only the last element of a tuple may have a dynamically sized type
149+
= note: required because it appears within the type `(A, B)`
150+
note: required by an implicit `Sized` bound in `Trait2`
151+
--> $DIR/unsized-bound.rs:9:14
152+
|
153+
LL | trait Trait2<A> {}
154+
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait2`
123155
help: consider removing the `?Sized` bound to make the type parameter `Sized`
124156
|
125157
LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
126-
LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
158+
LL + impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {}
159+
|
160+
help: consider relaxing the implicit `Sized` restriction
127161
|
162+
LL | trait Trait2<A: ?Sized> {}
163+
| ++++++++
128164

129165
error[E0277]: the size for values of type `A` cannot be known at compilation time
130166
--> $DIR/unsized-bound.rs:14:23

tests/ui/unsized/unsized3.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
3939
fn f9<X: ?Sized>(x1: Box<S<X>>) {
4040
f5(&(*x1, 34));
4141
//~^ ERROR the size for values of type
42+
//~| ERROR the size for values of type
4243
}
4344

4445
fn f10<X: ?Sized>(x1: Box<S<X>>) {

tests/ui/unsized/unsized3.stderr

+38-6
Original file line numberDiff line numberDiff line change
@@ -75,27 +75,59 @@ LL | fn f5<Y: ?Sized>(x: &Y) {}
7575
| ++++++++
7676

7777
error[E0277]: the size for values of type `X` cannot be known at compilation time
78-
--> $DIR/unsized3.rs:40:5
78+
--> $DIR/unsized3.rs:40:9
7979
|
8080
LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
8181
| - this type parameter needs to be `Sized`
8282
LL | f5(&(*x1, 34));
83-
| ^^ doesn't have a size known at compile-time
83+
| ^^^^^^^^^ doesn't have a size known at compile-time
8484
|
8585
note: required because it appears within the type `S<X>`
8686
--> $DIR/unsized3.rs:28:8
8787
|
8888
LL | struct S<X: ?Sized> {
8989
| ^
90-
= note: only the last element of a tuple may have a dynamically sized type
90+
= note: required because it appears within the type `(S<X>, {integer})`
91+
= note: tuples must have a statically known size to be initialized
9192
help: consider removing the `?Sized` bound to make the type parameter `Sized`
9293
|
9394
LL - fn f9<X: ?Sized>(x1: Box<S<X>>) {
9495
LL + fn f9<X>(x1: Box<S<X>>) {
9596
|
9697

9798
error[E0277]: the size for values of type `X` cannot be known at compilation time
98-
--> $DIR/unsized3.rs:45:9
99+
--> $DIR/unsized3.rs:40:8
100+
|
101+
LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
102+
| - this type parameter needs to be `Sized`
103+
LL | f5(&(*x1, 34));
104+
| -- ^^^^^^^^^^ doesn't have a size known at compile-time
105+
| |
106+
| required by a bound introduced by this call
107+
|
108+
note: required because it appears within the type `S<X>`
109+
--> $DIR/unsized3.rs:28:8
110+
|
111+
LL | struct S<X: ?Sized> {
112+
| ^
113+
= note: required because it appears within the type `(S<X>, {integer})`
114+
note: required by an implicit `Sized` bound in `f5`
115+
--> $DIR/unsized3.rs:24:7
116+
|
117+
LL | fn f5<Y>(x: &Y) {}
118+
| ^ required by the implicit `Sized` requirement on this type parameter in `f5`
119+
help: consider removing the `?Sized` bound to make the type parameter `Sized`
120+
|
121+
LL - fn f9<X: ?Sized>(x1: Box<S<X>>) {
122+
LL + fn f9<X>(x1: Box<S<X>>) {
123+
|
124+
help: consider relaxing the implicit `Sized` restriction
125+
|
126+
LL | fn f5<Y: ?Sized>(x: &Y) {}
127+
| ++++++++
128+
129+
error[E0277]: the size for values of type `X` cannot be known at compilation time
130+
--> $DIR/unsized3.rs:46:9
99131
|
100132
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
101133
| - this type parameter needs to be `Sized`
@@ -116,7 +148,7 @@ LL + fn f10<X>(x1: Box<S<X>>) {
116148
|
117149

118150
error[E0277]: the size for values of type `X` cannot be known at compilation time
119-
--> $DIR/unsized3.rs:45:8
151+
--> $DIR/unsized3.rs:46:8
120152
|
121153
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
122154
| - this type parameter needs to be `Sized`
@@ -146,6 +178,6 @@ help: consider relaxing the implicit `Sized` restriction
146178
LL | fn f5<Y: ?Sized>(x: &Y) {}
147179
| ++++++++
148180

149-
error: aborting due to 6 previous errors
181+
error: aborting due to 7 previous errors
150182

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

0 commit comments

Comments
 (0)