Skip to content

Commit a8c11d2

Browse files
committed
Auto merge of #53575 - matthewjasper:unsized-is-an-error, r=estebank
Don't reduce E0161 to a warning in NLL migrate mode This error has been on stable for a while, and allowing such code cause the compile to later ICE (since we can't codegen it). Errors `box UNSIZED EXPR` with unsized locals because it's not compatible with the current evaluation order (create the box before evaluating the expressions). cc #53469 (fixes the ICE in this case) cc @qnighy
2 parents c318691 + cd92da8 commit a8c11d2

13 files changed

+129
-47
lines changed

src/librustc_mir/borrow_check/nll/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
120120
flow_inits,
121121
move_data,
122122
elements,
123-
errors_buffer,
124123
);
125124

126125
if let Some(all_facts) = &mut all_facts {

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+23-31
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ use rustc::traits::query::type_op;
3636
use rustc::traits::query::{Fallible, NoSolution};
3737
use rustc::ty::fold::TypeFoldable;
3838
use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
39-
use rustc_errors::Diagnostic;
4039
use std::fmt;
4140
use std::rc::Rc;
4241
use syntax_pos::{Span, DUMMY_SP};
@@ -103,8 +102,7 @@ mod relate_tys;
103102
/// - `liveness` -- results of a liveness computation on the MIR; used to create liveness
104103
/// constraints for the regions in the types of variables
105104
/// - `flow_inits` -- results of a maybe-init dataflow analysis
106-
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
107-
/// - `errors_buffer` -- errors are sent here for future reporting
105+
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysiss
108106
pub(crate) fn type_check<'gcx, 'tcx>(
109107
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
110108
param_env: ty::ParamEnv<'gcx>,
@@ -117,7 +115,6 @@ pub(crate) fn type_check<'gcx, 'tcx>(
117115
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
118116
move_data: &MoveData<'tcx>,
119117
elements: &Rc<RegionValueElements>,
120-
errors_buffer: &mut Vec<Diagnostic>,
121118
) -> MirTypeckResults<'tcx> {
122119
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
123120
let mut constraints = MirTypeckRegionConstraints {
@@ -157,7 +154,6 @@ pub(crate) fn type_check<'gcx, 'tcx>(
157154
&region_bound_pairs,
158155
Some(implicit_region_bound),
159156
Some(&mut borrowck_context),
160-
Some(errors_buffer),
161157
|cx| {
162158
cx.equate_inputs_and_outputs(
163159
mir,
@@ -185,7 +181,6 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
185181
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
186182
implicit_region_bound: Option<ty::Region<'tcx>>,
187183
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
188-
errors_buffer: Option<&mut Vec<Diagnostic>>,
189184
mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R,
190185
) -> R where {
191186
let mut checker = TypeChecker::new(
@@ -205,7 +200,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
205200

206201
if !errors_reported {
207202
// if verifier failed, don't do further checks to avoid ICEs
208-
checker.typeck_mir(mir, errors_buffer);
203+
checker.typeck_mir(mir);
209204
}
210205

211206
extra(&mut checker)
@@ -989,7 +984,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
989984
mir: &Mir<'tcx>,
990985
term: &Terminator<'tcx>,
991986
term_location: Location,
992-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
993987
) {
994988
debug!("check_terminator: {:?}", term);
995989
let tcx = self.tcx();
@@ -1069,7 +1063,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10691063
&sig,
10701064
);
10711065
let sig = self.normalize(sig, term_location);
1072-
self.check_call_dest(mir, term, &sig, destination, term_location, errors_buffer);
1066+
self.check_call_dest(mir, term, &sig, destination, term_location);
10731067

10741068
self.prove_predicates(
10751069
sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
@@ -1143,7 +1137,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11431137
sig: &ty::FnSig<'tcx>,
11441138
destination: &Option<(Place<'tcx>, BasicBlock)>,
11451139
term_location: Location,
1146-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
11471140
) {
11481141
let tcx = self.tcx();
11491142
match *destination {
@@ -1177,7 +1170,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11771170
// this check is done at `check_local`.
11781171
if self.tcx().features().unsized_locals {
11791172
let span = term.source_info.span;
1180-
self.ensure_place_sized(dest_ty, span, errors_buffer);
1173+
self.ensure_place_sized(dest_ty, span);
11811174
}
11821175
}
11831176
None => {
@@ -1330,7 +1323,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13301323
mir: &Mir<'tcx>,
13311324
local: Local,
13321325
local_decl: &LocalDecl<'tcx>,
1333-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
13341326
) {
13351327
match mir.local_kind(local) {
13361328
LocalKind::ReturnPointer | LocalKind::Arg => {
@@ -1346,18 +1338,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13461338
}
13471339

13481340
// When `#![feature(unsized_locals)]` is enabled, only function calls
1349-
// are checked in `check_call_dest`.
1341+
// and nullary ops are checked in `check_call_dest`.
13501342
if !self.tcx().features().unsized_locals {
13511343
let span = local_decl.source_info.span;
13521344
let ty = local_decl.ty;
1353-
self.ensure_place_sized(ty, span, errors_buffer);
1345+
self.ensure_place_sized(ty, span);
13541346
}
13551347
}
13561348

1357-
fn ensure_place_sized(&mut self,
1358-
ty: Ty<'tcx>,
1359-
span: Span,
1360-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>) {
1349+
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
13611350
let tcx = self.tcx();
13621351

13631352
// Erase the regions from `ty` to get a global type. The
@@ -1379,15 +1368,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13791368
cannot be statically determined",
13801369
ty
13811370
);
1382-
if let Some(ref mut errors_buffer) = *errors_buffer {
1383-
diag.buffer(errors_buffer);
1384-
} else {
1385-
// we're allowed to use emit() here because the
1386-
// NLL migration will be turned on (and thus
1387-
// errors will need to be buffered) *only if*
1388-
// errors_buffer is Some.
1389-
diag.emit();
1390-
}
1371+
1372+
// While this is located in `nll::typeck` this error is not
1373+
// an NLL error, it's a required check to prevent creation
1374+
// of unsized rvalues in certain cases:
1375+
// * operand of a box expression
1376+
// * callee in a call expression
1377+
diag.emit();
13911378
}
13921379
}
13931380
}
@@ -1462,6 +1449,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
14621449
},
14631450

14641451
Rvalue::NullaryOp(_, ty) => {
1452+
// Even with unsized locals cannot box an unsized value.
1453+
if self.tcx().features().unsized_locals {
1454+
let span = mir.source_info(location).span;
1455+
self.ensure_place_sized(ty, span);
1456+
}
1457+
14651458
let trait_ref = ty::TraitRef {
14661459
def_id: tcx.lang_items().sized_trait().unwrap(),
14671460
substs: tcx.mk_substs_trait(ty, &[]),
@@ -1895,12 +1888,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
18951888
})
18961889
}
18971890

1898-
fn typeck_mir(&mut self, mir: &Mir<'tcx>, mut errors_buffer: Option<&mut Vec<Diagnostic>>) {
1891+
fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
18991892
self.last_span = mir.span;
19001893
debug!("run_on_mir: {:?}", mir.span);
19011894

19021895
for (local, local_decl) in mir.local_decls.iter_enumerated() {
1903-
self.check_local(mir, local, local_decl, &mut errors_buffer);
1896+
self.check_local(mir, local, local_decl);
19041897
}
19051898

19061899
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
@@ -1916,7 +1909,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
19161909
location.statement_index += 1;
19171910
}
19181911

1919-
self.check_terminator(mir, block_data.terminator(), location, &mut errors_buffer);
1912+
self.check_terminator(mir, block_data.terminator(), location);
19201913
self.check_iscleanup(mir, block_data);
19211914
}
19221915
}
@@ -1973,7 +1966,6 @@ impl MirPass for TypeckMir {
19731966
&[],
19741967
None,
19751968
None,
1976-
None,
19771969
|_| (),
19781970
);
19791971

src/test/ui/dst/dst-index.nll.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ error[E0161]: cannot move a value of type str: the size of str cannot be statica
44
LL | S[0];
55
| ^^^^
66

7-
error[E0507]: cannot move out of borrowed content
8-
--> $DIR/dst-index.rs:41:5
9-
|
10-
LL | S[0];
11-
| ^^^^ cannot move out of borrowed content
12-
137
error[E0161]: cannot move a value of type dyn std::fmt::Debug: the size of dyn std::fmt::Debug cannot be statically determined
148
--> $DIR/dst-index.rs:44:5
159
|
1610
LL | T[0];
1711
| ^^^^
1812

13+
error[E0507]: cannot move out of borrowed content
14+
--> $DIR/dst-index.rs:41:5
15+
|
16+
LL | S[0];
17+
| ^^^^ cannot move out of borrowed content
18+
1919
error[E0507]: cannot move out of borrowed content
2020
--> $DIR/dst-index.rs:44:5
2121
|

src/test/ui/dst/dst-rvalue.nll.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ error[E0161]: cannot move a value of type str: the size of str cannot be statica
44
LL | let _x: Box<str> = box *"hello world";
55
| ^^^^^^^^^^^^^^
66

7-
error[E0507]: cannot move out of borrowed content
8-
--> $DIR/dst-rvalue.rs:16:28
9-
|
10-
LL | let _x: Box<str> = box *"hello world";
11-
| ^^^^^^^^^^^^^^ cannot move out of borrowed content
12-
137
error[E0161]: cannot move a value of type [isize]: the size of [isize] cannot be statically determined
148
--> $DIR/dst-rvalue.rs:21:32
159
|
1610
LL | let _x: Box<[isize]> = box *array;
1711
| ^^^^^^
1812

13+
error[E0507]: cannot move out of borrowed content
14+
--> $DIR/dst-rvalue.rs:16:28
15+
|
16+
LL | let _x: Box<str> = box *"hello world";
17+
| ^^^^^^^^^^^^^^ cannot move out of borrowed content
18+
1919
error[E0508]: cannot move out of type `[isize]`, a non-copy slice
2020
--> $DIR/dst-rvalue.rs:21:32
2121
|
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:9
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:5
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:9
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:5
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:9
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:5
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.

src/test/ui/error-codes/E0161.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,28 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// ignore-compare-mode-nll
12+
13+
// Check that E0161 is a hard error in all possible configurations that might
14+
// affect it.
15+
16+
// revisions: ast nll zflags edition astul nllul zflagsul editionul
17+
//[zflags]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
18+
//[edition]edition:2018
19+
//[zflagsul]compile-flags: -Z borrowck=migrate -Z two-phase-borrows
20+
//[editionul]edition:2018
21+
22+
#![cfg_attr(nll, feature(nll))]
23+
#![cfg_attr(nllul, feature(nll))]
24+
#![cfg_attr(astul, feature(unsized_locals))]
25+
#![cfg_attr(zflagsul, feature(unsized_locals))]
26+
#![cfg_attr(nllul, feature(unsized_locals))]
27+
#![cfg_attr(editionul, feature(unsized_locals))]
28+
1129
#![feature(box_syntax)]
1230

13-
fn main() {
14-
let _x: Box<str> = box *"hello"; //~ ERROR E0161
15-
//~^ ERROR E0507
31+
fn foo(x: Box<[i32]>) {
32+
box *x; //~ ERROR E0161
1633
}
34+
35+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:9
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0161]: cannot move a value of type [i32]: the size of [i32] cannot be statically determined
2+
--> $DIR/E0161.rs:32:5
3+
|
4+
LL | box *x; //~ ERROR E0161
5+
| ^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0161`.

0 commit comments

Comments
 (0)