extract input_output code into its own module
No functional change.
This commit is contained in:
parent
a66c6512aa
commit
da63aaa7ab
2 changed files with 101 additions and 51 deletions
75
src/librustc_mir/borrow_check/nll/type_check/input_output.rs
Normal file
75
src/librustc_mir/borrow_check/nll/type_check/input_output.rs
Normal 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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue