]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc_typeck/check/writeback.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / librustc_typeck / check / writeback.rs
index 5f8861f309948d1dfdff5a65d1b18a2f931bc14c..0b70d904c26549830c9a3326afb669ccfa736a93 100644 (file)
@@ -18,7 +18,6 @@ use hir::def_id::DefId;
 use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee};
 use rustc::ty::adjustment;
 use rustc::ty::fold::{TypeFolder,TypeFoldable};
-use rustc::ty::subst::ParamSpace;
 use rustc::infer::{InferCtxt, FixupError};
 use rustc::util::nodemap::DefIdMap;
 use write_substs_to_tcx;
@@ -68,7 +67,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         wbcx.visit_closures();
         wbcx.visit_liberated_fn_sigs();
         wbcx.visit_fru_field_types();
-        wbcx.visit_anon_types();
+        wbcx.visit_anon_types(item_id);
         wbcx.visit_deferred_obligations(item_id);
     }
 }
@@ -88,7 +87,7 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
     // early-bound versions of them, visible from the
     // outside of the function. This is needed by, and
     // only populated if there are any `impl Trait`.
-    free_to_bound_regions: DefIdMap<ty::Region>
+    free_to_bound_regions: DefIdMap<&'gcx ty::Region>
 }
 
 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
@@ -103,23 +102,26 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
             return wbcx;
         }
 
+        let gcx = fcx.tcx.global_tcx();
         let free_substs = fcx.parameter_environment.free_substs;
-        for &space in &ParamSpace::all() {
-            for (i, r) in free_substs.regions.get_slice(space).iter().enumerate() {
-                match *r {
-                    ty::ReFree(ty::FreeRegion {
-                        bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
-                    }) => {
-                        let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion {
-                            space: space,
-                            index: i as u32,
-                            name: name,
-                        });
-                        wbcx.free_to_bound_regions.insert(def_id, bound_region);
-                    }
-                    _ => {
-                        bug!("{:?} is not a free region for an early-bound lifetime", r);
-                    }
+        for (i, k) in free_substs.params().iter().enumerate() {
+            let r = if let Some(r) = k.as_region() {
+                r
+            } else {
+                continue;
+            };
+            match *r {
+                ty::ReFree(ty::FreeRegion {
+                    bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
+                }) => {
+                    let bound_region = gcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
+                        index: i as u32,
+                        name: name,
+                    }));
+                    wbcx.free_to_bound_regions.insert(def_id, bound_region);
+                }
+                _ => {
+                    bug!("{:?} is not a free region for an early-bound lifetime", r);
                 }
             }
         }
@@ -199,7 +201,7 @@ impl<'cx, 'gcx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'gcx, 'tcx> {
         self.visit_method_map_entry(ResolvingExpr(e.span),
                                     MethodCall::expr(e.id));
 
-        if let hir::ExprClosure(_, ref decl, _, _) = e.node {
+        if let hir::ExprClosure(_, ref decl, ..) = e.node {
             for input in &decl.inputs {
                 self.visit_node_id(ResolvingExpr(e.span), input.id);
             }
@@ -300,11 +302,13 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
         }
     }
 
-    fn visit_anon_types(&self) {
+    fn visit_anon_types(&self, item_id: ast::NodeId) {
         if self.fcx.writeback_errors.get() {
             return
         }
 
+        let item_def_id = self.fcx.tcx.map.local_def_id(item_id);
+
         let gcx = self.tcx().global_tcx();
         for (&def_id, &concrete_ty) in self.fcx.anon_types.borrow().iter() {
             let reason = ResolvingAnonTy(def_id);
@@ -313,13 +317,14 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
             // Convert the type from the function into a type valid outside
             // the function, by replacing free regions with early-bound ones.
             let outside_ty = gcx.fold_regions(&inside_ty, &mut false, |r, _| {
-                match r {
+                match *r {
                     // 'static is valid everywhere.
-                    ty::ReStatic => ty::ReStatic,
+                    ty::ReStatic |
+                    ty::ReEmpty => gcx.mk_region(*r),
 
                     // Free regions that come from early-bound regions are valid.
                     ty::ReFree(ty::FreeRegion {
-                        bound_region: ty::BoundRegion::BrNamed(def_id, _, _), ..
+                        bound_region: ty::BoundRegion::BrNamed(def_id, ..), ..
                     }) if self.free_to_bound_regions.contains_key(&def_id) => {
                         self.free_to_bound_regions[&def_id]
                     }
@@ -333,11 +338,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                         span_err!(self.tcx().sess, span, E0564,
                                   "only named lifetimes are allowed in `impl Trait`, \
                                    but `{}` was found in the type `{}`", r, inside_ty);
-                        ty::ReStatic
+                        gcx.mk_region(ty::ReStatic)
                     }
 
                     ty::ReVar(_) |
-                    ty::ReEmpty |
                     ty::ReErased => {
                         let span = reason.span(self.tcx());
                         span_bug!(span, "invalid region in impl Trait: {:?}", r);
@@ -345,9 +349,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                 }
             });
 
-            gcx.tcache.borrow_mut().insert(def_id, ty::TypeScheme {
+            gcx.register_item_type(def_id, ty::TypeScheme {
                 ty: outside_ty,
-                generics: ty::Generics::empty()
+                generics: gcx.lookup_generics(item_def_id)
             });
         }
     }
@@ -628,12 +632,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Resolver<'cx, 'gcx, 'tcx> {
         }
     }
 
-    fn fold_region(&mut self, r: ty::Region) -> ty::Region {
+    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
         match self.infcx.fully_resolve(&r) {
             Ok(r) => r,
             Err(e) => {
                 self.report_error(e);
-                ty::ReStatic
+                self.tcx.mk_region(ty::ReStatic)
             }
         }
     }