Skip to content

Check that a box expression's type is Sized #88087

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.