about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-12-09 10:56:20 -0500
committerNiko Matsakis <niko@alum.mit.edu>2017-12-20 14:04:52 -0500
commit7f50e7ca8564489b888f23839687b1e076844a49 (patch)
treeadf9ed0441866c8717a8ee8843a4bfe3a699bbd7 /src
parent8e64ba83beac81f38c5b473f9dbee924a03a3ea7 (diff)
downloadrust-7f50e7ca8564489b888f23839687b1e076844a49.tar.gz
rust-7f50e7ca8564489b888f23839687b1e076844a49.zip
extract the writeback code for anon types into InferCtxt
No functional change.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/anon_types/mod.rs103
-rw-r--r--src/librustc_typeck/check/writeback.rs254
2 files changed, 225 insertions, 132 deletions
diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs
index 74daeb837c9..f163076218a 100644
--- a/src/librustc/infer/anon_types/mod.rs
+++ b/src/librustc/infer/anon_types/mod.rs
@@ -11,12 +11,13 @@
 use hir::def_id::DefId;
 use infer::{self, InferCtxt, InferOk, TypeVariableOrigin};
 use infer::outlives::free_region_map::FreeRegionRelations;
+use rustc_data_structures::fx::FxHashMap;
 use syntax::ast;
 use traits::{self, PredicateObligation};
 use ty::{self, Ty};
 use ty::fold::{BottomUpFolder, TypeFoldable};
 use ty::outlives::Component;
-use ty::subst::Substs;
+use ty::subst::{Kind, Substs};
 use util::nodemap::DefIdMap;
 
 pub type AnonTypeMap<'tcx> = DefIdMap<AnonTypeDecl<'tcx>>;
@@ -375,6 +376,106 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
         }
     }
+
+    /// Given the fully resolved, instantiated type for an anonymous
+    /// type, i.e., the value of an inference variable like C1 or C2
+    /// (*), computes the "definition type" for an abstract type
+    /// definition -- that is, the inferred value of `Foo1<'x>` or
+    /// `Foo2<'x>` that we would conceptually use in its definition:
+    ///
+    ///     abstract type Foo1<'x>: Bar<'x> = AAA; <-- this type AAA
+    ///     abstract type Foo2<'x>: Bar<'x> = BBB; <-- or this type BBB
+    ///     fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
+    ///
+    /// Note that these values are defined in terms of a distinct set of
+    /// generic parameters (`'x` instead of `'a`) from C1 or C2. The main
+    /// purpose of this function is to do that translation.
+    ///
+    /// (*) C1 and C2 were introduced in the comments on
+    /// `constrain_anon_types`. Read that comment for more context.
+    ///
+    /// # Parameters
+    ///
+    /// - `def_id`, the `impl Trait` type
+    /// - `anon_defn`, the anonymous definition created in `instantiate_anon_types`
+    /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
+    ///   `anon_defn.concrete_ty`
+    pub fn infer_anon_definition_from_instantiation(
+        &self,
+        def_id: DefId,
+        anon_defn: &AnonTypeDecl<'tcx>,
+        instantiated_ty: Ty<'gcx>,
+    ) -> Ty<'gcx> {
+        debug!(
+            "infer_anon_definition_from_instantiation(instantiated_ty={:?})",
+            instantiated_ty
+        );
+
+        let gcx = self.tcx.global_tcx();
+
+        // Use substs to build up a reverse map from regions to their
+        // identity mappings. This is necessary because of `impl
+        // Trait` lifetimes are computed by replacing existing
+        // lifetimes with 'static and remapping only those used in the
+        // `impl Trait` return type, resulting in the parameters
+        // shifting.
+        let id_substs = Substs::identity_for_item(gcx, def_id);
+        let map: FxHashMap<Kind<'tcx>, Kind<'gcx>> = anon_defn
+            .substs
+            .iter()
+            .enumerate()
+            .map(|(index, subst)| (*subst, id_substs[index]))
+            .collect();
+
+        // Convert the type from the function into a type valid outside
+        // the function, by replacing invalid regions with 'static,
+        // after producing an error for each of them.
+        let definition_ty = gcx.fold_regions(&instantiated_ty, &mut false, |r, _| {
+            match *r {
+                // 'static and early-bound regions are valid.
+                ty::ReStatic | ty::ReEmpty => r,
+
+                // All other regions, we map them appropriately to their adjusted
+                // indices, erroring if we find any lifetimes that were not mapped
+                // into the new set.
+                _ => if let Some(r1) = map.get(&Kind::from(r)).and_then(|k| k.as_region()) {
+                    r1
+                } else {
+                    // No mapping was found. This means that
+                    // it is either a disallowed lifetime,
+                    // which will be caught by regionck, or it
+                    // is a region in a non-upvar closure
+                    // generic, which is explicitly
+                    // allowed. If that surprises you, read
+                    // on.
+                    //
+                    // The case of closure is a somewhat
+                    // subtle (read: hacky) consideration. The
+                    // problem is that our closure types
+                    // currently include all the lifetime
+                    // parameters declared on the enclosing
+                    // function, even if they are unused by
+                    // the closure itself. We can't readily
+                    // filter them out, so here we replace
+                    // those values with `'empty`. This can't
+                    // really make a difference to the rest of
+                    // the compiler; those regions are ignored
+                    // for the outlives relation, and hence
+                    // don't affect trait selection or auto
+                    // traits, and they are erased during
+                    // trans.
+                    gcx.types.re_empty
+                },
+            }
+        });
+
+        debug!(
+            "infer_anon_definition_from_instantiation: definition_ty={:?}",
+            definition_ty
+        );
+
+        definition_ty
+    }
 }
 
 struct Instantiator<'a, 'gcx: 'tcx, 'tcx: 'a> {
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 1052f031bbf..29dc983ab56 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -15,12 +15,11 @@
 use check::FnCtxt;
 use rustc::hir;
 use rustc::hir::def_id::{DefId, DefIndex};
