Skip to content

Commit

Permalink
FIXME thread the errors_buffer down into nll::type_check.
Browse files Browse the repository at this point in the history
Right now its solely used for `check_local`, which ... I guess is not surprising?

This commit is tagged as "FIXME" because it explicitly imports the
`errors::Emit` trait since in one place it has a pretty dirty hack
where it dynamically detects whether we are buffering the errors or
not (based on whether it was passed a `Some(&mut errors_buffer)`).
  • Loading branch information
pnkfelix committed Jul 20, 2018
1 parent 31acb7d commit 389c4cf
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/librustc_mir/borrow_check/nll/mod.rs
Expand Up @@ -119,6 +119,7 @@ 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 {
Expand Down
59 changes: 39 additions & 20 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Expand Up @@ -40,6 +40,7 @@ use std::rc::Rc;
use syntax_pos::{Span, DUMMY_SP};
use transform::{MirPass, MirSource};
use util::liveness::LivenessResults;
use rustc_errors::DiagnosticBuilder;

use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::Idx;
Expand Down Expand Up @@ -101,8 +102,9 @@ mod 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
pub(crate) fn type_check<'gcx, 'tcx>(
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
/// - `errors_buffer` -- errors are sent here for future reporting
pub(crate) fn type_check<'cx, 'gcx, 'tcx>(
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'gcx>,
mir: &Mir<'tcx>,
mir_def_id: DefId,
Expand All @@ -114,6 +116,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
elements: &Rc<RegionValueElements>,
errors_buffer: &mut Vec<DiagnosticBuilder<'cx>>,
) -> MirTypeckRegionConstraints<'tcx> {
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
let mut constraints = MirTypeckRegionConstraints {
Expand All @@ -139,28 +142,28 @@ pub(crate) fn type_check<'gcx, 'tcx>(
&universal_regions.region_bound_pairs,
Some(implicit_region_bound),
Some(&mut borrowck_context),
Some(errors_buffer),
|cx| {
liveness::generate(cx, mir, liveness, flow_inits, move_data);

cx.equate_inputs_and_outputs(mir, mir_def_id, universal_regions);
},
);
}

constraints
}

fn type_check_internal<'a, 'gcx, 'tcx, F>(
fn type_check_internal<'a, 'errs, 'gcx, 'tcx, F>(
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
mir_def_id: DefId,
param_env: ty::ParamEnv<'gcx>,
mir: &'a Mir<'tcx>,
region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
implicit_region_bound: Option<ty::Region<'tcx>>,
borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
errors_buffer: Option<&mut Vec<DiagnosticBuilder<'errs>>>,
mut extra: F,
)
where F: FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>)
where F: FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>), 'errs: 'a, 'gcx: 'errs
{
let mut checker = TypeChecker::new(
infcx,
Expand All @@ -179,7 +182,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, F>(

if !errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
checker.typeck_mir(mir);
checker.typeck_mir(mir, errors_buffer);
}

extra(&mut checker);
Expand Down Expand Up @@ -1226,7 +1229,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}

fn check_local(&mut self, mir: &Mir<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
fn check_local<'cx>(&mut self,
mir: &Mir<'tcx>,
local: Local,
local_decl: &LocalDecl<'tcx>,
errors_buffer: &mut Option<&mut Vec<DiagnosticBuilder<'cx>>>)
where 'cx: 'a, 'gcx: 'cx
{
// we're allowed to use emit() here because the NLL migration
// will be turned on (and thus errors will need to be
// buffered) if *and only if* errors_buffer is Some.
use syntax::errors::Emit;
match mir.local_kind(local) {
LocalKind::ReturnPointer | LocalKind::Arg => {
// return values of normal functions are required to be
Expand Down Expand Up @@ -1254,15 +1267,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
// slot or local, so to find all unsized rvalues it is enough
// to check all temps, return slots and locals.
if let None = self.reported_errors.replace((ty, span)) {
// FIXME
span_err!(
self.tcx().sess,
span,
E0161,
"cannot move a value of type {0}: the size of {0} \
cannot be statically determined",
ty
);
let mut diag = struct_span_err!(self.tcx().sess,
span,
E0161,
"cannot move a value of type {0}: the size of {0} \
cannot be statically determined",
ty);
if let Some(ref mut errors_buffer) = *errors_buffer {
errors_buffer.push(diag);
} else {
diag.emit();
}
}
}
}
Expand Down Expand Up @@ -1742,12 +1757,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
})
}

fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
fn typeck_mir<'errs>(&mut self,
mir: &Mir<'tcx>,
mut errors_buffer: Option<&mut Vec<DiagnosticBuilder<'errs>>>)
where 'errs: 'a, 'gcx: 'errs
{
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);
self.check_local(mir, local, local_decl, &mut errors_buffer);
}

for (block, block_data) in mir.basic_blocks().iter_enumerated() {
Expand Down Expand Up @@ -1812,7 +1831,7 @@ impl MirPass for TypeckMir {

let param_env = tcx.param_env(def_id);
tcx.infer_ctxt().enter(|infcx| {
type_check_internal(&infcx, def_id, param_env, mir, &[], None, None, |_| ());
type_check_internal(&infcx, def_id, param_env, mir, &[], None, None, None, |_| ());

// For verification purposes, we just ignore the resulting
// region constraint sets. Not our problem. =)
Expand Down

0 comments on commit 389c4cf

Please sign in to comment.