Skip to content

Commit

Permalink
Auto merge of #88087 - jesyspa:issue-87935-box, r=jackh726
Browse files Browse the repository at this point in the history
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?
  • Loading branch information
bors committed Aug 20, 2021
2 parents a003591 + c75a930 commit 1e3d632
Show file tree
Hide file tree
Showing 18 changed files with 90 additions and 90 deletions.
26 changes: 21 additions & 5 deletions compiler/rustc_error_codes/src/error_codes/E0161.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ Erroneous code example:

```compile_fail,E0161
#![feature(box_syntax)]
trait Bar {
fn f(self);
}
impl Bar for i32 {
fn f(self) {}
}
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<[isize]> = box *array;
// error: cannot move a value of type [isize]: the size of [isize] cannot
let b: Box<dyn Bar> = box (0 as i32);
b.f();
// error: cannot move a value of type dyn Bar: the size of dyn Bar cannot
// be statically determined
}
```
Expand All @@ -22,8 +29,17 @@ it around as usual. Example:
```
#![feature(box_syntax)]
trait Bar {
fn f(&self);
}
impl Bar for i32 {
fn f(&self) {}
}
fn main() {
let array: &[isize] = &[1, 2, 3];
let _x: Box<&[isize]> = box array; // ok!
let b: Box<dyn Bar> = box (0 as i32);
b.f();
// ok!
}
```
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ pub enum ObligationCauseCode<'tcx> {
SizedReturnType,
/// Yield type must be `Sized`.
SizedYieldType,
/// Box expression result type must be `Sized`.
SizedBoxType,
/// Inline asm operand type must be `Sized`.
InlineAsmSized,
/// `[T, ..n]` implies that `T` must be `Copy`.
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_mir/src/borrow_check/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1893,9 +1893,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

// While this is located in `nll::typeck` this error is not
// an NLL error, it's a required check to prevent creation
// of unsized rvalues in certain cases:
// * operand of a box expression
// * callee in a call expression
// of unsized rvalues in a call expression.
diag.emit();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ObligationCauseCode::SizedYieldType => {
err.note("the yield type of a generator must have a statically known size");
}
ObligationCauseCode::SizedBoxType => {
err.note("the type of a box expression must have a statically known size");
}
ObligationCauseCode::AssignmentLhsSized => {
err.note("the left-hand-side of an assignment must have a statically known size");
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => NoExpectation,
});
let referent_ty = self.check_expr_with_expectation(expr, expected_inner);
self.require_type_is_sized(referent_ty, expr.span, traits::SizedBoxType);
self.tcx.mk_box(referent_ty)
}

Expand Down
6 changes: 2 additions & 4 deletions src/test/ui/dst/dst-rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@

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

let array: &[isize] = &[1, 2, 3];
let _x: Box<[isize]> = box *array;
//~^ ERROR E0161
//~^^ ERROR cannot move out of type `[isize]`, a non-copy slice
//~^ ERROR E0277
}
34 changes: 12 additions & 22 deletions src/test/ui/dst/dst-rvalue.stderr
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
error[E0161]: cannot move a value of type str: the size of str cannot be statically determined
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/dst-rvalue.rs:6:28
|
LL | let _x: Box<str> = box *"hello world";
| ^^^^^^^^^^^^^^

error[E0161]: cannot move a value of type [isize]: the size of [isize] cannot be statically determined
--> $DIR/dst-rvalue.rs:11:32
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
LL | let _x: Box<[isize]> = box *array;
| ^^^^^^
= help: the trait `Sized` is not implemented for `str`
= note: the type of a box expression must have a statically known size

error[E0507]: cannot move out of a shared reference
--> $DIR/dst-rvalue.rs:6:28
|
LL | let _x: Box<str> = box *"hello world";
| ^^^^^^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait

error[E0508]: cannot move out of type `[isize]`, a non-copy slice
--> $DIR/dst-rvalue.rs:11:32
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
--> $DIR/dst-rvalue.rs:10:32
|
LL | let _x: Box<[isize]> = box *array;
| ^^^^^^
| |
| cannot move out of here
| move occurs because `*array` has type `[isize]`, which does not implement the `Copy` trait
| ^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[isize]`
= note: the type of a box expression must have a statically known size

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

Some errors have detailed explanations: E0161, E0507, E0508.
For more information about an error, try `rustc --explain E0161`.
For more information about this error, try `rustc --explain E0277`.
8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0161.edition.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
--> $DIR/E0161.rs:22:9
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
|
LL | box *x;
| ^^
LL | x.f();
| ^

error: aborting due to previous error

Expand Down
9 changes: 0 additions & 9 deletions src/test/ui/error-codes/E0161.editionul.stderr

This file was deleted.

8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0161.migrate.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
--> $DIR/E0161.rs:22:9
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
|
LL | box *x;
| ^^
LL | x.f();
| ^

error: aborting due to previous error

Expand Down
9 changes: 0 additions & 9 deletions src/test/ui/error-codes/E0161.migrateul.stderr

This file was deleted.

8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0161.nll.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
--> $DIR/E0161.rs:22:9
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
|
LL | box *x;
| ^^
LL | x.f();
| ^

error: aborting due to previous error

Expand Down
9 changes: 0 additions & 9 deletions src/test/ui/error-codes/E0161.nllul.stderr

This file was deleted.

14 changes: 10 additions & 4 deletions src/test/ui/error-codes/E0161.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
//[edition]edition:2018
//[zflagsul]compile-flags: -Z borrowck=migrate
//[editionul]edition:2018
//[migrateul] check-pass
//[nllul] check-pass
//[zflagsul] check-pass
//[editionul] check-pass

#![allow(incomplete_features)]
#![cfg_attr(nll, feature(nll))]
Expand All @@ -16,12 +20,14 @@
#![cfg_attr(zflagsul, feature(unsized_locals))]
#![cfg_attr(nllul, feature(unsized_locals))]
#![cfg_attr(editionul, feature(unsized_locals))]
#![feature(box_syntax)]

fn foo(x: Box<[i32]>) {
box *x;
trait Bar {
fn f(self);
}

fn foo(x: Box<dyn Bar>) {
x.f();
//[migrate,nll,zflags,edition]~^ ERROR E0161
//[migrateul,nllul,zflagsul,editionul]~^^ ERROR E0161
}

fn main() {}
8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0161.zflags.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
--> $DIR/E0161.rs:22:9
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
|
LL | box *x;
| ^^
LL | x.f();
| ^

error: aborting due to previous error

Expand Down
9 changes: 0 additions & 9 deletions src/test/ui/error-codes/E0161.zflagsul.stderr

This file was deleted.

10 changes: 10 additions & 0 deletions src/test/ui/typeck/issue-87935-unsized-box-expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![feature(box_syntax)]
// Box expression needs to be movable, and hence has to be of a Sized type.
fn main() {
let _x: Box<[u32]> = box { loop {} };
//~^ ERROR: the size for values of type `[u32]` cannot be known at compilation time

// Check that a deduced size does not cause issues.
let _y: Box<[u32]> = box [];
let _z: Box<[u32; 0]> = box { loop {} };
}
12 changes: 12 additions & 0 deletions src/test/ui/typeck/issue-87935-unsized-box-expr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
--> $DIR/issue-87935-unsized-box-expr.rs:4:30
|
LL | let _x: Box<[u32]> = box { loop {} };
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u32]`
= note: the type of a box expression must have a statically known size

error: aborting due to previous error

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

0 comments on commit 1e3d632

Please sign in to comment.