Skip to content

Commit c107f12

Browse files
committed
Fix tuple element tys returned from sized_conditions()
Instead of returning the type of the last element we flip it around and return types of all elements _except_ the last one. This matches the the constraint on tuple types which says that only the last element can be unsized.
1 parent dc00e8c commit c107f12

17 files changed

+212
-192
lines changed

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -2116,9 +2116,14 @@ 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) => {
2120+
let tys_except_last = match tys.split_last() {
2121+
Some((_, t)) => t.to_owned(),
2122+
Option::None => Vec::new(),
2123+
};
2124+
2125+
Where(obligation.predicate.rebind(tys_except_last))
2126+
}
21222127

21232128
ty::Adt(def, args) => {
21242129
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 cannot move out of
1313
}

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

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
2-
--> $DIR/dst-bad-deep-2.rs:11:30
1+
error[E0507]: cannot move out of `*g` which is behind a shared reference
2+
--> $DIR/dst-bad-deep-2.rs:11:31
33
|
44
LL | let h: &(([isize],),) = &(*g,);
5-
| ^^^^^ doesn't have a size known at compile-time
6-
|
7-
= help: within `(([isize],),)`, the trait `Sized` is not implemented for `[isize]`, which is required by `(([isize],),): Sized`
8-
= note: required because it appears within the type `([isize],)`
9-
= note: required because it appears within the type `(([isize],),)`
10-
= note: tuples must have a statically known size to be initialized
5+
| ^^ move occurs because `*g` has type `([isize],)`, which does not implement the `Copy` trait
116

127
error: aborting due to 1 previous error
138

14-
For more information about this error, try `rustc --explain E0277`.
9+
For more information about this error, try `rustc --explain E0507`.

tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ impl Trait for Struct {}
55
impl Trait for u32 {}
66

77
fn fuz() -> (usize, Trait) { (42, Struct) }
8-
//~^ ERROR E0277
9-
//~| ERROR E0308
8+
//~^ ERROR E0308
109
fn bar() -> (usize, dyn Trait) { (42, Struct) }
11-
//~^ ERROR E0277
12-
//~| ERROR E0308
10+
//~^ ERROR E0308
1311
fn bap() -> Trait { Struct }
1412
//~^ ERROR E0746
1513
fn ban() -> dyn Trait { Struct }

tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr

+19-43
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,8 @@ LL | fn fuz() -> (usize, Trait) { (42, Struct) }
88
found struct `Struct`
99
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
1010

