Skip to content

Commit

Permalink
Fix tuple element tys returned from sized_conditions()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
gurry committed Mar 4, 2024
1 parent dc00e8c commit cf7a036
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 52 deletions.
4 changes: 1 addition & 3 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2116,9 +2116,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {

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

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

ty::Adt(def, args) => {
let sized_crit = def.sized_constraint(self.tcx());
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/dst/dst-bad-deep-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ pub fn main() {
let f: ([isize; 3],) = ([5, 6, 7],);
let g: &([isize],) = &f;
let h: &(([isize],),) = &(*g,);
//~^ ERROR the size for values of type
//~^ ERROR the size for values of type `[isize]` cannot be known at compilation time
}
1 change: 1 addition & 0 deletions tests/ui/layout/issue-84108.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42);

static BAZ: ([u8], usize) = ([], 0);
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
//~| ERROR the size for values of type `[u8]` cannot be known at compilation time
//~| ERROR mismatched types
12 changes: 11 additions & 1 deletion tests/ui/layout/issue-84108.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ LL | static BAZ: ([u8], usize) = ([], 0);
= help: the trait `Sized` is not implemented for `[u8]`
= note: only the last element of a tuple may have a dynamically sized type

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-84108.rs:12:29
|
LL | static BAZ: ([u8], usize) = ([], 0);
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: within `([u8], usize)`, the trait `Sized` is not implemented for `[u8]`, which is required by `([u8], usize): Sized`
= note: required because it appears within the type `([u8], usize)`
= note: constant expressions must have a statically known size

error[E0308]: mismatched types
--> $DIR/issue-84108.rs:12:30
|
Expand All @@ -38,7 +48,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
= note: expected slice `[u8]`
found array `[_; 0]`

error: aborting due to 4 previous errors
error: aborting due to 5 previous errors

Some errors have detailed explanations: E0277, E0308, E0412.
For more information about an error, try `rustc --explain E0277`.
16 changes: 16 additions & 0 deletions tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Regression test for #121443
// Checks that no ICE occurs upon encountering
// a tuple with unsized element that is not
// the last element

type Fn = dyn FnOnce() -> u8;

const TEST: Fn = some_fn;
//~^ ERROR cannot find value `some_fn` in this scope
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
const TEST2: (Fn, u8) = (TEST, 0);
//~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time

fn main() {}
46 changes: 46 additions & 0 deletions tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
error[E0425]: cannot find value `some_fn` in this scope
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
|
LL | const TEST: Fn = some_fn;
| ^^^^^^^ not found in this scope

error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:13
|
LL | const TEST: Fn = some_fn;
| ^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`

error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
|
LL | const TEST: Fn = some_fn;
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
= note: constant expressions must have a statically known size

error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:14
|
LL | const TEST2: (Fn, u8) = (TEST, 0);
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
= note: only the last element of a tuple may have a dynamically sized type

error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:25
|
LL | const TEST2: (Fn, u8) = (TEST, 0);
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= 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`
= note: required because it appears within the type `((dyn FnOnce() -> u8 + 'static), u8)`
= note: constant expressions must have a statically known size

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0277, E0425.
For more information about an error, try `rustc --explain E0277`.
106 changes: 71 additions & 35 deletions tests/ui/trait-bounds/unsized-bound.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0277]: the size for values of type `B` cannot be known at compilation time
error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/unsized-bound.rs:2:30
|
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
= note: required because it appears within the type `(A, B)`
note: required by an implicit `Sized` bound in `Trait`
Expand All @@ -15,35 +15,42 @@ LL | trait Trait<A> {}
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
LL + impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {}
LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `A` cannot be known at compilation time
error[E0277]: the size for values of type `B` cannot be known at compilation time
--> $DIR/unsized-bound.rs:2:30
|
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
= note: only the last element of a tuple may have a dynamically sized type
= note: required because it appears within the type `(A, B)`
note: required by an implicit `Sized` bound in `Trait`
--> $DIR/unsized-bound.rs:1:13
|
LL | trait Trait<A> {}
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
LL + impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
LL + impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `C` cannot be known at compilation time
error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/unsized-bound.rs:5:52
|
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
| - ^^^^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
|
= note: required because it appears within the type `(A, B, C)`
note: required by an implicit `Sized` bound in `Trait`
Expand All @@ -54,46 +61,66 @@ LL | trait Trait<A> {}
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
LL + impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `A` cannot be known at compilation time
error[E0277]: the size for values of type `B` cannot be known at compilation time
--> $DIR/unsized-bound.rs:5:52
|
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
|
= note: required because it appears within the type `(A, B, C)`
note: required by an implicit `Sized` bound in `Trait`
--> $DIR/unsized-bound.rs:1:13
|
= note: only the last element of a tuple may have a dynamically sized type
LL | trait Trait<A> {}
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
LL + impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) {}
LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `B` cannot be known at compilation time
error[E0277]: the size for values of type `C` cannot be known at compilation time
--> $DIR/unsized-bound.rs:5:52
|
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
| - ^^^^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
= note: required because it appears within the type `(A, B, C)`
note: required by an implicit `Sized` bound in `Trait`
--> $DIR/unsized-bound.rs:1:13
|
= note: only the last element of a tuple may have a dynamically sized type
LL | trait Trait<A> {}
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
LL + impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
LL + impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `B` cannot be known at compilation time
error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/unsized-bound.rs:10:47
|
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
= note: required because it appears within the type `(A, B)`
note: required by an implicit `Sized` bound in `Trait2`
Expand All @@ -104,27 +131,36 @@ LL | trait Trait2<A> {}
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
LL + impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {}
LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait2<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `A` cannot be known at compilation time
error[E0277]: the size for values of type `B` cannot be known at compilation time
--> $DIR/unsized-bound.rs:10:47
|
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
| - ^^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
= note: only the last element of a tuple may have a dynamically sized type
= note: required because it appears within the type `(A, B)`
note: required by an implicit `Sized` bound in `Trait2`
--> $DIR/unsized-bound.rs:9:14
|
LL | trait Trait2<A> {}
| ^ required by the implicit `Sized` requirement on this type parameter in `Trait2`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
LL + impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
LL + impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {}
|
help: consider relaxing the implicit `Sized` restriction
|
LL | trait Trait2<A: ?Sized> {}
| ++++++++