-use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use rustc::infer::{InferCtxt};
+use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc::infer::InferCtxt;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::fold::{TypeFolder, TypeFoldable};
-use rustc::ty::subst::{Kind, Substs};
-use rustc::util::nodemap::{DefIdSet, FxHashMap};
+use rustc::ty::fold::{TypeFoldable, TypeFolder};
+use rustc::util::nodemap::DefIdSet;
 use syntax::ast;
 use syntax_pos::Span;
 use std::mem;
@@ -30,8 +29,7 @@ use std::rc::Rc;
 // Entry point
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
-    pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body)
-                                     -> &'gcx ty::TypeckTables<'gcx> {
+    pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::TypeckTables<'gcx> {
         let item_id = self.tcx.hir.body_owner(body.id());
         let item_def_id = self.tcx.hir.local_def_id(item_id);
 
@@ -48,14 +46,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         wbcx.visit_cast_types();
         wbcx.visit_free_region_map();
 
-        let used_trait_imports = mem::replace(&mut self.tables.borrow_mut().used_trait_imports,
-                                              Rc::new(DefIdSet()));
-        debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
+        let used_trait_imports = mem::replace(
+            &mut self.tables.borrow_mut().used_trait_imports,
+            Rc::new(DefIdSet()),
+        );
+        debug!(
+            "used_trait_imports({:?}) = {:?}",
+            item_def_id,
+            used_trait_imports
+        );
         wbcx.tables.used_trait_imports = used_trait_imports;
 
         wbcx.tables.tainted_by_errors = self.is_tainted_by_errors();
 
-        debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables);
+        debug!(
+            "writeback: tables for {:?} are {:#?}",
+            item_def_id,
+            wbcx.tables
+        );
 
         self.tcx.alloc_tables(wbcx.tables)
     }
@@ -69,7 +77,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 // there, it applies a few ad-hoc checks that were not convenient to
 // do elsewhere.
 
-struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
+struct WritebackCx<'cx, 'gcx: 'cx + 'tcx, 'tcx: 'cx> {
     fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>,
 
     tables: ty::TypeckTables<'gcx>,
@@ -78,9 +86,10 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
 }
 
 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
-    fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, body: &'gcx hir::Body)
-        -> WritebackCx<'cx, 'gcx, 'tcx>
-    {
+    fn new(
+        fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>,
+        body: &'gcx hir::Body,
+    ) -> WritebackCx<'cx, 'gcx, 'tcx> {
         let owner = fcx.tcx.hir.definitions().node_to_hir_id(body.id().node_id);
 
         WritebackCx {
@@ -95,7 +104,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     }
 
     fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
-        debug!("write_ty_to_tables({:?}, {:?})", hir_id,  ty);
+        debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
         assert!(!ty.needs_infer());
         self.tables.node_types_mut().insert(hir_id, ty);
     }
