Skip to content

Commit 8652f5d

Browse files
committed
Fix tuple element tys returned from
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 8652f5d

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)