]> git.lizzy.rs Git - rust.git/commitdiff
introduce a Vec<Ty> to TyClosure for storing upvar types
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 16 Jul 2015 09:32:45 +0000 (05:32 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 24 Jul 2015 08:50:45 +0000 (04:50 -0400)
27 files changed:
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/fast_reject.rs
src/librustc/middle/implicator.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/project.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/ty_relate/mod.rs
src/librustc/middle/ty_walk.rs
src/librustc/util/ppaux.rs
src/librustc_lint/builtin.rs
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/attributes.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/declare.rs
src/librustc_trans/trans/meth.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/coherence/mod.rs

index ee9e199a6c52aa66157d06c4e82cbfa6e197b0ea..72e1525b506d13edc96722dfb35977812a4017d2 100644 (file)
@@ -564,8 +564,13 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
           assert_eq!(next(st), '[');
           let did = parse_def_(st, ClosureSource, conv);
           let substs = parse_substs_(st, conv);
+          let mut tys = vec![];
+          while peek(st) != '.' {
+              tys.push(parse_ty_(st, conv));
+          }
+          assert_eq!(next(st), '.');
           assert_eq!(next(st), ']');
-          return st.tcx.mk_closure(did, st.tcx.mk_substs(substs));
+          return st.tcx.mk_closure(did, st.tcx.mk_substs(substs), tys);
       }
       'P' => {
           assert_eq!(next(st), '[');
index e29c0f2b8370528e54e0f636fea238737898ebf1..77b5306c36e43262416c14ad94c2badfb6527e59 100644 (file)
@@ -143,9 +143,13 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::TyClosure(def, substs) => {
+        ty::TyClosure(def, substs, ref tys) => {
             mywrite!(w, "k[{}|", (cx.ds)(def));
             enc_substs(w, cx, substs);
+            for ty in tys {
+                enc_ty(w, cx, ty);
+            }
+            mywrite!(w, ".");
             mywrite!(w, "]");
         }
         ty::TyProjection(ref data) => {
index de7582a13716620ec4e9bd6baf141d1a473d1fdf..4635e406c4122320e9c5b65556d56a8659e36d46 100644 (file)
@@ -76,7 +76,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
                 Err(msg) => tcx.sess.fatal(&msg),
             }
         }
-        ty::TyClosure(def_id, _) => {
+        ty::TyClosure(def_id, _, _) => {
             Some(ClosureSimplifiedType(def_id))
         }
         ty::TyTuple(ref tys) => {
index 18059848481e6e557a6f80badb0fafd87788e019..b6a8037fe033ec45044757bef7a84fa00cf17c58 100644 (file)
@@ -96,7 +96,8 @@ fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
                 // No borrowed content reachable here.
             }
 
-            ty::TyClosure(def_id, substs) => {
+            ty::TyClosure(def_id, substs, _) => {
+                // TODO remove RegionSubClosure
                 let &(r_a, opt_ty) = self.stack.last().unwrap();
                 self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
             }
index 4345649de0c815d9ad8094d7f40b956473b078c5..fbb80fef9e6df2977c0aebec3eb082c105607005 100644 (file)
@@ -1493,7 +1493,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
         let fn_ty = self.ir.tcx.node_id_to_type(id);
         match fn_ty.sty {
-            ty::TyClosure(closure_def_id, substs) =>
+            ty::TyClosure(closure_def_id, substs, _) =>
                 self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
             _ => fn_ty.fn_ret()
         }
index bf47396bb9f656afdba931e1e18e178c52099744..4ba154b1046f30797f307056f2490f8b0976e36f 100644 (file)
@@ -584,7 +584,7 @@ pub fn cat_def(&self,
           def::DefUpvar(var_id, fn_node_id) => {
               let ty = try!(self.node_ty(fn_node_id));
               match ty.sty {
-                  ty::TyClosure(closure_id, _) => {
+                  ty::TyClosure(closure_id, _, _) => {
                       match self.typer.closure_kind(closure_id) {
                           Some(kind) => {
                               self.cat_upvar(id, span, var_id, fn_node_id, kind)
index 148b27adf64b241c475e3b84a6223767879c8a8e..ea2dee761593555d131b07d59faa0c76b108cfa1 100644 (file)
@@ -271,6 +271,7 @@ pub struct VtableImplData<'tcx, N> {
 pub struct VtableClosureData<'tcx, N> {
     pub closure_def_id: ast::DefId,
     pub substs: subst::Substs<'tcx>,
+    pub upvar_tys: Vec<Ty<'tcx>>,
     /// Nested obligations. This can be non-empty if the closure
     /// signature contains associated types.
     pub nested: Vec<N>
@@ -548,7 +549,8 @@ pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
             VtableClosure(c) => VtableClosure(VtableClosureData {
                 closure_def_id: c.closure_def_id,
                 substs: c.substs,
-                nested: c.nested.into_iter().map(f).collect()
+                nested: c.nested.into_iter().map(f).collect(),
+                upvar_tys: c.upvar_tys,
             })
         }
     }
index cd38e9d0d31bc529a6559d8b51cb23ae5142b4bf..b678aa405a89cfdc01947b01a3a9b4d01f479a95 100644 (file)
@@ -154,7 +154,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
     debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}",
            self_ty.sty);
     match self_ty.sty {
-        ty::TyClosure(closure_def_id, substs) => {
+        ty::TyClosure(closure_def_id, substs, _) => {
             let closure_typer = selcx.closure_typer();
             let closure_type = closure_typer.closure_type(closure_def_id, substs);
             let ty::Binder((_, ret_type)) =
index 81e59f57ae7de35a0996478f4532fe5a87c94e80..af41e205aec6672d9a0ff2f6732d69f8e820c42a 100644 (file)
@@ -201,7 +201,7 @@ enum SelectionCandidate<'tcx> {
 
     /// Implementation of a `Fn`-family trait by one of the
     /// anonymous types generated for a `||` expression.
-    ClosureCandidate(/* closure */ ast::DefId, Substs<'tcx>),
+    ClosureCandidate(/* closure */ ast::DefId, &'tcx Substs<'tcx>, &'tcx Vec<Ty<'tcx>>),
 
     /// Implementation of a `Fn`-family trait by one of the anonymous
     /// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -348,7 +348,7 @@ fn consider_unification_despite_ambiguity(&mut self, obligation: &TraitObligatio
         // lifetimes can appear inside the self-type.
         let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
         let (closure_def_id, substs) = match self_ty.sty {
-            ty::TyClosure(id, ref substs) => (id, substs.clone()),
+            ty::TyClosure(id, ref substs, _) => (id, substs.clone()),
             _ => { return; }
         };
         assert!(!substs.has_escaping_regions());
@@ -1142,8 +1142,8 @@ fn assemble_closure_candidates(&mut self,
         // touch bound regions, they just capture the in-scope
         // type/region parameters
         let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
-        let (closure_def_id, substs) = match self_ty.sty {
-            ty::TyClosure(id, substs) => (id, substs),
+        let (closure_def_id, substs, upvar_tys) = match self_ty.sty {
+            ty::TyClosure(id, substs, ref upvar_tys) => (id, substs, upvar_tys),
             ty::TyInfer(ty::TyVar(_)) => {
                 debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
                 candidates.ambiguous = true;
@@ -1161,8 +1161,7 @@ fn assemble_closure_candidates(&mut self,
             Some(closure_kind) => {
                 debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
                 if closure_kind.extends(kind) {
-                    candidates.vec.push(ClosureCandidate(closure_def_id,
-                                                         substs.clone()));
+                    candidates.vec.push(ClosureCandidate(closure_def_id, substs, upvar_tys));
                 }
             }
             None => {
@@ -1704,7 +1703,7 @@ fn builtin_bound(&mut self,
             // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
             ty::TyTuple(ref tys) => ok_if(tys.clone()),
 
-            ty::TyClosure(def_id, substs) => {
+            ty::TyClosure(def_id, substs, _) => {
                 // FIXME -- This case is tricky. In the case of by-ref
                 // closures particularly, we need the results of
                 // inference to decide how to reflect the type of each
@@ -1730,6 +1729,7 @@ fn builtin_bound(&mut self,
                     return ok_if(Vec::new());
                 }
 
+                // TODO
                 match self.infcx.closure_upvars(def_id, substs) {
                     Some(upvars) => ok_if(upvars.iter().map(|c| c.ty).collect()),
                     None => {
@@ -1865,9 +1865,10 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Option<Vec<Ty<'tcx>>> {
                 Some(tys.clone())
             }
 
-            ty::TyClosure(def_id, substs) => {
+            ty::TyClosure(def_id, substs, _) => {
                 assert_eq!(def_id.krate, ast::LOCAL_CRATE);
 
+                // TODO
                 match self.infcx.closure_upvars(def_id, substs) {
                     Some(upvars) => {
                         Some(upvars.iter().map(|c| c.ty).collect())
@@ -2014,9 +2015,10 @@ fn confirm_candidate(&mut self,
                 Ok(VtableImpl(vtable_impl))
             }
 
-            ClosureCandidate(closure_def_id, substs) => {
+            ClosureCandidate(closure_def_id, substs, upvar_tys) => {
                 let vtable_closure =
-                    try!(self.confirm_closure_candidate(obligation, closure_def_id, &substs));
+                    try!(self.confirm_closure_candidate(obligation, closure_def_id,
+                                                        &substs, upvar_tys));
                 Ok(VtableClosure(vtable_closure))
             }
 
@@ -2365,7 +2367,8 @@ fn confirm_fn_pointer_candidate(&mut self,
     fn confirm_closure_candidate(&mut self,
                                  obligation: &TraitObligation<'tcx>,
                                  closure_def_id: ast::DefId,
-                                 substs: &Substs<'tcx>)
+                                 substs: &Substs<'tcx>,
+                                 upvar_tys: &'tcx Vec<Ty<'tcx>>)
                                  -> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
                                            SelectionError<'tcx>>
     {
@@ -2391,6 +2394,7 @@ fn confirm_closure_candidate(&mut self,
         Ok(VtableClosureData {
             closure_def_id: closure_def_id,
             substs: substs.clone(),
+            upvar_tys: upvar_tys.clone(),
             nested: obligations
         })
     }
index 64e707f6264e6cae2bdf35ea569ea228e0fd8962..17d55737114fb73787862044e81dd477c853e2c4 100644 (file)
@@ -1767,7 +1767,7 @@ pub enum TypeVariants<'tcx> {
 
     /// The anonymous type of a closure. Used to represent the type of
     /// `|a| a`.
-    TyClosure(DefId, &'tcx Substs<'tcx>),
+    TyClosure(DefId, &'tcx Substs<'tcx>, Vec<Ty<'tcx>>),
 
     /// A tuple type.  For example, `(i32, bool)`.
     TyTuple(Vec<Ty<'tcx>>),
@@ -3214,10 +3214,11 @@ fn add_sty(&mut self, st: &TypeVariants) {
                 }
             }
 
-            &TyClosure(_, substs) => {
+            &TyClosure(_, substs, ref tys) => {
                 self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                 self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
                 self.add_substs(substs);
+                self.add_tys(tys);
             }
 
             &TyInfer(_) => {
@@ -3659,9 +3660,12 @@ pub fn mk_struct(&self, struct_id: ast::DefId,
         self.mk_ty(TyStruct(struct_id, substs))
     }
 
-    pub fn mk_closure(&self, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
+    pub fn mk_closure(&self,
+                      closure_id: ast::DefId,
+                      substs: &'tcx Substs<'tcx>,
+                      tys: Vec<Ty<'tcx>>)
                       -> Ty<'tcx> {
-        self.mk_ty(TyClosure(closure_id, substs))
+        self.mk_ty(TyClosure(closure_id, substs, tys))
     }
 
     pub fn mk_var(&self, v: TyVid) -> Ty<'tcx> {
@@ -3928,7 +3932,7 @@ pub fn ty_to_def_id(&self) -> Option<ast::DefId> {
             TyTrait(ref tt) => Some(tt.principal_def_id()),
             TyStruct(id, _) |
             TyEnum(id, _) |
-            TyClosure(id, _) => Some(id),
+            TyClosure(id, _, _) => Some(id),
             _ => None
         }
     }
@@ -4146,7 +4150,7 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
                     apply_lang_items(cx, did, res)
                 }
 
-                TyClosure(did, substs) => {
+                TyClosure(did, substs, _) => {
                     let param_env = cx.empty_parameter_environment();
                     let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false);
                     let upvars = infcx.closure_upvars(did, substs).unwrap();
@@ -6378,7 +6382,7 @@ macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
                     }
                     TyInfer(_) => unreachable!(),
                     TyError => byte!(21),
-                    TyClosure(d, _) => {
+                    TyClosure(d, _, _) => {
                         byte!(22);
                         did(state, d);
                     }
index eae2bb4966408c01fd6641528773af6eb3df81c7..87b5fcbd28e90e3fb6bf67480fe0748c8dc6a434 100644 (file)
@@ -450,6 +450,7 @@ fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableClosure
             closure_def_id: self.closure_def_id,
             substs: self.substs.fold_with(folder),
             nested: self.nested.fold_with(folder),
+            upvar_tys: self.upvar_tys.fold_with(folder),
         }
     }
 }
@@ -602,9 +603,10 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
             let substs = substs.fold_with(this);
             ty::TyStruct(did, this.tcx().mk_substs(substs))
         }
-        ty::TyClosure(did, ref substs) => {
+        ty::TyClosure(did, ref substs, ref tys) => {
             let s = substs.fold_with(this);
-            ty::TyClosure(did, this.tcx().mk_substs(s))
+            let tys = tys.fold_with(this);
+            ty::TyClosure(did, this.tcx().mk_substs(s), tys)
         }
         ty::TyProjection(ref data) => {
             ty::TyProjection(data.fold_with(this))
index 0159801d5beea7918ad7f35d690a9481422eeca6..33cddc978d9bb46d5905100630d8f7b2e842e5eb 100644 (file)
@@ -48,6 +48,12 @@ fn relate<T:Relate<'a,'tcx>>(&mut self, a: &T, b: &T) -> RelateResult<'tcx, T> {
         Relate::relate(self, a, b)
     }
 
+    /// Relete elements of two slices pairwise.
+    fn relate_zip<T:Relate<'a,'tcx>>(&mut self, a: &[T], b: &[T]) -> RelateResult<'tcx, Vec<T>> {
+        assert_eq!(a.len(), b.len());
+        a.iter().zip(b).map(|(a, b)| self.relate(a, b)).collect()
+    }
+
     /// Switch variance for the purpose of relating `a` and `b`.
     fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
                                                variance: ty::Variance,
@@ -500,15 +506,16 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R,
             Ok(tcx.mk_struct(a_id, tcx.mk_substs(substs)))
         }
 
-        (&ty::TyClosure(a_id, a_substs),
-         &ty::TyClosure(b_id, b_substs))
+        (&ty::TyClosure(a_id, a_substs, ref a_tys),
+         &ty::TyClosure(b_id, b_substs, ref b_tys))
             if a_id == b_id =>
         {
             // All TyClosure types with the same id represent
             // the (anonymous) type of the same closure expression. So
             // all of their regions should be equated.
             let substs = try!(relate_substs(relation, None, a_substs, b_substs));
-            Ok(tcx.mk_closure(a_id, tcx.mk_substs(substs)))
+            let tys = try!(relation.relate_zip(a_tys, b_tys));
+            Ok(tcx.mk_closure(a_id, tcx.mk_substs(substs), tys))
         }
 
         (&ty::TyBox(a_inner), &ty::TyBox(b_inner)) =>
index 3e9a402f9499c15666a731ff5ab58ea7069f8f6e..97f3bd1297197e4a67d3264b1fb650fe2c3fc710 100644 (file)
@@ -88,10 +88,13 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
             }).collect::<Vec<_>>());
         }
         ty::TyEnum(_, ref substs) |
-        ty::TyStruct(_, ref substs) |
-        ty::TyClosure(_, ref substs) => {
+        ty::TyStruct(_, ref substs) => {
             push_reversed(stack, substs.types.as_slice());
         }
+        ty::TyClosure(_, ref substs, ref tys) => {
+            push_reversed(stack, substs.types.as_slice());
+            push_reversed(stack, tys);
+        }
         ty::TyTuple(ref ts) => {
             push_reversed(stack, ts);
         }
index b0510a76385bee3379975c2af0fe75d28d448054..d6696e392bcff4c726188b27e7c988a44195e29d 100644 (file)
@@ -662,7 +662,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             TyTrait(ref data) => write!(f, "{}", data),
             ty::TyProjection(ref data) => write!(f, "{}", data),
             TyStr => write!(f, "str"),
-            TyClosure(ref did, substs) => ty::tls::with(|tcx| {
+            TyClosure(ref did, substs, _) => ty::tls::with(|tcx| {
                 try!(write!(f, "[closure"));
                 let closure_tys = &tcx.tables.borrow().closure_tys;
                 try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| {
index 6289d50588104bbffa0baf63dd9379b38862e535..331bcaa8da89b8dab27b10fa7d7a0bf2bb5b6592 100644 (file)
@@ -2529,7 +2529,7 @@ fn check_crate(&mut self, ctx: &Context, _: &ast::Crate) {
             match dtor_self_type.sty {
                 ty::TyEnum(self_type_did, _) |
                 ty::TyStruct(self_type_did, _) |
-                ty::TyClosure(self_type_did, _) => {
+                ty::TyClosure(self_type_did, _, _) => {
                     let hints = ctx.tcx.lookup_repr_hints(self_type_did);
                     if hints.iter().any(|attr| *attr == attr::ReprExtern) &&
                         ctx.tcx.ty_dtor(self_type_did).has_drop_flag() {
index 7b2bdee50fe7880321d9abb2a6fafc4fd82a141d..985ef2d7b14fcf979562039578fd4478661ec58a 100644 (file)
@@ -221,9 +221,9 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor))
         }
-        ty::TyClosure(def_id, substs) => {
+        ty::TyClosure(def_id, substs, _) => {
             let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
-            let upvars = infcx.closure_upvars(def_id, substs).unwrap();
+            let upvars = infcx.closure_upvars(def_id, substs).unwrap(); // TODO
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
             Univariant(mk_struct(cx, &upvar_types[..], false, t), 0)
         }
@@ -441,9 +441,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
 
         // Perhaps one of the upvars of this struct is non-zero
         // Let's recurse and find out!
-        ty::TyClosure(def_id, substs) => {
+        ty::TyClosure(def_id, substs, _) => {
             let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
-            let upvars = infcx.closure_upvars(def_id, substs).unwrap();
+            let upvars = infcx.closure_upvars(def_id, substs).unwrap(); // TODO
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
 
             for (j, &ty) in upvar_types.iter().enumerate() {
index f8daefa87a5ff51aa10130df94ed202b32034c70..03e7d9e3aa28596dc06e89a9ec2a5683cfc6b727 100644 (file)
@@ -145,7 +145,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
     let function_type;
     let (fn_sig, abi, env_ty) = match fn_type.sty {
         ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
-        ty::TyClosure(closure_did, substs) => {
+        ty::TyClosure(closure_did, substs, _) => {
             let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
             function_type = infcx.closure_type(closure_did, substs);
             let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
index 258051357b1057b21ab41be45deba19a7f00ba11..678b5063816c70531148e13a9c71610e4503bef2 100644 (file)
@@ -470,7 +470,7 @@ fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
               }
           })
       }
-      ty::TyClosure(def_id, substs) => {
+      ty::TyClosure(def_id, substs, _) => { // TODO
           let repr = adt::represent_type(cx.ccx(), t);
           let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
           let upvars = infcx.closure_upvars(def_id, substs).unwrap();
index f00029ec2ff932a8d762423017949e92f963ee36..defa0a1d898bf60e5c52d3d0aade1233e9f9fab2 100644 (file)
@@ -12,6 +12,7 @@
 use back::link::{self, mangle_internal_name_by_path_and_seq};
 use llvm::{ValueRef, get_params};
 use middle::infer;
+use middle::ty::Ty;
 use trans::adt;
 use trans::attributes;
 use trans::base::*;
@@ -142,7 +143,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
     // duplicate declarations
     let function_type = erase_regions(ccx.tcx(), &function_type);
     let params = match function_type.sty {
-        ty::TyClosure(_, substs) => &substs.types,
+        ty::TyClosure(_, substs, _) => &substs.types,
         _ => unreachable!()
     };
     let mono_id = MonoId {
@@ -269,6 +270,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
 pub fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
                                       closure_def_id: ast::DefId,
                                       substs: Substs<'tcx>,
+                                      upvar_tys: Vec<Ty<'tcx>>,
                                       node: ExprOrMethodCall,
                                       param_substs: &'tcx Substs<'tcx>,
                                       trait_closure_kind: ty::ClosureKind)
@@ -288,6 +290,7 @@ pub fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
     trans_closure_adapter_shim(ccx,
                                closure_def_id,
                                substs,
+                               upvar_tys,
                                closure_kind,
                                trait_closure_kind,
                                llfn)
@@ -297,6 +300,7 @@ fn trans_closure_adapter_shim<'a, 'tcx>(
     ccx: &'a CrateContext<'a, 'tcx>,
     closure_def_id: ast::DefId,
     substs: Substs<'tcx>,
+    upvar_tys: Vec<Ty<'tcx>>,
     llfn_closure_kind: ty::ClosureKind,
     trait_closure_kind: ty::ClosureKind,
     llfn: ValueRef)
@@ -335,7 +339,7 @@ fn trans_closure_adapter_shim<'a, 'tcx>(
             //     fn call_once(mut self, ...) { call_mut(&mut self, ...) }
             //
             // These are both the same at trans time.
-            trans_fn_once_adapter_shim(ccx, closure_def_id, substs, llfn)
+            trans_fn_once_adapter_shim(ccx, closure_def_id, substs, upvar_tys, llfn)
         }
         _ => {
             tcx.sess.bug(&format!("trans_closure_adapter_shim: cannot convert {:?} to {:?}",
@@ -349,6 +353,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
     ccx: &'a CrateContext<'a, 'tcx>,
     closure_def_id: ast::DefId,
     substs: Substs<'tcx>,
+    upvar_tys: Vec<Ty<'tcx>>,
     llreffn: ValueRef)
     -> ValueRef
 {
@@ -363,7 +368,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
     // Find a version of the closure type. Substitute static for the
     // region since it doesn't really matter.
     let substs = tcx.mk_substs(substs);
-    let closure_ty = tcx.mk_closure(closure_def_id, substs);
+    let closure_ty = tcx.mk_closure(closure_def_id, substs, upvar_tys);
     let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty);
 
     // Make a version with the type of by-ref closure.
index 5f17197a4b9a746fed0458a0ee19c180067966c3..d0c6c0ab308c4bec0b52411366d6ffb721f6e4b0 100644 (file)
@@ -287,7 +287,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
                     }
                 }
             },
-            ty::TyClosure(def_id, substs) => {
+            ty::TyClosure(def_id, substs, _) => {
                 let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
                 let closure_ty = infcx.closure_type(def_id, substs);
                 self.get_unique_type_id_of_closure_type(cx,
@@ -811,7 +811,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
 
         }
-        ty::TyClosure(def_id, substs) => {
+        ty::TyClosure(def_id, substs, _) => {
             let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
             let upvars = infcx.closure_upvars(def_id, substs).unwrap();
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
index c802de91e38b3da452a8b09f64de196bad07fc1c..a641302e53fab835c6dc31d44dbf19c069d6c594 100644 (file)
@@ -116,7 +116,7 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
         ty::TyBareFn(_, ref f) => {
             (&f.sig, f.abi, None)
         }
-        ty::TyClosure(closure_did, substs) => {
+        ty::TyClosure(closure_did, substs, _) => {
             let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
             function_type = infcx.closure_type(closure_did, substs);
             let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);
index 8901361b27976396cfada7ff1c19b21ed4914634..cf2a226db41eb45426a4d910683b07e108b3f7ec 100644 (file)
@@ -341,6 +341,7 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let llfn = closure::trans_closure_method(bcx.ccx(),
                                                      vtable_closure.closure_def_id,
                                                      vtable_closure.substs,
+                                                     vtable_closure.upvar_tys,
                                                      MethodCallKey(method_call),
                                                      bcx.fcx.param_substs,
                                                      trait_closure_kind);
@@ -641,11 +642,13 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 traits::VtableClosureData {
                     closure_def_id,
                     substs,
+                    upvar_tys,
                     nested: _ }) => {
                 let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                 let llfn = closure::trans_closure_method(ccx,
                                                          closure_def_id,
                                                          substs,
+                                                         upvar_tys,
                                                          ExprId(0),
                                                          param_substs,
                                                          trait_closure_kind);
index f32a4fe43d6964da162e8a9835aa47350c1b9ac8..955a301340519b84c4600732b49a42a5a990f731 100644 (file)
@@ -131,7 +131,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             return Some(CallStep::Builtin);
         }
 
-        ty::TyClosure(def_id, substs) => {
+        ty::TyClosure(def_id, substs, _) => {
             assert_eq!(def_id.krate, ast::LOCAL_CRATE);
 
             // Check whether this is a call to a closure where we
index 6d1e9dfacf2816e55e6035e818bb03a8e58acfc8..71e51292a7846f145b733dd82e8606a34f43ece1 100644 (file)
@@ -60,8 +60,18 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         abi::RustCall,
         expected_sig);
 
-    let closure_type = fcx.ccx.tcx.mk_closure(expr_def_id,
-        fcx.ccx.tcx.mk_substs(fcx.inh.infcx.parameter_environment.free_substs.clone()));
+    let freevar_tys =
+        fcx.tcx().with_freevars(expr.id, |fv| {
+            fv.iter()
+              .map(|_| fcx.tcx().types.bool) // TODO
+              .collect()
+        });
+
+    let closure_type =
+        fcx.ccx.tcx.mk_closure(
+            expr_def_id,
+            fcx.ccx.tcx.mk_substs(fcx.inh.infcx.parameter_environment.free_substs.clone()),
+            freevar_tys);
 
     fcx.write_ty(expr.id, closure_type);
 
index 7d911cf8b03bc3c4d217d5254e1a58e6761ae3fd..f37177684d55219b35424c919cc93844d75c6291 100644 (file)
@@ -42,7 +42,7 @@ pub fn check_drop_impl(tcx: &ty::ctxt, drop_impl_did: ast::DefId) -> Result<(),
     match dtor_self_type.sty {
         ty::TyEnum(self_type_did, self_to_impl_substs) |
         ty::TyStruct(self_type_did, self_to_impl_substs) |
-        ty::TyClosure(self_type_did, self_to_impl_substs) => {
+        ty::TyClosure(self_type_did, self_to_impl_substs, _) => {
             try!(ensure_drop_params_and_item_params_correspond(tcx,
                                                                drop_impl_did,
                                                                dtor_generics,
index a960123efc6b8172045ea9fefa1c0fe7a4ed8e3e..8b9871428c4d12d78f06aa917d7da38bf5d1d174 100644 (file)
@@ -288,7 +288,7 @@ fn assemble_probe(&mut self, self_ty: Ty<'tcx>) {
             }
             ty::TyEnum(did, _) |
             ty::TyStruct(did, _) |
-            ty::TyClosure(did, _) => {
+            ty::TyClosure(did, _, _) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
             }
             ty::TyBox(_) => {
@@ -711,7 +711,7 @@ fn assemble_closure_candidates(&mut self,
         let steps = self.steps.clone();
         for step in steps.iter() {
             let closure_def_id = match step.self_ty.sty {
-                ty::TyClosure(a, _) => a,
+                ty::TyClosure(a, _, _) => a,
                 _ => continue,
             };
 
index 2b800bd9a441f738c3ecdbaf93a5d059b4eede9e..0878ca1c29562c66ed9342d3c6fa820776543deb 100644 (file)
@@ -312,7 +312,7 @@ fn populate_destructor_table(&self) {
             match self_type.ty.sty {
                 ty::TyEnum(type_def_id, _) |
                 ty::TyStruct(type_def_id, _) |
-                ty::TyClosure(type_def_id, _) => {
+                ty::TyClosure(type_def_id, _, _) => {
                     tcx.destructor_for_type
                        .borrow_mut()
                        .insert(type_def_id, method_def_id.def_id());