error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/unsized-bound.rs:14:23
Expand Down
1 change: 1 addition & 0 deletions tests/ui/unsized/unsized3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
fn f9<X: ?Sized>(x1: Box<S<X>>) {
f5(&(*x1, 34));
//~^ ERROR the size for values of type
//~| ERROR the size for values of type
}

fn f10<X: ?Sized>(x1: Box<S<X>>) {
Expand Down
44 changes: 38 additions & 6 deletions tests/ui/unsized/unsized3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,59 @@ LL | fn f5<Y: ?Sized>(x: &Y) {}
| ++++++++

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

error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:45:9
--> $DIR/unsized3.rs:40:8
|
LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
| - this type parameter needs to be `Sized`
LL | f5(&(*x1, 34));
| -- ^^^^^^^^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `S<X>`
--> $DIR/unsized3.rs:28:8
|
LL | struct S<X: ?Sized> {
| ^
= note: required because it appears within the type `(S<X>, {integer})`
note: required by an implicit `Sized` bound in `f5`
--> $DIR/unsized3.rs:24:7
|
LL | fn f5<Y>(x: &Y) {}
| ^ required by the implicit `Sized` requirement on this type parameter in `f5`
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn f9<X: ?Sized>(x1: Box<S<X>>) {
LL + fn f9<X>(x1: Box<S<X>>) {
|
help: consider relaxing the implicit `Sized` restriction
|
LL | fn f5<Y: ?Sized>(x: &Y) {}
| ++++++++

error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized3.rs:46:9
|
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
| - this type parameter needs to be `Sized`
Expand All @@ -116,7 +148,7 @@ LL + fn f10<X>(x1: Box<S<X>>) {
|

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

error: aborting due to 6 previous errors
error: aborting due to 7 previous errors

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

0 comments on commit cf7a036

Please sign in to comment.