11-
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
12-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
13-
|
14-
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
15-
| ^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
16-
| |
17-
| doesn't have a size known at compile-time
18-
|
19-
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`, which is required by `(usize, (dyn Trait + 'static)): Sized`
20-
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
21-
= note: the return type of a function must have a statically known size
22-
2311
error[E0308]: mismatched types
24-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39
12+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:9:39
2513
|
2614
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
2715
| ^^^^^^ expected `dyn Trait`, found `Struct`
@@ -30,20 +18,8 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
3018
found struct `Struct`
3119
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
3220

33-
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
34-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13
35-
|
36-
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
37-
| ^^^^^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
38-
| |
39-
| doesn't have a size known at compile-time
40-
|
41-
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`, which is required by `(usize, (dyn Trait + 'static)): Sized`
42-
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
43-
= note: the return type of a function must have a statically known size
44-
4521
error[E0746]: return type cannot have an unboxed trait object
46-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13
22+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:13
4723
|
4824
LL | fn bap() -> Trait { Struct }
4925
| ^^^^^ doesn't have a size known at compile-time
@@ -54,7 +30,7 @@ LL | fn bap() -> Box<Trait> { Box::new(Struct) }
5430
| ++++ + +++++++++ +
5531

5632
error[E0746]: return type cannot have an unboxed trait object
57-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
33+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13
5834
|
5935
LL | fn ban() -> dyn Trait { Struct }
6036
| ^^^^^^^^^ doesn't have a size known at compile-time
@@ -69,7 +45,7 @@ LL | fn ban() -> Box<dyn Trait> { Box::new(Struct) }
6945
| ++++ + +++++++++ +
7046

7147
error[E0746]: return type cannot have an unboxed trait object
72-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
48+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
7349
|
7450
LL | fn bak() -> dyn Trait { unimplemented!() }
7551
| ^^^^^^^^^ doesn't have a size known at compile-time
@@ -84,7 +60,7 @@ LL | fn bak() -> Box<dyn Trait> { Box::new(unimplemented!()) }
8460
| ++++ + +++++++++ +
8561

8662
error[E0746]: return type cannot have an unboxed trait object
87-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13
63+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
8864
|
8965
LL | fn bal() -> dyn Trait {
9066
| ^^^^^^^^^ doesn't have a size known at compile-time
@@ -103,7 +79,7 @@ LL ~ Box::new(42)
10379
|
10480

10581
error[E0746]: return type cannot have an unboxed trait object
106-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13
82+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:13
10783
|
10884
LL | fn bax() -> dyn Trait {
10985
| ^^^^^^^^^ doesn't have a size known at compile-time
@@ -122,7 +98,7 @@ LL ~ Box::new(42)
12298
|
12399

124100
error[E0308]: mismatched types
125-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16
101+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:32:16
126102
|
127103
LL | fn bam() -> Box<dyn Trait> {
128104
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -139,7 +115,7 @@ LL | return Box::new(Struct);
139115
| +++++++++ +
140116

141117
error[E0308]: mismatched types
142-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5
118+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:5
143119
|
144120
LL | fn bam() -> Box<dyn Trait> {
145121
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -156,7 +132,7 @@ LL | Box::new(42)
156132
| +++++++++ +
157133

158134
error[E0308]: mismatched types
159-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16
135+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:38:16
160136
|
161137
LL | fn baq() -> Box<dyn Trait> {
162138
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -173,7 +149,7 @@ LL | return Box::new(0);
173149
| +++++++++ +
174150

175151
error[E0308]: mismatched types
176-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5
152+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:5
177153
|
178154
LL | fn baq() -> Box<dyn Trait> {
179155
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -190,7 +166,7 @@ LL | Box::new(42)
190166
| +++++++++ +
191167

192168
error[E0308]: mismatched types
193-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
169+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:44:9
194170
|
195171
LL | fn baz() -> Box<dyn Trait> {
196172
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -207,7 +183,7 @@ LL | Box::new(Struct)
207183
| +++++++++ +
208184

209185
error[E0308]: mismatched types
210-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
186+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
211187
|
212188
LL | fn baz() -> Box<dyn Trait> {
213189
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -224,7 +200,7 @@ LL | Box::new(42)
224200
| +++++++++ +
225201

226202
error[E0308]: mismatched types
227-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9
203+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:51:9
228204
|
229205
LL | fn baw() -> Box<dyn Trait> {
230206
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -241,7 +217,7 @@ LL | Box::new(0)
241217
| +++++++++ +
242218

243219
error[E0308]: mismatched types
244-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
220+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9
245221
|
246222
LL | fn baw() -> Box<dyn Trait> {
247223
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
@@ -258,7 +234,7 @@ LL | Box::new(42)
258234
| +++++++++ +
259235

260236
error[E0746]: return type cannot have an unboxed trait object
261-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13
237+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:58:13
262238
|
263239
LL | fn bat() -> dyn Trait {
264240
| ^^^^^^^^^ doesn't have a size known at compile-time
@@ -277,7 +253,7 @@ LL ~ Box::new(42)
277253
|
278254

279255
error[E0746]: return type cannot have an unboxed trait object
280-
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:66:13
256+
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:64:13
281257
|
282258
LL | fn bay() -> dyn Trait {
283259
| ^^^^^^^^^ doesn't have a size known at compile-time
@@ -295,7 +271,7 @@ LL | } else {
295271
LL ~ Box::new(42)
296272
|
297273

298-
error: aborting due to 19 previous errors
274+
error: aborting due to 17 previous errors
299275

300-
Some errors have detailed explanations: E0277, E0308, E0746.
301-
For more information about an error, try `rustc --explain E0277`.
276+
Some errors have detailed explanations: E0308, E0746.
277+
For more information about an error, try `rustc --explain E0308`.

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.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
trait Trait<A> {}
22
impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
33
//~^ ERROR E0277
4-
//~| ERROR E0277
54
impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
65
//~^ ERROR E0277
76
//~| ERROR E0277
8-
//~| ERROR E0277
97
trait Trait2<A> {}
108
impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
119
//~^ ERROR E0277
12-
//~| ERROR E0277
1310
trait Trait3<A> {}
1411
impl<A> Trait3<A> for A where A: ?Sized {}
1512
//~^ ERROR E0277

0 commit comments

Comments
 (0)