From ba83b39d4e53f412339f1af8c4f7cbe80eb1ee6e Mon Sep 17 00:00:00 2001 From: Anton Golov Date: Fri, 20 Aug 2021 15:59:42 +0200 Subject: [PATCH 1/3] Change example and tests for E0161. The code will not emit this warning once box expressions require a sized type (since that error is emitted earlier in the flow). --- .../src/error_codes/E0161.md | 26 +++++++++++++++---- src/test/ui/error-codes/E0161.edition.stderr | 8 +++--- .../ui/error-codes/E0161.editionul.stderr | 9 ------- src/test/ui/error-codes/E0161.migrate.stderr | 8 +++--- .../ui/error-codes/E0161.migrateul.stderr | 9 ------- src/test/ui/error-codes/E0161.nll.stderr | 8 +++--- src/test/ui/error-codes/E0161.nllul.stderr | 9 ------- src/test/ui/error-codes/E0161.rs | 14 +++++++--- src/test/ui/error-codes/E0161.zflags.stderr | 8 +++--- src/test/ui/error-codes/E0161.zflagsul.stderr | 9 ------- 10 files changed, 47 insertions(+), 61 deletions(-) delete mode 100644 src/test/ui/error-codes/E0161.editionul.stderr delete mode 100644 src/test/ui/error-codes/E0161.migrateul.stderr delete mode 100644 src/test/ui/error-codes/E0161.nllul.stderr delete mode 100644 src/test/ui/error-codes/E0161.zflagsul.stderr 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 = 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 = box (0 as i32); + b.f(); + // ok! } ``` 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) { + 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`. From b8fff9596158911ad37b60ee89ea2e2c326e1ce6 Mon Sep 17 00:00:00 2001 From: Anton Golov Date: Fri, 20 Aug 2021 16:25:52 +0200 Subject: [PATCH 2/3] Require a box expression's type to be Sized --- compiler/rustc_middle/src/traits/mod.rs | 2 ++ compiler/rustc_mir/src/borrow_check/type_check/mod.rs | 4 +--- .../src/traits/error_reporting/suggestions.rs | 3 +++ compiler/rustc_typeck/src/check/expr.rs | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) 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) } From c75a93023a77dc9c468519e79a1206e5b56b33b9 Mon Sep 17 00:00:00 2001 From: Anton Golov Date: Fri, 20 Aug 2021 16:26:24 +0200 Subject: [PATCH 3/3] Update old box expression tests and add a new one. New tests also check that we're not triggering this error over-zealously. --- src/test/ui/dst/dst-rvalue.rs | 6 ++-- src/test/ui/dst/dst-rvalue.stderr | 34 +++++++------------ .../ui/typeck/issue-87935-unsized-box-expr.rs | 10 ++++++ .../issue-87935-unsized-box-expr.stderr | 12 +++++++ 4 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 src/test/ui/typeck/issue-87935-unsized-box-expr.rs create mode 100644 src/test/ui/typeck/issue-87935-unsized-box-expr.stderr 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 = 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 = box *"hello world"; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: the type of a box expression must have a statically known size -error[E0161]: cannot move a value of type [isize]: the size of [isize] cannot be statically determined - --> $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; - | ^^^^^^ - -error[E0507]: cannot move out of a shared reference - --> $DIR/dst-rvalue.rs:6:28 + | ^^^^^^ doesn't have a size known at compile-time | -LL | let _x: Box = box *"hello world"; - | ^^^^^^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait + = help: the trait `Sized` is not implemented for `[isize]` + = note: the type of a box expression must have a statically known size -error[E0508]: cannot move out of type `[isize]`, a non-copy slice - --> $DIR/dst-rvalue.rs:11: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 +error: aborting due to 2 previous errors -error: aborting due to 4 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/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`.