@@ -106,8 +115,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     // operating on scalars, we clear the overload.
     fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
         match e.node {
-            hir::ExprUnary(hir::UnNeg, ref inner) |
-            hir::ExprUnary(hir::UnNot, ref inner)  => {
+            hir::ExprUnary(hir::UnNeg, ref inner) | hir::ExprUnary(hir::UnNot, ref inner) => {
                 let inner_ty = self.fcx.node_ty(inner.hir_id);
                 let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
 
@@ -117,8 +125,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                     tables.node_substs_mut().remove(e.hir_id);
                 }
             }
-            hir::ExprBinary(ref op, ref lhs, ref rhs) |
-            hir::ExprAssignOp(ref op, ref lhs, ref rhs) => {
+            hir::ExprBinary(ref op, ref lhs, ref rhs)
+            | hir::ExprAssignOp(ref op, ref lhs, ref rhs) => {
                 let lhs_ty = self.fcx.node_ty(lhs.hir_id);
                 let lhs_ty = self.fcx.resolve_type_vars_if_possible(&lhs_ty);
 
@@ -137,15 +145,18 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                                 adjustments.get_mut(lhs.hir_id).map(|a| a.pop());
                                 adjustments.get_mut(rhs.hir_id).map(|a| a.pop());
                             }
-                        },
+                        }
                         hir::ExprAssignOp(..) => {
-                            tables.adjustments_mut().get_mut(lhs.hir_id).map(|a| a.pop());
-                        },
-                        _ => {},
+                            tables
+                                .adjustments_mut()
+                                .get_mut(lhs.hir_id)
+                                .map(|a| a.pop());
+                        }
+                        _ => {}
                     }
                 }
             }
-            _ => {},
+            _ => {}
         }
     }
 }
@@ -189,11 +200,11 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
         match p.node {
             hir::PatKind::Binding(..) => {
                 let bm = *self.fcx
-                              .tables
-                              .borrow()
-                              .pat_binding_modes()
-                              .get(p.hir_id)
-                              .expect("missing binding mode");
+                    .tables
+                    .borrow()
+                    .pat_binding_modes()
+                    .get(p.hir_id)
+                    .expect("missing binding mode");
                 self.tables.pat_binding_modes_mut().insert(p.hir_id, bm);
             }
             _ => {}
@@ -228,14 +239,20 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                 ty::UpvarCapture::ByRef(ref upvar_borrow) => {
                     let r = upvar_borrow.region;
                     let r = self.resolve(&r, &upvar_id.var_id);
-                    ty::UpvarCapture::ByRef(
-                        ty::UpvarBorrow { kind: upvar_borrow.kind, region: r })
+                    ty::UpvarCapture::ByRef(ty::UpvarBorrow {
+                        kind: upvar_borrow.kind,
+                        region: r,
+                    })
                 }
             };
-            debug!("Upvar capture for {:?} resolved to {:?}",
-                   upvar_id,
-                   new_upvar_capture);
-            self.tables.upvar_capture_map.insert(*upvar_id, new_upvar_capture);
+            debug!(
+                "Upvar capture for {:?} resolved to {:?}",
+                upvar_id,
+                new_upvar_capture
+            );
+            self.tables
+                .upvar_capture_map
+                .insert(*upvar_id, new_upvar_capture);
         }
     }
 
@@ -249,7 +266,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                 owner: common_local_id_root.index,
                 local_id: id,
             };
-            self.tables.closure_kind_origins_mut().insert(hir_id, origin);
+            self.tables
+                .closure_kind_origins_mut()
+                .insert(hir_id, origin);
         }
     }
 
@@ -270,7 +289,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     }
 
     fn visit_free_region_map(&mut self) {
-        let free_region_map = self.tcx().lift_to_global(&self.fcx.tables.borrow().free_region_map);
+        let free_region_map = self.tcx()
+            .lift_to_global(&self.fcx.tables.borrow().free_region_map);
         let free_region_map = free_region_map.expect("all regions in free-region-map are global");
         self.tables.free_region_map = free_region_map;
     }
