Skip to content

Commit b83fe42

Browse files
committed
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
1 parent b75b047 commit b83fe42

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
125125
flow_inits,
126126
move_data,
127127
elements,
128-
errors_buffer,
129128
);
130129

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

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

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use rustc::traits::query::type_op;
3838
use rustc::traits::query::{Fallible, NoSolution};
3939
use rustc::ty::fold::TypeFoldable;
4040
use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
41-
use rustc_errors::Diagnostic;
4241
use std::fmt;
4342
use std::rc::Rc;
4443
use syntax_pos::{Span, DUMMY_SP};
@@ -106,8 +105,7 @@ mod relate_tys;
106105
/// - `liveness` -- results of a liveness computation on the MIR; used to create liveness
107106
/// constraints for the regions in the types of variables
108107
/// - `flow_inits` -- results of a maybe-init dataflow analysis
109-
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
110-
/// - `errors_buffer` -- errors are sent here for future reporting
108+
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysiss
111109
pub(crate) fn type_check<'gcx, 'tcx>(
112110
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
113111
param_env: ty::ParamEnv<'gcx>,
@@ -120,7 +118,6 @@ pub(crate) fn type_check<'gcx, 'tcx>(
120118
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
121119
move_data: &MoveData<'tcx>,
122120
elements: &Rc<RegionValueElements>,
123-
errors_buffer: &mut Vec<Diagnostic>,
124121
) -> MirTypeckResults<'tcx> {
125122
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
126123
let mut constraints = MirTypeckRegionConstraints {
@@ -161,7 +158,6 @@ pub(crate) fn type_check<'gcx, 'tcx>(
161158
&region_bound_pairs,
162159
Some(implicit_region_bound),
163160
Some(&mut borrowck_context),
164-
Some(errors_buffer),
165161
|cx| {
166162
cx.equate_inputs_and_outputs(
167163
mir,
@@ -191,7 +187,6 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
191187
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
192188
implicit_region_bound: Option<ty::Region<'tcx>>,
193189
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
194-
errors_buffer: Option<&mut Vec<Diagnostic>>,
195190
mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R,
196191
) -> R where {
197192
let mut checker = TypeChecker::new(
@@ -211,7 +206,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
211206

212207
if !errors_reported {
213208
// if verifier failed, don't do further checks to avoid ICEs
214-
checker.typeck_mir(mir, errors_buffer);
209+
checker.typeck_mir(mir);
215210
}
216211

217212
extra(&mut checker)
@@ -964,7 +959,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
964959
mir: &Mir<'tcx>,
965960
term: &Terminator<'tcx>,
966961
term_location: Location,
967-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
968962
) {
969963
debug!("check_terminator: {:?}", term);
970964
let tcx = self.tcx();
@@ -1044,7 +1038,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10441038
&sig,
10451039
);
10461040
let sig = self.normalize(sig, term_location);
1047-
self.check_call_dest(mir, term, &sig, destination, term_location, errors_buffer);
1041+
self.check_call_dest(mir, term, &sig, destination, term_location);
10481042

10491043
self.prove_predicates(
10501044
sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
@@ -1118,7 +1112,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11181112
sig: &ty::FnSig<'tcx>,
11191113
destination: &Option<(Place<'tcx>, BasicBlock)>,
11201114
term_location: Location,
1121-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
11221115
) {
11231116
let tcx = self.tcx();
11241117
match *destination {
@@ -1152,7 +1145,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11521145
// this check is done at `check_local`.
11531146
if self.tcx().features().unsized_locals {
11541147
let span = term.source_info.span;
1155-
self.ensure_place_sized(dest_ty, span, errors_buffer);
1148+
self.ensure_place_sized(dest_ty, span);
11561149
}
11571150
}
11581151
None => {
@@ -1305,7 +1298,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13051298
mir: &Mir<'tcx>,
13061299
local: Local,
13071300
local_decl: &LocalDecl<'tcx>,
1308-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
13091301
) {
13101302
match mir.local_kind(local) {
13111303
LocalKind::ReturnPointer | LocalKind::Arg => {
@@ -1321,18 +1313,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13211313
}
13221314

13231315
// When `#![feature(unsized_locals)]` is enabled, only function calls
1324-
// are checked in `check_call_dest`.
1316+
// and nullary ops are checked in `check_call_dest`.
13251317
if !self.tcx().features().unsized_locals {
13261318
let span = local_decl.source_info.span;
13271319
let ty = local_decl.ty;
1328-
self.ensure_place_sized(ty, span, errors_buffer);
1320+
self.ensure_place_sized(ty, span);
13291321
}
13301322
}
13311323

1332-
fn ensure_place_sized(&mut self,
1333-
ty: Ty<'tcx>,
1334-
span: Span,
1335-
errors_buffer: &mut Option<&mut Vec<Diagnostic>>) {
1324+
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
13361325
let tcx = self.tcx();
13371326

13381327
// Erase the regions from `ty` to get a global type. The
@@ -1354,15 +1343,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13541343
cannot be statically determined",
13551344
ty
13561345
);
1357-
if let Some(ref mut errors_buffer) = *errors_buffer {
1358-
diag.buffer(errors_buffer);
1359-
} else {
1360-
// we're allowed to use emit() here because the
1361-
// NLL migration will be turned on (and thus
1362-
// errors will need to be buffered) *only if*
1363-
// errors_buffer is Some.
1364-
diag.emit();
1365-
}
1346+
1347+
// While this is located in `nll::typeck` this error is not
1348+
// an NLL error, it's a required check to prevent creation
1349+
// of unsized rvalues in certain cases:
1350+
// * operand of a box expression
1351+
// * callee in a call expression
1352+
diag.emit();
13661353
}
13671354
}
13681355
}
@@ -1437,6 +1424,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
14371424
},
14381425

14391426
Rvalue::NullaryOp(_, ty) => {
1427+
// Even with unsized locals cannot box an unsized value.
1428+
if self.tcx().features().unsized_locals {
1429+
let span = mir.source_info(location).span;
1430+
self.ensure_place_sized(ty, span);
1431+
}
1432+
14401433
let trait_ref = ty::TraitRef {
14411434
def_id: tcx.lang_items().sized_trait().unwrap(),
14421435
substs: tcx.mk_substs_trait(ty, &[]),
@@ -1840,12 +1833,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
18401833
})
18411834
}
18421835

1843-
fn typeck_mir(&mut self, mir: &Mir<'tcx>, mut errors_buffer: Option<&mut Vec<Diagnostic>>) {
1836+
fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
18441837
self.last_span = mir.span;
18451838
debug!("run_on_mir: {:?}", mir.span);
18461839

18471840
for (local, local_decl) in mir.local_decls.iter_enumerated() {
1848-
self.check_local(mir, local, local_decl, &mut errors_buffer);
1841+
self.check_local(mir, local, local_decl);
18491842
}
18501843

18511844
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
@@ -1861,7 +1854,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
18611854
location.statement_index += 1;
18621855
}
18631856

1864-
self.check_terminator(mir, block_data.terminator(), location, &mut errors_buffer);
1857+
self.check_terminator(mir, block_data.terminator(), location);
18651858
self.check_iscleanup(mir, block_data);
18661859
}
18671860
}
@@ -1918,7 +1911,6 @@ impl MirPass for TypeckMir {
19181911
&[],
19191912
None,
19201913
None,
1921-
None,
19221914
|_| (),
19231915
);
19241916

0 commit comments

Comments
 (0)