diff options
| author | bors <bors@rust-lang.org> | 2021-08-20 23:04:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-08-20 23:04:57 +0000 |
| commit | 1e3d632f8f921d03ccc5b71d97decf980df7dbe4 (patch) | |
| tree | 7bc2ba77dbc9b6e8ff164d449f2d0fe6d1ac17cf | |
| parent | a0035916e01d8e644ccd44554c57f0874cef8c8c (diff) | |
| parent | c75a93023a77dc9c468519e79a1206e5b56b33b9 (diff) | |
| download | rust-1e3d632f8f921d03ccc5b71d97decf980df7dbe4.tar.gz rust-1e3d632f8f921d03ccc5b71d97decf980df7dbe4.zip | |
Auto merge of #88087 - jesyspa:issue-87935-box, r=jackh726
Check that a box expression's type is Sized This resolves [issue 87935](https://github.com/rust-lang/rust/issues/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?
18 files changed, 90 insertions, 90 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0161.md b/compiler/rustc_error_codes/src/error_codes/E0161.md index c2e2f0240f4..ebd2c97698b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0161.md +++ b/compiler/rustc_error_codes/src/error_codes/E0161.md @@ -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 } ``` @@ -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! } ``` diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a4a2e824637..d8d98bba3fb 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -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`. diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index d05e0135dfe..35bb6ef6c2d 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -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(); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5499993db63..003642ff259 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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"); } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 23ce4275d40..9cbd3f7bb33 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -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) } diff --git a/src/test/ui/dst/dst-rvalue.rs b/src/test/ui/dst/dst-rvalue.rs index aa028396be4..b52a95a701f 100644 --- a/src/test/ui/dst/dst-rvalue.rs +++ b/src/test/ui/dst/dst-rvalue.rs @@ -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 } diff --git a/src/test/ui/dst/dst-rvalue.stderr b/src/test/ui/dst/dst-rvalue.stderr index 6a51c517558..15830636b51 100644 --- a/src/test/ui/dst/dst-rvalue.stderr +++ b/src/test/ui/dst/dst-rvalue.stderr @@ -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`. diff --git a/src/test/ui/error-codes/E0161.edition.stderr b/src/test/ui/error-codes/E0161.edition.stderr index 536a81a4bc6..6beb29c57d5 100644 --- a/src/test/ui/error-codes/E0161.edition.stderr +++ b/src/test/ui/error-codes/E0161.edition.stderr @@ -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 diff --git a/src/test/ui/error-codes/E0161.editionul.stderr b/src/test/ui/error-codes/E0161.editionul.stderr deleted file mode 100644 index 2baba998f12..00000000000 --- a/src/test/ui/error-codes/E0161.editionul.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined - --> $DIR/E0161.rs:22:5 - | -LL | box *x; - | ^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0161`. diff --git a/src/test/ui/error-codes/E0161.migrate.stderr b/src/test/ui/error-codes/E0161.migrate.stderr index 536a81a4bc6..6beb29c57d5 100644 --- a/src/test/ui/error-codes/E0161.migrate.stderr +++ b/src/test/ui/error-codes/E0161.migrate.stderr @@ -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 diff --git a/src/test/ui/error-codes/E0161.migrateul.stderr b/src/test/ui/error-codes/E0161.migrateul.stderr deleted file mode 100644 index 2baba998f12..00000000000 --- a/src/test/ui/error-codes/E0161.migrateul.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined - --> $DIR/E0161.rs:22:5 - | -LL | box *x; - | ^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0161`. diff --git a/src/test/ui/error-codes/E0161.nll.stderr b/src/test/ui/error-codes/E0161.nll.stderr index 536a81a4bc6..6beb29c57d5 100644 --- a/src/test/ui/error-codes/E0161.nll.stderr +++ b/src/test/ui/error-codes/E0161.nll.stderr @@ -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 diff --git a/src/test/ui/error-codes/E0161.nllul.stderr b/src/test/ui/error-codes/E0161.nllul.stderr deleted file mode 100644 index 2baba998f12..00000000000 --- a/src/test/ui/error-codes/E0161.nllul.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined - --> $DIR/E0161.rs:22:5 - | -LL | box *x; - | ^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0161`. diff --git a/src/test/ui/error-codes/E0161.rs b/src/test/ui/error-codes/E0161.rs index e0f5776424e..ba74529e4b6 100644 --- a/src/test/ui/error-codes/E0161.rs +++ b/src/test/ui/error-codes/E0161.rs @@ -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))] @@ -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() {} diff --git a/src/test/ui/error-codes/E0161.zflags.stderr b/src/test/ui/error-codes/E0161.zflags.stderr index 536a81a4bc6..6beb29c57d5 100644 --- a/src/test/ui/error-codes/E0161.zflags.stderr +++ b/src/test/ui/error-codes/E0161.zflags.stderr @@ -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 diff --git a/src/test/ui/error-codes/E0161.zflagsul.stderr b/src/test/ui/error-codes/E0161.zflagsul.stderr deleted file mode 100644 index 2baba998f12..00000000000 --- a/src/test/ui/error-codes/E0161.zflagsul.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined - --> $DIR/E0161.rs:22:5 - | -LL | box *x; - | ^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0161`. diff --git a/src/test/ui/typeck/issue-87935-unsized-box-expr.rs b/src/test/ui/typeck/issue-87935-unsized-box-expr.rs new file mode 100644 index 00000000000..cd2a82074ed --- /dev/null +++ b/src/test/ui/typeck/issue-87935-unsized-box-expr.rs @@ -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 {} }; +} diff --git a/src/test/ui/typeck/issue-87935-unsized-box-expr.stderr b/src/test/ui/typeck/issue-87935-unsized-box-expr.stderr new file mode 100644 index 00000000000..9ff822352a1 --- /dev/null +++ b/src/test/ui/typeck/issue-87935-unsized-box-expr.stderr @@ -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`. |
