Skip to content

Commit 1e3d632

Browse files
committed
Auto merge of #88087 - jesyspa:issue-87935-box, r=jackh726
Check that a box expression's type is Sized This resolves [issue 87935](#87935). This makes E0161 (move from an unsized rvalue) much less common. I've replaced the test to use [this case](https://github.com/rust-lang/rust/blob/master/src/test/ui/object-safety/object-safety-by-value-self-use.rs), when a boxed `dyn` trait is passed by value, but that isn't an error when `unsized_locals` is enabled. I think it may be possible to get rid of E0161 entirely by checking that case earlier, but I'm not sure if that's desirable?
2 parents a003591 + c75a930 commit 1e3d632

File tree

18 files changed

+90
-90
lines changed

18 files changed

+90
-90
lines changed

compiler/rustc_error_codes/src/error_codes/E0161.md

+21-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ Erroneous code example:
44

55
```compile_fail,E0161
66
#![feature(box_syntax)]
7+
trait Bar {
8+
fn f(self);
9+
}
10+
11+
impl Bar for i32 {
12+
fn f(self) {}
13+
}
714
815
fn main() {
9-
let array: &[isize] = &[1, 2, 3];
10-
let _x: Box<[isize]> = box *array;
11-
// error: cannot move a value of type [isize]: the size of [isize] cannot
16+
let b: Box<dyn Bar> = box (0 as i32);
17+
b.f();
18+
// error: cannot move a value of type dyn Bar: the size of dyn Bar cannot
1219
// be statically determined
1320
}
1421
```
@@ -22,8 +29,17 @@ it around as usual. Example:
2229
```
2330
#![feature(box_syntax)]
2431
32+
trait Bar {
33+
fn f(&self);
34+
}
35+
36+
impl Bar for i32 {
37+
fn f(&self) {}
38+
}
39+
2540
fn main() {
26-
let array: &[isize] = &[1, 2, 3];
27-
let _x: Box<&[isize]> = box array; // ok!
41+
let b: Box<dyn Bar> = box (0 as i32);
42+
b.f();
43+
// ok!
2844
}
2945
```

compiler/rustc_middle/src/traits/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ pub enum ObligationCauseCode<'tcx> {
225225
SizedReturnType,
226226
/// Yield type must be `Sized`.
227227
SizedYieldType,
228+
/// Box expression result type must be `Sized`.
229+
SizedBoxType,
228230
/// Inline asm operand type must be `Sized`.
229231
InlineAsmSized,
230232
/// `[T, ..n]` implies that `T` must be `Copy`.

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1893,9 +1893,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18931893

18941894
// While this is located in `nll::typeck` this error is not
18951895
// an NLL error, it's a required check to prevent creation
1896-
// of unsized rvalues in certain cases:
1897-
// * operand of a box expression
1898-
// * callee in a call expression
1896+
// of unsized rvalues in a call expression.
18991897
diag.emit();
19001898
}
19011899
}

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

+3
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
20722072
ObligationCauseCode::SizedYieldType => {
20732073
err.note("the yield type of a generator must have a statically known size");
20742074
}
2075+
ObligationCauseCode::SizedBoxType => {
2076+
err.note("the type of a box expression must have a statically known size");
2077+
}
20752078
ObligationCauseCode::AssignmentLhsSized => {
20762079
err.note("the left-hand-side of an assignment must have a statically known size");
20772080
}

compiler/rustc_typeck/src/check/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
313313
_ => NoExpectation,
314314
});
315315
let referent_ty = self.check_expr_with_expectation(expr, expected_inner);
316+
self.require_type_is_sized(referent_ty, expr.span, traits::SizedBoxType);
316317
self.tcx.mk_box(referent_ty)
317318
}
318319

src/test/ui/dst/dst-rvalue.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44

55
pub fn main() {
66
let _x: Box<str> = box *"hello world";
7-
//~^ ERROR E0161
8-
//~^^ ERROR cannot move out of a shared reference
7+
//~^ ERROR E0277
98

109
let array: &[isize] = &[1, 2, 3];
1110
let _x: Box<[isize]> = box *array;
12-
//~^ ERROR E0161
13-
//~^^ ERROR cannot move out of type `[isize]`, a non-copy slice
11+
//~^ ERROR E0277
1412
}

src/test/ui/dst/dst-rvalue.stderr

+12-22
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,21 @@
1-
error[E0161]: cannot move a value of type str: the size of str cannot be statically determined
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
22
--> $DIR/dst-rvalue.rs:6:28
33
|
44
LL | let _x: Box<str> = box *"hello world";
5-
| ^^^^^^^^^^^^^^
6-
7-
error[E0161]: cannot move a value of type [isize]: the size of [isize] cannot be statically determined
8-
--> $DIR/dst-rvalue.rs:11:32
5+
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
96
|
10-
LL | let _x: Box<[isize]> = box *array;
11-
| ^^^^^^
7+
= help: the trait `Sized` is not implemented for `str`
8+
= note: the type of a box expression must have a statically known size
129

