]> git.lizzy.rs Git - rust.git/commitdiff
extract `input_output` code into its own module
authorNiko Matsakis <niko@alum.mit.edu>
Sun, 10 Dec 2017 14:56:13 +0000 (09:56 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 20 Dec 2017 19:04:52 +0000 (14:04 -0500)
No functional change.

src/librustc_mir/borrow_check/nll/type_check/input_output.rs [new file with mode: 0644]
src/librustc_mir/borrow_check/nll/type_check/mod.rs

diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
new file mode 100644 (file)
index 0000000..b85573b
--- /dev/null
@@ -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
+            );
+        }
+    }
+}
index a56fb0492761eb2986f407639fbccfd51e2380c9..48750b626114b5cee0dc1b82338fcb378f41c2a6 100644 (file)
 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 @@ fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> UnitRe
         })
     }
 
-    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
     }