]> git.lizzy.rs Git - rust.git/commitdiff
address review comments
authorAriel Ben-Yehuda <ariel.byd@gmail.com>
Sat, 12 Nov 2016 21:20:02 +0000 (23:20 +0200)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Sat, 12 Nov 2016 21:20:25 +0000 (23:20 +0200)
src/librustc/infer/mod.rs
src/librustc/ty/subst.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/collect.rs

index 24716c4795134609dd1525848a1993c6804ee998..2d4b36ec187603fc7aa442d678477afd0903c498 100644 (file)
@@ -1150,10 +1150,6 @@ pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
         self.tcx.mk_var(self.next_ty_var_id(true))
     }
 
-    pub fn next_ty_vars(&self, n: usize) -> Vec<Ty<'tcx>> {
-        (0..n).map(|_i| self.next_ty_var()).collect()
-    }
-
     pub fn next_int_var_id(&self) -> IntVid {
         self.int_unification_table
             .borrow_mut()
index 76d512a20b26e20c6e0b650e9912066c378df52e..41fcb09fb2dc7ef2c3eb324e7679900b1122d0fd 100644 (file)
@@ -183,6 +183,22 @@ pub fn for_item<FR, FT>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         tcx.intern_substs(&substs)
     }
 
+    pub fn extend_to<FR, FT>(&self,
+                             tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                             def_id: DefId,
+                             mut mk_region: FR,
+                             mut mk_type: FT)
+                             -> &'tcx Substs<'tcx>
+    where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
+          FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx>
+    {
+        let defs = tcx.item_generics(def_id);
+        let mut result = Vec::with_capacity(defs.count());
+        result.extend(self[..].iter().cloned());
+        Substs::fill_single(&mut result, defs, &mut mk_region, &mut mk_type);
+        tcx.intern_substs(&result)
+    }
+
     fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
                          tcx: TyCtxt<'a, 'gcx, 'tcx>,
                          defs: &ty::Generics<'tcx>,
@@ -195,7 +211,15 @@ fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
             let parent_defs = tcx.item_generics(def_id);
             Substs::fill_item(substs, tcx, parent_defs, mk_region, mk_type);
         }
+        Substs::fill_single(substs, defs, mk_region, mk_type)
+    }
 
