Skip to content

Commit 69d62e0

Browse files
committed
introduce a Vec<Ty> to TyClosure for storing upvar types
1 parent c9ef1a5 commit 69d62e0

File tree

27 files changed

+104
-54
lines changed

27 files changed

+104
-54
lines changed

src/librustc/metadata/tydecode.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,13 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
564564
assert_eq!(next(st), '[');
565565
let did = parse_def_(st, ClosureSource, conv);
566566
let substs = parse_substs_(st, conv);
567+
let mut tys = vec![];
568+
while peek(st) != '.' {
569+
tys.push(parse_ty_(st, conv));
570+
}
571+
assert_eq!(next(st), '.');
567572
assert_eq!(next(st), ']');
568-
return st.tcx.mk_closure(did, st.tcx.mk_substs(substs));
573+
return st.tcx.mk_closure(did, st.tcx.mk_substs(substs), tys);
569574
}
570575
'P' => {
571576
assert_eq!(next(st), '[');

src/librustc/metadata/tyencode.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,13 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
143143
enc_substs(w, cx, substs);
144144
mywrite!(w, "]");
145145
}
146-
ty::TyClosure(def, substs) => {
146+
ty::TyClosure(def, substs, ref tys) => {
147147
mywrite!(w, "k[{}|", (cx.ds)(def));
148148
enc_substs(w, cx, substs);
149+
for ty in tys {
150+
enc_ty(w, cx, ty);
151+
}
152+
mywrite!(w, ".");
149153
mywrite!(w, "]");
150154
}
151155
ty::TyProjection(ref data) => {

src/librustc/middle/fast_reject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
7676
Err(msg) => tcx.sess.fatal(&msg),
7777
}
7878
}
79-
ty::TyClosure(def_id, _) => {
79+
ty::TyClosure(def_id, _, _) => {
8080
Some(ClosureSimplifiedType(def_id))
8181
}
8282
ty::TyTuple(ref tys) => {

src/librustc/middle/implicator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
9696
// No borrowed content reachable here.
9797
}
9898

99-
ty::TyClosure(def_id, substs) => {
99+
ty::TyClosure(def_id, substs, _) => {
100+
// TODO remove RegionSubClosure
100101
let &(r_a, opt_ty) = self.stack.last().unwrap();
101102
self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
102103
}

src/librustc/middle/liveness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
14931493
fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
14941494
let fn_ty = self.ir.tcx.node_id_to_type(id);
14951495
match fn_ty.sty {
1496-
ty::TyClosure(closure_def_id, substs) =>
1496+
ty::TyClosure(closure_def_id, substs, _) =>
14971497
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
14981498
_ => fn_ty.fn_ret()
14991499
}

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
584584
def::DefUpvar(var_id, fn_node_id) => {
585585
let ty = try!(self.node_ty(fn_node_id));
586586
match ty.sty {
587-
ty::TyClosure(closure_id, _) => {
587+
ty::TyClosure(closure_id, _, _) => {
588588
match self.typer.closure_kind(closure_id) {
589589
Some(kind) => {
590590
self.cat_upvar(id, span, var_id, fn_node_id, kind)

src/librustc/middle/traits/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ pub struct VtableImplData<'tcx, N> {
271271
pub struct VtableClosureData<'tcx, N> {
272272
pub closure_def_id: ast::DefId,
273273
pub substs: subst::Substs<'tcx>,
274+
pub upvar_tys: Vec<Ty<'tcx>>,
274275
/// Nested obligations. This can be non-empty if the closure
275276
/// signature contains associated types.
276277
pub nested: Vec<N>
@@ -548,7 +549,8 @@ impl<'tcx, N> Vtable<'tcx, N> {
548549
VtableClosure(c) => VtableClosure(VtableClosureData {
549550
closure_def_id: c.closure_def_id,
550551
substs: c.substs,
551-
nested: c.nested.into_iter().map(f).collect()
552+
nested: c.nested.into_iter().map(f).collect(),
553+
upvar_tys: c.upvar_tys,
552554
})
553555
}
554556
}

src/librustc/middle/traits/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
154154
debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}",
155155
self_ty.sty);
156156
match self_ty.sty {
157-
ty::TyClosure(closure_def_id, substs) => {
157+
ty::TyClosure(closure_def_id, substs, _) => {
158158
let closure_typer = selcx.closure_typer();
159159
let closure_type = closure_typer.closure_type(closure_def_id, substs);
160160
let ty::Binder((_, ret_type)) =

src/librustc/middle/traits/select.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ enum SelectionCandidate<'tcx> {
201201

202202
/// Implementation of a `Fn`-family trait by one of the
203203
/// anonymous types generated for a `||` expression.
204-
ClosureCandidate(/* closure */ ast::DefId, Substs<'tcx>),
204+
ClosureCandidate(/* closure */ ast::DefId, &'tcx Substs<'tcx>, &'tcx Vec<Ty<'tcx>>),
205205

206206
/// Implementation of a `Fn`-family trait by one of the anonymous
207207
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -348,7 +348,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
348348
// lifetimes can appear inside the self-type.
349349
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
350350
let (closure_def_id, substs) = match self_ty.sty {
351-
ty::TyClosure(id, ref substs) => (id, substs.clone()),
351+
ty::TyClosure(id, ref substs, _) => (id, substs.clone()),
352352
_ => { return; }
353353
};
354354
assert!(!substs.has_escaping_regions());
@@ -1142,8 +1142,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11421142
// touch bound regions, they just capture the in-scope
11431143
// type/region parameters
11441144
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
1145-
let (closure_def_id, substs) = match self_ty.sty {
1146-
ty::TyClosure(id, substs) => (id, substs),
1145+
let (closure_def_id, substs, upvar_tys) = match self_ty.sty {
1146+
ty::TyClosure(id, substs, ref upvar_tys) => (id, substs, upvar_tys),
11471147
ty::TyInfer(ty::TyVar(_)) => {
11481148
debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
11491149
candidates.ambiguous = true;
@@ -1161,8 +1161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11611161
Some(closure_kind) => {
11621162
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
11631163
if closure_kind.extends(kind) {
1164-
candidates.vec.push(ClosureCandidate(closure_def_id,
1165-
substs.clone()));
1164+
candidates.vec.push(ClosureCandidate(closure_def_id, substs, upvar_tys));
11661165
}
11671166
}
11681167
None => {
@@ -1704,7 +1703,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17041703
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
17051704
ty::TyTuple(ref tys) => ok_if(tys.clone()),
17061705

1707-
ty::TyClosure(def_id, substs) => {
1706+
ty::TyClosure(def_id, substs, _) => {
17081707
// FIXME -- This case is tricky. In the case of by-ref
17091708
// closures particularly, we need the results of
17101709
// inference to decide how to reflect the type of each
@@ -1730,6 +1729,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17301729
return ok_if(Vec::new());
17311730
}
17321731

1732+
// TODO
17331733
match self.infcx.closure_upvars(def_id, substs) {
17341734
Some(upvars) => ok_if(upvars.iter().map(|c| c.ty).collect()),
17351735
None => {
@@ -1865,9 +1865,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18651865
Some(tys.clone())
18661866
}
18671867

1868-
ty::TyClosure(def_id, substs) => {
1868+
ty::TyClosure(def_id, substs, _) => {
18691869
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
18701870

1871+
// TODO
18711872
match self.infcx.closure_upvars(def_id, substs) {
18721873
Some(upvars) => {
18731874
Some(upvars.iter().map(|c| c.ty).collect())
@@ -2014,9 +2015,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20142015
Ok(VtableImpl(vtable_impl))
20152016
}
20162017

2017-
ClosureCandidate(closure_def_id, substs) => {
2018+
ClosureCandidate(closure_def_id, substs, upvar_tys) => {
20182019
let vtable_closure =
2019-
try!(self.confirm_closure_candidate(obligation, closure_def_id, &substs));
2020+
try!(self.confirm_closure_candidate(obligation, closure_def_id,
2021+
&substs, upvar_tys));
20202022
Ok(VtableClosure(vtable_closure))
20212023
}
20222024

@@ -2365,7 +2367,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23652367
fn confirm_closure_candidate(&mut self,
23662368
obligation: &TraitObligation<'tcx>,
23672369
closure_def_id: ast::DefId,
2368-
substs: &Substs<'tcx>)
2370+
substs: &Substs<'tcx>,
2371+
upvar_tys: &'tcx Vec<Ty<'tcx>>)
23692372
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
23702373
SelectionError<'tcx>>
23712374
{
@@ -2391,6 +2394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23912394
Ok(VtableClosureData {
23922395
closure_def_id: closure_def_id,
23932396
substs: substs.clone(),
2397+
upvar_tys: upvar_tys.clone(),
23942398
nested: obligations
23952399
})
23962400
}

src/librustc/middle/ty.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,7 @@ pub enum TypeVariants<'tcx> {
17671767

17681768
/// The anonymous type of a closure. Used to represent the type of
17691769
/// `|a| a`.
1770-
TyClosure(DefId, &'tcx Substs<'tcx>),
1770+
TyClosure(DefId, &'tcx Substs<'tcx>, Vec<Ty<'tcx>>),
17711771

17721772
/// A tuple type. For example, `(i32, bool)`.
17731773
TyTuple(Vec<Ty<'tcx>>),
@@ -3214,10 +3214,11 @@ impl FlagComputation {
32143214
}
32153215
}
32163216

3217-
&TyClosure(_, substs) => {
3217+
&TyClosure(_, substs, ref tys) => {
32183218
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
32193219
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
32203220
self.add_substs(substs);
3221+
self.add_tys(tys);
32213222
}
32223223

32233224
&TyInfer(_) => {
@@ -3659,9 +3660,12 @@ impl<'tcx> ctxt<'tcx> {
36593660
self.mk_ty(TyStruct(struct_id, substs))
36603661
}
36613662

3662-
pub fn mk_closure(&self, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
3663+
pub fn mk_closure(&self,
3664+
closure_id: ast::DefId,
3665+
substs: &'tcx Substs<'tcx>,
3666+
tys: Vec<Ty<'tcx>>)
36633667
-> Ty<'tcx> {
3664-
self.mk_ty(TyClosure(closure_id, substs))
3668+
self.mk_ty(TyClosure(closure_id, substs, tys))
36653669
}
36663670

36673671
pub fn mk_var(&self, v: TyVid) -> Ty<'tcx> {
@@ -3928,7 +3932,7 @@ impl<'tcx> TyS<'tcx> {
39283932
TyTrait(ref tt) => Some(tt.principal_def_id()),
39293933
TyStruct(id, _) |
39303934
TyEnum(id, _) |
3931-
TyClosure(id, _) => Some(id),
3935+
TyClosure(id, _, _) => Some(id),
39323936
_ => None
39333937
}
39343938
}
@@ -4146,7 +4150,7 @@ impl<'tcx> TyS<'tcx> {
41464150
apply_lang_items(cx, did, res)
41474151
}
41484152

4149-
TyClosure(did, substs) => {
4153+
TyClosure(did, substs, _) => {
41504154
let param_env = cx.empty_parameter_environment();
41514155
let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false);
41524156
let upvars = infcx.closure_upvars(did, substs).unwrap();
@@ -6378,7 +6382,7 @@ impl<'tcx> ctxt<'tcx> {
63786382
}
63796383
TyInfer(_) => unreachable!(),
63806384
TyError => byte!(21),
6381-
TyClosure(d, _) => {
6385+
TyClosure(d, _, _) => {
63826386
byte!(22);
63836387
did(state, d);
63846388
}

src/librustc/middle/ty_fold.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureDa
450450
closure_def_id: self.closure_def_id,
451451
substs: self.substs.fold_with(folder),
452452
nested: self.nested.fold_with(folder),
453+
upvar_tys: self.upvar_tys.fold_with(folder),
453454
}
454455
}
455456
}
@@ -602,9 +603,10 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
602603
let substs = substs.fold_with(this);
603604
ty::TyStruct(did, this.tcx().mk_substs(substs))
604605
}
605-
ty::TyClosure(did, ref substs) => {
606+
ty::TyClosure(did, ref substs, ref tys) => {
606607
let s = substs.fold_with(this);
607-
ty::TyClosure(did, this.tcx().mk_substs(s))
608+
let tys = tys.fold_with(this);
609+
ty::TyClosure(did, this.tcx().mk_substs(s), tys)
608610
}
609611
ty::TyProjection(ref data) => {
610612
ty::TyProjection(data.fold_with(this))

src/librustc/middle/ty_relate/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ pub trait TypeRelation<'a,'tcx> : Sized {
4848
Relate::relate(self, a, b)
4949
}
5050

51+
/// Relete elements of two slices pairwise.
52+
fn relate_zip<T:Relate<'a,'tcx>>(&mut self, a: &[T], b: &[T]) -> RelateResult<'tcx, Vec<T>> {
53+
assert_eq!(a.len(), b.len());
54+
a.iter().zip(b).map(|(a, b)| self.relate(a, b)).collect()
55+
}
56+
5157
/// Switch variance for the purpose of relating `a` and `b`.
5258
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
5359
variance: ty::Variance,
@@ -500,15 +506,16 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R,
500506
Ok(tcx.mk_struct(a_id, tcx.mk_substs(substs)))
501507
}
502508

503-
(&ty::TyClosure(a_id, a_substs),
504-
&ty::TyClosure(b_id, b_substs))
509+
(&ty::TyClosure(a_id, a_substs, ref a_tys),
510+
&ty::TyClosure(b_id, b_substs, ref b_tys))
505511
if a_id == b_id =>
506512
{
507513
// All TyClosure types with the same id represent
508514
// the (anonymous) type of the same closure expression. So
509515
// all of their regions should be equated.
510516
let substs = try!(relate_substs(relation, None, a_substs, b_substs));
511-
Ok(tcx.mk_closure(a_id, tcx.mk_substs(substs)))
517+
let tys = try!(relation.relate_zip(a_tys, b_tys));
518+
Ok(tcx.mk_closure(a_id, tcx.mk_substs(substs), tys))
512519
}
513520

514521
(&ty::TyBox(a_inner), &ty::TyBox(b_inner)) =>

src/librustc/middle/ty_walk.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,13 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
8888
}).collect::<Vec<_>>());
8989
}
9090
ty::TyEnum(_, ref substs) |
91-
ty::TyStruct(_, ref substs) |
92-
ty::TyClosure(_, ref substs) => {
91+
ty::TyStruct(_, ref substs) => {
9392
push_reversed(stack, substs.types.as_slice());
9493
}
94+
ty::TyClosure(_, ref substs, ref tys) => {
95+
push_reversed(stack, substs.types.as_slice());
96+
push_reversed(stack, tys);
97+
}
9598
ty::TyTuple(ref ts) => {
9699
push_reversed(stack, ts);
97100
}

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
662662
TyTrait(ref data) => write!(f, "{}", data),
663663
ty::TyProjection(ref data) => write!(f, "{}", data),
664664
TyStr => write!(f, "str"),
665-
TyClosure(ref did, substs) => ty::tls::with(|tcx| {
665+
TyClosure(ref did, substs, _) => ty::tls::with(|tcx| {
666666
try!(write!(f, "[closure"));
667667
let closure_tys = &tcx.tables.borrow().closure_tys;
668668
try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| {

src/librustc_lint/builtin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2529,7 +2529,7 @@ impl LintPass for DropWithReprExtern {
25292529
match dtor_self_type.sty {
25302530
ty::TyEnum(self_type_did, _) |
25312531
ty::TyStruct(self_type_did, _) |
2532-
ty::TyClosure(self_type_did, _) => {
2532+
ty::TyClosure(self_type_did, _, _) => {
25332533
let hints = ctx.tcx.lookup_repr_hints(self_type_did);
25342534
if hints.iter().any(|attr| *attr == attr::ReprExtern) &&
25352535
ctx.tcx.ty_dtor(self_type_did).has_drop_flag() {

src/librustc_trans/trans/adt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
221221

222222
Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor))
223223
}
224-
ty::TyClosure(def_id, substs) => {
224+
ty::TyClosure(def_id, substs, _) => {
225225
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
226-
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
226+
let upvars = infcx.closure_upvars(def_id, substs).unwrap(); // TODO
227227
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
228228
Univariant(mk_struct(cx, &upvar_types[..], false, t), 0)
229229
}
@@ -441,9 +441,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
441441

442442
// Perhaps one of the upvars of this struct is non-zero
443443
// Let's recurse and find out!
444-
ty::TyClosure(def_id, substs) => {
444+
ty::TyClosure(def_id, substs, _) => {
445445
let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
446-
let upvars = infcx.closure_upvars(def_id, substs).unwrap();
446+
let upvars = infcx.closure_upvars(def_id, substs).unwrap(); // TODO
447447
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
448448

449449
for (j, &ty) in upvar_types.iter().enumerate() {

src/librustc_trans/trans/attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
145145
let function_type;
146146
let (fn_sig, abi, env_ty) = match fn_type.sty {
147147
ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None),
148-
ty::TyClosure(closure_did, substs) => {
148+
ty::TyClosure(closure_did, substs, _) => {
149149
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
150150
function_type = infcx.closure_type(closure_did, substs);
151151
let self_type = base::self_type_for_closure(ccx, closure_did, fn_type);

src/librustc_trans/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
470470
}
471471
})
472472
}
473-
ty::TyClosure(def_id, substs) => {
473+
ty::TyClosure(def_id, substs, _) => { // TODO
474474
let repr = adt::represent_type(cx.ccx(), t);
475475
let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables);
476476
let upvars = infcx.closure_upvars(def_id, substs).unwrap();

0 commit comments

Comments
 (0)