From b83fe42237d5c3e3e40708f9ce8c8fa1eec3e431 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Tue, 21 Aug 2018 20:40:03 +0100 Subject: [PATCH 1/2] Hard error for unsized values more often * Sized checking in MIR should be a hard error in all borrowck modes * box operands should be an error even with unsized locals --- src/librustc_mir/borrow_check/nll/mod.rs | 1 - .../borrow_check/nll/type_check/mod.rs | 54 ++++++++----------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index f54d80d5f4f7e..502b67b513692 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -125,7 +125,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( flow_inits, move_data, elements, - errors_buffer, ); if let Some(all_facts) = &mut all_facts { diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 2fb5861dff444..0f17f4e7721fe 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -38,7 +38,6 @@ use rustc::traits::query::type_op; use rustc::traits::query::{Fallible, NoSolution}; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind}; -use rustc_errors::Diagnostic; use std::fmt; use std::rc::Rc; use syntax_pos::{Span, DUMMY_SP}; @@ -106,8 +105,7 @@ mod relate_tys; /// - `liveness` -- results of a liveness computation on the MIR; used to create liveness /// constraints for the regions in the types of variables /// - `flow_inits` -- results of a maybe-init dataflow analysis -/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis -/// - `errors_buffer` -- errors are sent here for future reporting +/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysiss pub(crate) fn type_check<'gcx, 'tcx>( infcx: &InferCtxt<'_, 'gcx, 'tcx>, param_env: ty::ParamEnv<'gcx>, @@ -120,7 +118,6 @@ pub(crate) fn type_check<'gcx, 'tcx>( flow_inits: &mut FlowAtLocation>, move_data: &MoveData<'tcx>, elements: &Rc, - errors_buffer: &mut Vec, ) -> MirTypeckResults<'tcx> { let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body)); let mut constraints = MirTypeckRegionConstraints { @@ -161,7 +158,6 @@ pub(crate) fn type_check<'gcx, 'tcx>( ®ion_bound_pairs, Some(implicit_region_bound), Some(&mut borrowck_context), - Some(errors_buffer), |cx| { cx.equate_inputs_and_outputs( mir, @@ -191,7 +187,6 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>( region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)], implicit_region_bound: Option>, borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>, - errors_buffer: Option<&mut Vec>, mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R, ) -> R where { let mut checker = TypeChecker::new( @@ -211,7 +206,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>( if !errors_reported { // if verifier failed, don't do further checks to avoid ICEs - checker.typeck_mir(mir, errors_buffer); + checker.typeck_mir(mir); } extra(&mut checker) @@ -964,7 +959,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { mir: &Mir<'tcx>, term: &Terminator<'tcx>, term_location: Location, - errors_buffer: &mut Option<&mut Vec>, ) { debug!("check_terminator: {:?}", term); let tcx = self.tcx(); @@ -1044,7 +1038,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { &sig, ); let sig = self.normalize(sig, term_location); - self.check_call_dest(mir, term, &sig, destination, term_location, errors_buffer); + self.check_call_dest(mir, term, &sig, destination, term_location); self.prove_predicates( sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)), @@ -1118,7 +1112,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { sig: &ty::FnSig<'tcx>, destination: &Option<(Place<'tcx>, BasicBlock)>, term_location: Location, - errors_buffer: &mut Option<&mut Vec>, ) { let tcx = self.tcx(); match *destination { @@ -1152,7 +1145,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // this check is done at `check_local`. if self.tcx().features().unsized_locals { let span = term.source_info.span; - self.ensure_place_sized(dest_ty, span, errors_buffer); + self.ensure_place_sized(dest_ty, span); } } None => { @@ -1305,7 +1298,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { mir: &Mir<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>, - errors_buffer: &mut Option<&mut Vec>, ) { match mir.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Arg => { @@ -1321,18 +1313,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } // When `#![feature(unsized_locals)]` is enabled, only function calls - // are checked in `check_call_dest`. + // and nullary ops are checked in `check_call_dest`. if !self.tcx().features().unsized_locals { let span = local_decl.source_info.span; let ty = local_decl.ty; - self.ensure_place_sized(ty, span, errors_buffer); + self.ensure_place_sized(ty, span); } } - fn ensure_place_sized(&mut self, - ty: Ty<'tcx>, - span: Span, - errors_buffer: &mut Option<&mut Vec>) { + fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) { let tcx = self.tcx(); // Erase the regions from `ty` to get a global type. The @@ -1354,15 +1343,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { cannot be statically determined", ty ); - if let Some(ref mut errors_buffer) = *errors_buffer { - diag.buffer(errors_buffer); - } else { - // we're allowed to use emit() here because the - // NLL migration will be turned on (and thus - // errors will need to be buffered) *only if* - // errors_buffer is Some. - diag.emit(); - } + + // 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 + diag.emit(); } } } @@ -1437,6 +1424,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { }, Rvalue::NullaryOp(_, ty) => { + // Even with unsized locals cannot box an unsized value. + if self.tcx().features().unsized_locals { + let span = mir.source_info(location).span; + self.ensure_place_sized(ty, span); + } + let trait_ref = ty::TraitRef { def_id: tcx.lang_items().sized_trait().unwrap(), substs: tcx.mk_substs_trait(ty, &[]), @@ -1840,12 +1833,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { }) } - fn typeck_mir(&mut self, mir: &Mir<'tcx>, mut errors_buffer: Option<&mut Vec>) { + fn typeck_mir(&mut self, mir: &Mir<'tcx>) { self.last_span = mir.span; debug!("run_on_mir: {:?}", mir.span); for (local, local_decl) in mir.local_decls.iter_enumerated() { - self.check_local(mir, local, local_decl, &mut errors_buffer); + self.check_local(mir, local, local_decl); } for (block, block_data) in mir.basic_blocks().iter_enumerated() { @@ -1861,7 +1854,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { location.statement_index += 1; } - self.check_terminator(mir, block_data.terminator(), location, &mut errors_buffer); + self.check_terminator(mir, block_data.terminator(), location); self.check_iscleanup(mir, block_data); } } @@ -1918,7 +1911,6 @@ impl MirPass for TypeckMir { &[], None, None, - None, |_| (), ); From cd92da833fcb8818ac679be615c7bfe02edaa235 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Tue, 21 Aug 2018 20:47:39 +0100 Subject: [PATCH 2/2] Update E0161 test to cover more cases Update another test that broke due to E0161 no longer being buffered --- src/test/ui/dst/dst-index.nll.stderr | 12 ++++----- src/test/ui/dst/dst-rvalue.nll.stderr | 12 ++++----- src/test/ui/error-codes/E0161.ast.stderr | 9 +++++++ src/test/ui/error-codes/E0161.astul.stderr | 9 +++++++ src/test/ui/error-codes/E0161.edition.stderr | 9 +++++++ .../ui/error-codes/E0161.editionul.stderr | 9 +++++++ src/test/ui/error-codes/E0161.nll.stderr | 9 +++++++ src/test/ui/error-codes/E0161.nllul.stderr | 9 +++++++ src/test/ui/error-codes/E0161.rs | 25 ++++++++++++++++--- src/test/ui/error-codes/E0161.zflags.stderr | 9 +++++++ src/test/ui/error-codes/E0161.zflagsul.stderr | 9 +++++++ 11 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/error-codes/E0161.ast.stderr create mode 100644 src/test/ui/error-codes/E0161.astul.stderr create mode 100644 src/test/ui/error-codes/E0161.edition.stderr create mode 100644 src/test/ui/error-codes/E0161.editionul.stderr create mode 100644 src/test/ui/error-codes/E0161.nll.stderr create mode 100644 src/test/ui/error-codes/E0161.nllul.stderr create mode 100644 src/test/ui/error-codes/E0161.zflags.stderr create mode 100644 src/test/ui/error-codes/E0161.zflagsul.stderr diff --git a/src/test/ui/dst/dst-index.nll.stderr b/src/test/ui/dst/dst-index.nll.stderr index 767d8a84c041d..0aa85d3ed7a3d 100644 --- a/src/test/ui/dst/dst-index.nll.stderr +++ b/src/test/ui/dst/dst-index.nll.stderr @@ -4,18 +4,18 @@ error[E0161]: cannot move a value of type str: the size of str cannot be statica LL | S[0]; | ^^^^ -error[E0507]: cannot move out of borrowed content - --> $DIR/dst-index.rs:41:5 - | -LL | S[0]; - | ^^^^ cannot move out of borrowed content - error[E0161]: cannot move a value of type dyn std::fmt::Debug: the size of dyn std::fmt::Debug cannot be statically determined --> $DIR/dst-index.rs:44:5 | LL | T[0]; | ^^^^ +error[E0507]: cannot move out of borrowed content + --> $DIR/dst-index.rs:41:5 + | +LL | S[0]; + | ^^^^ cannot move out of borrowed content + error[E0507]: cannot move out of borrowed content --> $DIR/dst-index.rs:44:5 | diff --git a/src/test/ui/dst/dst-rvalue.nll.stderr b/src/test/ui/dst/dst-rvalue.nll.stderr index 5eadcc3def5ff..b120da773a24a 100644 --- a/src/test/ui/dst/dst-rvalue.nll.stderr +++ b/src/test/ui/dst/dst-rvalue.nll.stderr @@ -4,18 +4,18 @@ error[E0161]: cannot move a value of type str: the size of str cannot be statica LL | let _x: Box = box *"hello world"; | ^^^^^^^^^^^^^^ -error[E0507]: cannot move out of borrowed content - --> $DIR/dst-rvalue.rs:16:28 - | -LL | let _x: Box = box *"hello world"; - | ^^^^^^^^^^^^^^ cannot move out of borrowed content - error[E0161]: cannot move a value of type [isize]: the size of [isize] cannot be statically determined --> $DIR/dst-rvalue.rs:21:32 | LL | let _x: Box<[isize]> = box *array; | ^^^^^^ +error[E0507]: cannot move out of borrowed content + --> $DIR/dst-rvalue.rs:16:28 + | +LL | let _x: Box = box *"hello world"; + | ^^^^^^^^^^^^^^ cannot move out of borrowed content + error[E0508]: cannot move out of type `[isize]`, a non-copy slice --> $DIR/dst-rvalue.rs:21:32 | diff --git a/src/test/ui/error-codes/E0161.ast.stderr b/src/test/ui/error-codes/E0161.ast.stderr new file mode 100644 index 0000000000000..62e8676e63198 --- /dev/null +++ b/src/test/ui/error-codes/E0161.ast.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:9 + | +LL | box *x; //~ ERROR E0161 + | ^^ + +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.astul.stderr b/src/test/ui/error-codes/E0161.astul.stderr new file mode 100644 index 0000000000000..79080fb4eae15 --- /dev/null +++ b/src/test/ui/error-codes/E0161.astul.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:5 + | +LL | box *x; //~ ERROR E0161 + | ^^^^^^ + +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.edition.stderr b/src/test/ui/error-codes/E0161.edition.stderr new file mode 100644 index 0000000000000..62e8676e63198 --- /dev/null +++ b/src/test/ui/error-codes/E0161.edition.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:9 + | +LL | box *x; //~ ERROR E0161 + | ^^ + +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.editionul.stderr b/src/test/ui/error-codes/E0161.editionul.stderr new file mode 100644 index 0000000000000..79080fb4eae15 --- /dev/null +++ b/src/test/ui/error-codes/E0161.editionul.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:5 + | +LL | box *x; //~ ERROR E0161 + | ^^^^^^ + +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 new file mode 100644 index 0000000000000..62e8676e63198 --- /dev/null +++ b/src/test/ui/error-codes/E0161.nll.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:9 + | +LL | box *x; //~ ERROR E0161 + | ^^ + +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.nllul.stderr b/src/test/ui/error-codes/E0161.nllul.stderr new file mode 100644 index 0000000000000..79080fb4eae15 --- /dev/null +++ b/src/test/ui/error-codes/E0161.nllul.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:5 + | +LL | box *x; //~ ERROR E0161 + | ^^^^^^ + +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 81adf9083024d..edc5a84a84367 100644 --- a/src/test/ui/error-codes/E0161.rs +++ b/src/test/ui/error-codes/E0161.rs @@ -8,9 +8,28 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-compare-mode-nll + +// Check that E0161 is a hard error in all possible configurations that might +// affect it. + +// revisions: ast nll zflags edition astul nllul zflagsul editionul +//[zflags]compile-flags: -Z borrowck=migrate -Z two-phase-borrows +//[edition]edition:2018 +//[zflagsul]compile-flags: -Z borrowck=migrate -Z two-phase-borrows +//[editionul]edition:2018 + +#![cfg_attr(nll, feature(nll))] +#![cfg_attr(nllul, feature(nll))] +#![cfg_attr(astul, feature(unsized_locals))] +#![cfg_attr(zflagsul, feature(unsized_locals))] +#![cfg_attr(nllul, feature(unsized_locals))] +#![cfg_attr(editionul, feature(unsized_locals))] + #![feature(box_syntax)] -fn main() { - let _x: Box = box *"hello"; //~ ERROR E0161 - //~^ ERROR E0507 +fn foo(x: Box<[i32]>) { + box *x; //~ ERROR E0161 } + +fn main() {} diff --git a/src/test/ui/error-codes/E0161.zflags.stderr b/src/test/ui/error-codes/E0161.zflags.stderr new file mode 100644 index 0000000000000..62e8676e63198 --- /dev/null +++ b/src/test/ui/error-codes/E0161.zflags.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:9 + | +LL | box *x; //~ ERROR E0161 + | ^^ + +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.zflagsul.stderr b/src/test/ui/error-codes/E0161.zflagsul.stderr new file mode 100644 index 0000000000000..79080fb4eae15 --- /dev/null +++ b/src/test/ui/error-codes/E0161.zflagsul.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined + --> $DIR/E0161.rs:32:5 + | +LL | box *x; //~ ERROR E0161 + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0161`.