+    fn fill_single<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
+                           defs: &ty::Generics<'tcx>,
+                           mk_region: &mut FR,
+                           mk_type: &mut FT)
+    where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
+          FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> {
         // Handle Self first, before all regions.
         let mut types = defs.types.iter();
         if defs.parent.is_none() && defs.has_self {
@@ -275,15 +299,6 @@ pub fn rebase_onto(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
         tcx.mk_substs(target_substs.iter().chain(&self[defs.own_count()..]).cloned())
     }
 
-    pub fn extend_with_types(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                             types: &[Ty<'tcx>])
-                             -> &'tcx Substs<'tcx> {
-        tcx.mk_substs(
-            self[..].iter().cloned().chain(
-                types.iter().map(|a| Kind::from(*a)))
-        )
-    }
-
     pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics<'tcx>)
                        -> &'tcx Substs<'tcx> {
         tcx.mk_substs(self.iter().take(generics.count()).cloned())
index 3efbd6b30c2201d9179bd644c0f9c9d38e620ea5..75287d4064ae1df607a970ce8a9d1c12292e8df7 100644 (file)
 use super::{check_fn, Expectation, FnCtxt};
 
 use astconv::AstConv;
-use rustc::hir::def_id::DefId;
 use rustc::ty::{self, ToPolyTraitRef, Ty};
-use rustc::ty::subst::Substs;
-use rustc::util::common::MemoizationMap;
 use std::cmp;
 use syntax::abi::Abi;
 use rustc::hir;
 
-use syntax::parse::token;
-
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn check_expr_closure(&self,
                               expr: &hir::Expr,
@@ -45,48 +40,6 @@ pub fn check_expr_closure(&self,
         self.check_closure(expr, expected_kind, decl, body, expected_sig)
     }
 
-    fn declare_closure(&self, def_id: DefId) {
-        let tcx = self.tcx.global_tcx();
-
-        tcx.generics.memoize(def_id, || {
-            let node_id = tcx.map.as_local_node_id(def_id).unwrap();
-            let base_def_id = self.tcx.closure_base_def_id(def_id);
-            let base_generics = tcx.item_generics(base_def_id);
-
-            // provide junk type parameter defs - the only place that
-            // cares about anything but the length is instantiation,
-            // and we don't do that for closures.
-            let upvar_decls : Vec<_> = tcx.with_freevars(node_id, |fv| {
-                fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
-                    index: (base_generics.count() as u32) + (i as u32),
-                    name: token::intern("<upvar>"),
-                    def_id: def_id,
-                    default_def_id: base_def_id,
-                    default: None,
-                    object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
-                    pure_wrt_drop: false,
-                }).collect()
-            });
-
-            tcx.alloc_generics(ty::Generics {
-                parent: Some(base_def_id),
-                parent_regions: base_generics.parent_regions +
-                    (base_generics.regions.len() as u32),
-                parent_types: base_generics.parent_types +
-                    (base_generics.types.len() as u32),
-                regions: vec![],
-                types: upvar_decls,
-                has_self: false,
-            })
-        });
-
-        tcx.item_types.memoize(def_id, || tcx.mk_closure(def_id, Substs::for_item(
-            tcx, def_id,
-            |def, _| tcx.mk_region(def.to_early_bound_region()),
-            |def, _| tcx.mk_param_from_def(def)
-        )));
-    }
-
     fn check_closure(&self,
                      expr: &hir::Expr,
                      opt_kind: Option<ty::ClosureKind>,
@@ -99,8 +52,6 @@ fn check_closure(&self,
                expected_sig);
 
         let expr_def_id = self.tcx.map.local_def_id(expr.id);
-        self.declare_closure(expr_def_id);
-
         let mut fn_ty = AstConv::ty_of_closure(self,
                                                hir::Unsafety::Normal,
                                                decl,
@@ -110,18 +61,15 @@ fn check_closure(&self,
         // Create type variables (for now) to represent the transformed
         // types of upvars. These will be unified during the upvar
         // inference phase (`upvar.rs`).
-        let num_upvars = self.tcx.with_freevars(expr.id, |fv| fv.len());
-        let upvar_tys = self.next_ty_vars(num_upvars);
-
-        debug!("check_closure: expr.id={:?} upvar_tys={:?}",
-               expr.id,
-               upvar_tys);
-
-        let closure_type = self.tcx.mk_closure(
-            expr_def_id,
-            self.parameter_environment.free_substs.extend_with_types(self.tcx, &upvar_tys)
+        let closure_type = self.tcx.mk_closure(expr_def_id,
+            self.parameter_environment.free_substs.extend_to(self.tcx, expr_def_id,
+                |_, _| span_bug!(expr.span, "closure has region param"),
+                |_, _| self.infcx.next_ty_var()
+            )
         );
 
+        debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
+
         let fn_sig = self.tcx
             .liberate_late_bound_regions(self.tcx.region_maps.call_site_extent(expr.id, body.id),
                                          &fn_ty.sig);
index 968d5d73e7a8b892f07b10d93d224f2f3da189d9..816243b3eab47082312578736ac19e650bd6e908 100644 (file)
@@ -80,7 +80,7 @@
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 
 use syntax::{abi, ast, attr};
-use syntax::parse::token::keywords;
+use syntax::parse::token::{self, keywords};
 use syntax_pos::Span;
 
 use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
@@ -134,6 +134,13 @@ fn visit_item(&mut self, item: &hir::Item) {
         intravisit::walk_item(self, item);
     }
 
+    fn visit_expr(&mut self, expr: &hir::Expr) {
+        if let hir::ExprClosure(..) = expr.node {
+            convert_closure(self.ccx, expr.id);
+        }
+        intravisit::walk_expr(self, expr);
+    }
+
     fn visit_ty(&mut self, ty: &hir::Ty) {
         if let hir::TyImplTrait(..) = ty.node {
             let def_id = self.ccx.tcx.map.local_def_id(ty.id);
@@ -559,6 +566,40 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     ccx.tcx.predicates.borrow_mut().insert(def_id, struct_predicates.clone());
 }
 
+fn convert_closure<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                             node_id: ast::NodeId)
+{
+    let tcx = ccx.tcx;
+    let def_id = tcx.map.local_def_id(node_id);
+    let base_def_id = tcx.closure_base_def_id(def_id);
+    let base_generics = generics_of_def_id(ccx, base_def_id);
+
+    // provide junk type parameter defs - the only place that
+    // cares about anything but the length is instantiation,
+    // and we don't do that for closures.
+    let upvar_decls : Vec<_> = tcx.with_freevars(node_id, |fv| {
+        fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
+            index: (base_generics.count() as u32) + (i as u32),
+            name: token::intern("<upvar>"),
+            def_id: def_id,
+            default_def_id: base_def_id,
+            default: None,
+            object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
+            pure_wrt_drop: false,
+        }).collect()
+    });
+    tcx.generics.borrow_mut().insert(def_id, tcx.alloc_generics(ty::Generics {
+        parent: Some(base_def_id),
+        parent_regions: base_generics.parent_regions + (base_generics.regions.len() as u32),
+        parent_types: base_generics.parent_types + (base_generics.types.len() as u32),
+        regions: vec![],
+        types: upvar_decls,
+        has_self: base_generics.has_self,
+    }));
+
+    type_of_def_id(ccx, def_id);
+}
+
 fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                             container: AssociatedItemContainer,
                             id: ast::NodeId,
@@ -1504,6 +1545,13 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     }
                 }
             }
+            NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
+                ccx.tcx.mk_closure(def_id, Substs::for_item(
+                    ccx.tcx, def_id,
+                    |def, _| ccx.tcx.mk_region(def.to_early_bound_region()),
+                    |def, _| ccx.tcx.mk_param_from_def(def)
+                ))
+            }
             x => {
                 bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
             }