extract input_output code into its own module

No functional change.
This commit is contained in:
Niko Matsakis 2017-12-10 09:56:13 -05:00
parent a66c6512aa
commit da63aaa7ab
2 changed files with 101 additions and 51 deletions

View file

@ -0,0 +1,75 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This module contains code to equate the input/output types appearing
//! in the MIR with the expected input/output types from the function
//! signature. This requires a bit of processing, as the expected types
//! are supplied to us before normalization and may contain existential
//! `impl Trait` instances. In contrast, the input/output types found in
//! the MIR (specifically, in the special local variables for the
//! `RETURN_PLACE` the MIR arguments) are always fully normalize (and
//! contain revealed `impl Trait` values).
use borrow_check::nll::universal_regions::UniversalRegions;
use rustc::ty::Ty;
use rustc::mir::*;
use rustc_data_structures::indexed_vec::Idx;
use super::{AtLocation, TypeChecker};
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
pub(super) fn equate_inputs_and_outputs(
&mut self,
mir: &Mir<'tcx>,
universal_regions: &UniversalRegions<'tcx>,
) {
let &UniversalRegions {
unnormalized_output_ty,
unnormalized_input_tys,
..
} = universal_regions;
let start_position = Location {
block: START_BLOCK,
statement_index: 0,
};
// Equate expected input tys with those in the MIR.
let argument_locals = (1..).map(Local::new);
for (&unnormalized_input_ty, local) in unnormalized_input_tys.iter().zip(argument_locals) {
let input_ty = self.normalize(&unnormalized_input_ty, start_position);
let mir_input_ty = mir.local_decls[local].ty;
self.equate_normalized_input_or_output(start_position, input_ty, mir_input_ty);
}
// Return types are a bit more complex. They may contain existential `impl Trait`
// types.
let output_ty = self.normalize(&unnormalized_output_ty, start_position);
let mir_output_ty = mir.local_decls[RETURN_PLACE].ty;
self.equate_normalized_input_or_output(start_position, output_ty, mir_output_ty);
}
fn equate_normalized_input_or_output(&mut self, location: Location, a: Ty<'tcx>, b: Ty<'tcx>) {
debug!("equate_normalized_input_or_output(a={:?}, b={:?})", a, b);
if let Err(terr) = self.eq_types(a, b, location.at_self()) {
span_mirbug!(
self,
location,
"equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`",
a,
b,
terr
);
}
}
}

View file

@ -36,7 +36,32 @@ use util::liveness::LivenessResults;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::Idx;
macro_rules! span_mirbug {
($context:expr, $elem:expr, $($message:tt)*) => ({
$crate::borrow_check::nll::type_check::mirbug(
$context.tcx(),
$context.last_span,
&format!(
"broken MIR in {:?} ({:?}): {}",
$context.body_id,
$elem,
format_args!($($message)*),
),
)
})
}
macro_rules! span_mirbug_and_err {
($context:expr, $elem:expr, $($message:tt)*) => ({
{
span_mirbug!($context, $elem, $($message)*);
$context.error()
}
})
}
mod liveness;
mod input_output;
/// Type checks the given `mir` in the context of the inference
/// context `infcx`. Returns any region constraints that have yet to
@ -88,18 +113,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
&mut |cx| {
liveness::generate(cx, mir, liveness, flow_inits, move_data);
// Equate the input and output tys given by the user with
// the ones found in the MIR.
let &UniversalRegions {
unnormalized_output_ty,
unnormalized_input_tys,
..
} = universal_regions;
cx.equate_input_or_output(unnormalized_output_ty, mir.local_decls[RETURN_PLACE].ty);
let arg_locals = (1..).map(Local::new);
for (&input_ty, local) in unnormalized_input_tys.iter().zip(arg_locals) {
cx.equate_input_or_output(input_ty, mir.local_decls[local].ty);
}
cx.equate_inputs_and_outputs(mir, universal_regions);
},
)
}
@ -136,7 +150,6 @@ fn type_check_internal<'gcx, 'tcx>(
checker.constraints
}
fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
// We sometimes see MIR failures (notably predicate failures) due to
// the fact that we check rvalue sized predicates here. So use `delay_span_bug`
@ -144,25 +157,6 @@ fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
tcx.sess.diagnostic().delay_span_bug(span, msg);
}
macro_rules! span_mirbug {
($context:expr, $elem:expr, $($message:tt)*) => ({
mirbug($context.tcx(), $context.last_span,
&format!("broken MIR in {:?} ({:?}): {}",
$context.body_id,
$elem,
format_args!($($message)*)))
})
}
macro_rules! span_mirbug_and_err {
($context:expr, $elem:expr, $($message:tt)*) => ({
{
span_mirbug!($context, $elem, $($message)*);
$context.error()
}
})
}
enum FieldAccessError {
OutOfRange { field_count: usize },
}
@ -714,25 +708,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
})
}
fn equate_input_or_output(&mut self, unnormalized_a: Ty<'tcx>, b: Ty<'tcx>) {
let start_position = Location {
block: START_BLOCK,
statement_index: 0,
};
let a = self.normalize(&unnormalized_a, start_position);
if let Err(terr) = self.eq_types(a, b, start_position.at_self()) {
span_mirbug!(
self,
start_position,
"bad input or output {:?} normalized to {:?} should equal {:?} but got error {:?}",
unnormalized_a,
a,
b,
terr
);
}
}
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
self.infcx.tcx
}