]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/writeback.rs
rustc: remove unnecessary ItemSubsts wrapper.
[rust.git] / src / librustc_typeck / check / writeback.rs
index f196aa82b1ef3ebc7a76da218e2a1de2b5b52e68..dcdfed6cbd888e98196a1aea8aaa4bce175baad8 100644 (file)
 use rustc::hir;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::infer::{InferCtxt};
-use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee};
+use rustc::ty::{self, Ty, TyCtxt, MethodCallee};
 use rustc::ty::adjustment;
 use rustc::ty::fold::{TypeFolder,TypeFoldable};
-use rustc::util::nodemap::{DefIdMap, DefIdSet};
+use rustc::util::nodemap::DefIdSet;
 use syntax::ast;
 use syntax_pos::Span;
 use std::mem;
@@ -43,7 +43,6 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body)
         wbcx.visit_liberated_fn_sigs();
         wbcx.visit_fru_field_types();
         wbcx.visit_anon_types();
-        wbcx.visit_type_nodes();
         wbcx.visit_cast_types();
         wbcx.visit_lints();
         wbcx.visit_free_region_map();
@@ -72,55 +71,17 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
 
     tables: ty::TypeckTables<'gcx>,
 
-    // Mapping from free regions of the function to the
-    // 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<&'gcx ty::Region>,
-
     body: &'gcx hir::Body,
 }
 
 impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, body: &'gcx hir::Body)
         -> WritebackCx<'cx, 'gcx, 'tcx> {
-        let mut wbcx = WritebackCx {
+        WritebackCx {
             fcx: fcx,
             tables: ty::TypeckTables::empty(),
-            free_to_bound_regions: DefIdMap(),
             body: body
-        };
-
-        // Only build the reverse mapping if `impl Trait` is used.
-        if fcx.anon_types.borrow().is_empty() {
-            return wbcx;
-        }
-
-        let gcx = fcx.tcx.global_tcx();
-        let free_substs = fcx.parameter_environment.free_substs;
-        for (i, k) in free_substs.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);
-                }
-            }
         }
-
-        wbcx
     }
 
     fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
@@ -145,7 +106,7 @@ fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
                 let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
 
                 if inner_ty.is_scalar() {
-                    self.fcx.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
+                    self.fcx.tables.borrow_mut().method_map.remove(&e.id);
                 }
             }
             hir::ExprBinary(ref op, ref lhs, ref rhs) |
@@ -157,7 +118,7 @@ fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr) {
                 let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty);
 
                 if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
-                    self.fcx.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
+                    self.fcx.tables.borrow_mut().method_map.remove(&e.id);
 
                     // weird but true: the by-ref binops put an
                     // adjustment on the lhs but not the rhs; the