13-
error[E0507]: cannot move out of a shared reference
14-
--> $DIR/dst-rvalue.rs:6:28
15-
|
16-
LL | let _x: Box<str> = box *"hello world";
17-
| ^^^^^^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
18-
19-
error[E0508]: cannot move out of type `[isize]`, a non-copy slice
20-
--> $DIR/dst-rvalue.rs:11:32
10+
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
11+
--> $DIR/dst-rvalue.rs:10:32
2112
|
2213
LL | let _x: Box<[isize]> = box *array;
23-
| ^^^^^^
24-
| |
25-
| cannot move out of here
26-
| move occurs because `*array` has type `[isize]`, which does not implement the `Copy` trait
14+
| ^^^^^^ doesn't have a size known at compile-time
15+
|
16+
= help: the trait `Sized` is not implemented for `[isize]`
17+
= note: the type of a box expression must have a statically known size
2718

28-
error: aborting due to 4 previous errors
19+
error: aborting due to 2 previous errors
2920

30-
Some errors have detailed explanations: E0161, E0507, E0508.
31-
For more information about an error, try `rustc --explain E0161`.
21+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/error-codes/E0161.edition.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2-
--> $DIR/E0161.rs:22:9
1+
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
2+
--> $DIR/E0161.rs:29:5
33
|
4-
LL | box *x;
5-
| ^^
4+
LL | x.f();
5+
| ^
66

77
error: aborting due to previous error
88

src/test/ui/error-codes/E0161.editionul.stderr

-9
This file was deleted.

src/test/ui/error-codes/E0161.migrate.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2-
--> $DIR/E0161.rs:22:9
1+
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
2+
--> $DIR/E0161.rs:29:5
33
|
4-
LL | box *x;
5-
| ^^
4+
LL | x.f();
5+
| ^
66

77
error: aborting due to previous error
88

src/test/ui/error-codes/E0161.migrateul.stderr

-9
This file was deleted.

src/test/ui/error-codes/E0161.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2-
--> $DIR/E0161.rs:22:9
1+
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
2+
--> $DIR/E0161.rs:29:5
33
|
4-
LL | box *x;
5-
| ^^
4+
LL | x.f();
5+
| ^
66

77
error: aborting due to previous error
88

src/test/ui/error-codes/E0161.nllul.stderr

-9
This file was deleted.

src/test/ui/error-codes/E0161.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
//[edition]edition:2018
99
//[zflagsul]compile-flags: -Z borrowck=migrate
1010
//[editionul]edition:2018
11+
//[migrateul] check-pass
12+
//[nllul] check-pass
13+
//[zflagsul] check-pass
14+
//[editionul] check-pass
1115

1216
#![allow(incomplete_features)]
1317
#![cfg_attr(nll, feature(nll))]
@@ -16,12 +20,14 @@
1620
#![cfg_attr(zflagsul, feature(unsized_locals))]
1721
#![cfg_attr(nllul, feature(unsized_locals))]
1822
#![cfg_attr(editionul, feature(unsized_locals))]
19-
#![feature(box_syntax)]
2023

21-
fn foo(x: Box<[i32]>) {
22-
box *x;
24+
trait Bar {
25+
fn f(self);
26+
}
27+
28+
fn foo(x: Box<dyn Bar>) {
29+
x.f();
2330
//[migrate,nll,zflags,edition]~^ ERROR E0161
24-
//[migrateul,nllul,zflagsul,editionul]~^^ ERROR E0161
2531
}
2632

2733
fn main() {}

src/test/ui/error-codes/E0161.zflags.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2-
--> $DIR/E0161.rs:22:9
1+
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
2+
--> $DIR/E0161.rs:29:5
33
|
4-
LL | box *x;
5-
| ^^
4+
LL | x.f();
5+
| ^
66

77
error: aborting due to previous error
88

src/test/ui/error-codes/E0161.zflagsul.stderr

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(box_syntax)]
2+
// Box expression needs to be movable, and hence has to be of a Sized type.
3+
fn main() {
4+
let _x: Box<[u32]> = box { loop {} };
5+
//~^ ERROR: the size for values of type `[u32]` cannot be known at compilation time
6+
7+
// Check that a deduced size does not cause issues.
8+
let _y: Box<[u32]> = box [];
9+
let _z: Box<[u32; 0]> = box { loop {} };
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
2+
--> $DIR/issue-87935-unsized-box-expr.rs:4:30
3+
|
4+
LL | let _x: Box<[u32]> = box { loop {} };
5+
| ^^^^^^^^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `[u32]`
8+
= note: the type of a box expression must have a statically known size
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)