@@ -279,77 +299,25 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
         let gcx = self.tcx().global_tcx();
         for (&def_id, anon_defn) in self.fcx.anon_types.borrow().iter() {
             let node_id = gcx.hir.as_local_node_id(def_id).unwrap();
-            let inside_ty = self.resolve(&anon_defn.concrete_ty, &node_id);
-
-            // Use substs to build up a reverse map from regions
-            // to their identity mappings.
-            // This is necessary because of `impl Trait` lifetimes
-            // are computed by replacing existing lifetimes with 'static
-            // and remapping only those used in the `impl Trait` return type,
-            // resulting in the parameters shifting.
-            let id_substs = Substs::identity_for_item(gcx, def_id);
-            let map: FxHashMap<Kind<'tcx>, Kind<'gcx>> =
-                anon_defn.substs
-                         .iter()
-                         .enumerate()
-                         .map(|(index, subst)| (*subst, id_substs[index]))
-                         .collect();
-
-            // Convert the type from the function into a type valid outside
-            // the function, by replacing invalid regions with 'static,
-            // after producing an error for each of them.
-            let outside_ty = gcx.fold_regions(&inside_ty, &mut false, |r, _| {
-                match *r {
-                    // 'static and early-bound regions are valid.
-                    ty::ReStatic |
-                    ty::ReEmpty => r,
-
-                    // All other regions, we map them appropriately to their adjusted
-                    // indices, erroring if we find any lifetimes that were not mapped
-                    // into the new set.
-                    _ => if let Some(r1) =
-                            map.get(&Kind::from(r)).and_then(|k| k.as_region()) { r1 } else
-                        {
-                            // No mapping was found. This means that
-                            // it is either a disallowed lifetime,
-                            // which will be caught by regionck, or it
-                            // is a region in a non-upvar closure
-                            // generic, which is explicitly
-                            // allowed. If that surprises you, read
-                            // on.
-                            //
-                            // The case of closure is a somewhat
-                            // subtle (read: hacky) consideration. The
-                            // problem is that our closure types
-                            // currently include all the lifetime
-                            // parameters declared on the enclosing
-                            // function, even if they are unused by
-                            // the closure itself. We can't readily
-                            // filter them out, so here we replace
-                            // those values with `'empty`. This can't
-                            // really make a difference to the rest of
-                            // the compiler; those regions are ignored
-                            // for the outlives relation, and hence
-                            // don't affect trait selection or auto
-                            // traits, and they are erased during
-                            // trans.
-                            gcx.types.re_empty
-                        },
-                }
-            });
-
+            let instantiated_ty = self.resolve(&anon_defn.concrete_ty, &node_id);
+            let definition_ty = self.fcx.infer_anon_definition_from_instantiation(
+                def_id,
+                anon_defn,
+                instantiated_ty,
+            );
             let hir_id = self.tcx().hir.node_to_hir_id(node_id);
-            self.tables.node_types_mut().insert(hir_id, outside_ty);
+            self.tables.node_types_mut().insert(hir_id, definition_ty);
         }
     }
 
     fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) {
         // Export associated path extensions and method resultions.
         if let Some(def) = self.fcx
-                               .tables
-                               .borrow_mut()
-                               .type_dependent_defs_mut()
-                               .remove(hir_id) {
+            .tables
+            .borrow_mut()
+            .type_dependent_defs_mut()
+            .remove(hir_id)
+        {
             self.tables.type_dependent_defs_mut().insert(hir_id, def);
         }
 
@@ -373,10 +341,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
 
     fn visit_adjustments(&mut self, span: Span, hir_id: hir::HirId) {
         let adjustment = self.fcx
-                             .tables
-                             .borrow_mut()
-                             .adjustments_mut()
-                             .remove(hir_id);
+            .tables
+            .borrow_mut()
+            .adjustments_mut()
+            .remove(hir_id);
         match adjustment {
             None => {
                 debug!("No adjustments for node {:?}", hir_id);
@@ -384,18 +352,24 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
 
             Some(adjustment) => {
                 let resolved_adjustment = self.resolve(&adjustment, &span);
-                debug!("Adjustments for node {:?}: {:?}", hir_id, resolved_adjustment);
-                self.tables.adjustments_mut().insert(hir_id, resolved_adjustment);
+                debug!(
+                    "Adjustments for node {:?}: {:?}",
+                    hir_id,
+                    resolved_adjustment
+                );
+                self.tables
+                    .adjustments_mut()
+                    .insert(hir_id, resolved_adjustment);
             }
         }
     }
 
     fn visit_pat_adjustments(&mut self, span: Span, hir_id: hir::HirId) {
         let adjustment = self.fcx
-                             .tables
-                             .borrow_mut()
-                             .pat_adjustments_mut()
-                             .remove(hir_id);
+            .tables
+            .borrow_mut()
+            .pat_adjustments_mut()
+            .remove(hir_id);
         match adjustment {
             None => {
                 debug!("No pat_adjustments for node {:?}", hir_id);
@@ -403,8 +377,14 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
 
             Some(adjustment) => {
                 let resolved_adjustment = self.resolve(&adjustment, &span);
-                debug!("pat_adjustments for node {:?}: {:?}", hir_id, resolved_adjustment);
-                self.tables.pat_adjustments_mut().insert(hir_id, resolved_adjustment);
+                debug!(
+                    "pat_adjustments for node {:?}: {:?}",
+                    hir_id,
+                    resolved_adjustment
+                );
+                self.tables
+                    .pat_adjustments_mut()
+                    .insert(hir_id, resolved_adjustment);
             }
         }
     }
@@ -420,7 +400,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                 local_id,
             };
             let fn_sig = self.resolve(fn_sig, &hir_id);
-            self.tables.liberated_fn_sigs_mut().insert(hir_id, fn_sig.clone());
+            self.tables
+                .liberated_fn_sigs_mut()
+                .insert(hir_id, fn_sig.clone());
         }
     }
 
@@ -440,15 +422,18 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     }
 
     fn resolve<T>(&self, x: &T, span: &Locatable) -> T::Lifted