@@ -203,7 +164,7 @@ fn visit_expr(&mut self, e: &'gcx hir::Expr) {
         self.fix_scalar_builtin_expr(e);
 
         self.visit_node_id(e.span, e.id);
-        self.visit_method_map_entry(e.span, MethodCall::expr(e.id));
+        self.visit_method_map_entry(e.span, e.id);
 
         if let hir::ExprClosure(_, _, body, _) = e.node {
             let body = self.fcx.tcx.hir.body(body);
@@ -275,7 +236,9 @@ fn visit_lints(&mut self) {
     }
 
     fn visit_free_region_map(&mut self) {
-        self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
+        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;
     }
 
     fn visit_anon_types(&mut self) {
@@ -284,22 +247,16 @@ fn visit_anon_types(&mut self) {
             let inside_ty = self.resolve(&concrete_ty, &node_id);
 
             // Convert the type from the function into a type valid outside
-            // the function, by replacing free regions with early-bound ones.
+            // 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 is valid everywhere.
+                    // 'static and early-bound regions are valid.
                     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, ..), ..
-                    }) if self.free_to_bound_regions.contains_key(&def_id) => {
-                        self.free_to_bound_regions[&def_id]
-                    }
+                    ty::ReEarlyBound(_) |
+                    ty::ReEmpty => r,
 
                     ty::ReFree(_) |
-                    ty::ReEarlyBound(_) |
                     ty::ReLateBound(..) |
                     ty::ReScope(_) |
                     ty::ReSkolemized(..) => {
@@ -307,7 +264,7 @@ fn visit_anon_types(&mut self) {
                         span_err!(self.tcx().sess, span, E0564,
                                   "only named lifetimes are allowed in `impl Trait`, \
                                    but `{}` was found in the type `{}`", r, inside_ty);
-                        gcx.mk_region(ty::ReStatic)
+                        gcx.types.re_static
                     }
 
                     ty::ReVar(_) |
@@ -338,14 +295,12 @@ fn visit_node_id(&mut self, span: Span, node_id: ast::NodeId) {
         debug!("Node {} has type {:?}", node_id, n_ty);
 
         // Resolve any substitutions
-        self.fcx.opt_node_ty_substs(node_id, |item_substs| {
-            let item_substs = self.resolve(item_substs, &span);
-            if !item_substs.is_noop() {
-                debug!("write_substs_to_tcx({}, {:?})", node_id, item_substs);
-                assert!(!item_substs.substs.needs_infer());
-                self.tables.item_substs.insert(node_id, item_substs);
-            }
-        });
+        if let Some(&substs) = self.fcx.tables.borrow().node_substs.get(&node_id) {
+            let substs = self.resolve(&substs, &span);
+            debug!("write_substs_to_tcx({}, {:?})", node_id, substs);
+            assert!(!substs.needs_infer());
+            self.tables.node_substs.insert(node_id, substs);
+        }
     }
 
     fn visit_adjustments(&mut self, span: Span, node_id: ast::NodeId) {
@@ -378,13 +333,16 @@ fn visit_adjustments(&mut self, span: Span, node_id: ast::NodeId) {
                     }
 
                     adjustment::Adjust::DerefRef { autoderefs, autoref, unsize } => {
-                        for autoderef in 0..autoderefs {
-                            let method_call = MethodCall::autoderef(node_id, autoderef as u32);
-                            self.visit_method_map_entry(span, method_call);
-                        }
-
                         adjustment::Adjust::DerefRef {
-                            autoderefs: autoderefs,
+                            autoderefs: autoderefs.iter().map(|overloaded| {
+                                overloaded.map(|method| {
+                                    MethodCallee {
+                                        def_id: method.def_id,
+                                        substs: self.resolve(&method.substs, &span),
+                                        sig: self.resolve(&method.sig, &span),
+                                    }
+                                })
+                            }).collect(),
                             autoref: self.resolve(&autoref, &span),
                             unsize: unsize,
                         }
@@ -402,27 +360,22 @@ fn visit_adjustments(&mut self, span: Span, node_id: ast::NodeId) {
 
     fn visit_method_map_entry(&mut self,
                               method_span: Span,
-                              method_call: MethodCall) {
+                              node_id: ast::NodeId) {
         // Resolve any method map entry
-        let new_method = match self.fcx.tables.borrow_mut().method_map.remove(&method_call) {
+        let new_method = match self.fcx.tables.borrow_mut().method_map.remove(&node_id) {
             Some(method) => {
-                debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
-                       method_call,
-                       method);
-                let new_method = MethodCallee {
+                Some(MethodCallee {
                     def_id: method.def_id,
-                    ty: self.resolve(&method.ty, &method_span),
                     substs: self.resolve(&method.substs, &method_span),
-                };
-
-                Some(new_method)
+                    sig: self.resolve(&method.sig, &method_span),
+                })
             }
             None => None
         };
 
         //NB(jroesch): We need to match twice to avoid a double borrow which would cause an ICE
         if let Some(method) = new_method {
-            self.tables.method_map.insert(method_call, method);
+            self.tables.method_map.insert(node_id, method);
         }
     }
 
@@ -440,13 +393,6 @@ fn visit_fru_field_types(&mut self) {
         }
     }
 
-    fn visit_type_nodes(&self) {
-        for (&id, ty) in self.fcx.ast_ty_to_ty_cache.borrow().iter() {
-            let ty = self.resolve(ty, &id);
-            self.fcx.tcx.ast_ty_to_ty_cache.borrow_mut().insert(id, ty);
-        }
-    }
-
     fn resolve<T>(&self, x: &T, span: &Locatable) -> T::Lifted
         where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
     {
@@ -522,11 +468,11 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
 
     // FIXME This should be carefully checked
     // We could use `self.report_error` but it doesn't accept a ty::Region, right now.
-    fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
+    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         match self.infcx.fully_resolve(&r) {
             Ok(r) => r,
             Err(_) => {
-                self.tcx.mk_region(ty::ReStatic)
+                self.tcx.types.re_static
             }
         }
     }