-        where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
+    where
+        T: TypeFoldable<'tcx> + ty::Lift<'gcx>,
     {
         let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body));
         if let Some(lifted) = self.tcx().lift_to_global(&x) {
             lifted
         } else {
-            span_bug!(span.to_span(&self.fcx.tcx),
-                      "writeback: `{:?}` missing from the global type context",
-                      x);
+            span_bug!(
+                span.to_span(&self.fcx.tcx),
+                "writeback: `{:?}` missing from the global type context",
+                x
+            );
         }
     }
 }
@@ -458,11 +443,15 @@ trait Locatable {
 }
 
 impl Locatable for Span {
-    fn to_span(&self, _: &TyCtxt) -> Span { *self }
+    fn to_span(&self, _: &TyCtxt) -> Span {
+        *self
+    }
 }
 
 impl Locatable for ast::NodeId {
-    fn to_span(&self, tcx: &TyCtxt) -> Span { tcx.hir.span(*self) }
+    fn to_span(&self, tcx: &TyCtxt) -> Span {
+        tcx.hir.span(*self)
+    }
 }
 
 impl Locatable for DefIndex {
@@ -483,7 +472,7 @@ impl Locatable for hir::HirId {
 // The Resolver. This is the type folding engine that detects
 // unresolved types and so forth.
 
-struct Resolver<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
+struct Resolver<'cx, 'gcx: 'cx + 'tcx, 'tcx: 'cx> {
     tcx: TyCtxt<'cx, 'gcx, 'tcx>,
     infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
     span: &'cx Locatable,
@@ -491,9 +480,11 @@ struct Resolver<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
 }
 
 impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> {
-    fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, span: &'cx Locatable, body: &'gcx hir::Body)
-        -> Resolver<'cx, 'gcx, 'tcx>
-    {
+    fn new(
+        fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>,
+        span: &'cx Locatable,
+        body: &'gcx hir::Body,
+    ) -> Resolver<'cx, 'gcx, 'tcx> {
         Resolver {
             tcx: fcx.tcx,
             infcx: fcx,
@@ -504,7 +495,8 @@ impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> {
 
     fn report_error(&self, t: Ty<'tcx>) {
         if !self.tcx.sess.has_errors() {
-            self.infcx.need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t);
+            self.infcx
+                .need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t);
         }
     }
 }
@@ -518,8 +510,10 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
         match self.infcx.fully_resolve(&t) {
             Ok(t) => t,
             Err(_) => {
-                debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable",
-                       t);
+                debug!(
+                    "Resolver::fold_ty: input type `{:?}` not fully resolvable",
+                    t
+                );
                 self.report_error(t);
                 self.tcx().types.err
             }
@@ -531,9 +525,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         match self.infcx.fully_resolve(&r) {
             Ok(r) => r,
-            Err(_) => {
-                self.tcx.types.re_static
-            }
+            Err(_) => self.tcx.types.re_static,
         }
     }
 }