Skip to content

Commit d394e75

Browse files
committed
address review comments
1 parent 5795098 commit d394e75

File tree

4 files changed

+80
-73
lines changed

4 files changed

+80
-73
lines changed

src/librustc/infer/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1150,10 +1150,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11501150
self.tcx.mk_var(self.next_ty_var_id(true))
11511151
}
11521152

1153-
pub fn next_ty_vars(&self, n: usize) -> Vec<Ty<'tcx>> {
1154-
(0..n).map(|_i| self.next_ty_var()).collect()
1155-
}
1156-
11571153
pub fn next_int_var_id(&self) -> IntVid {
11581154
self.int_unification_table
11591155
.borrow_mut()

src/librustc/ty/subst.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,22 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
183183
tcx.intern_substs(&substs)
184184
}
185185

186+
pub fn extend_to<FR, FT>(&self,
187+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
188+
def_id: DefId,
189+
mut mk_region: FR,
190+
mut mk_type: FT)
191+
-> &'tcx Substs<'tcx>
192+
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
193+
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx>
194+
{
195+
let defs = tcx.item_generics(def_id);
196+
let mut result = Vec::with_capacity(defs.count());
197+
result.extend(self[..].iter().cloned());
198+
Substs::fill_single(&mut result, defs, &mut mk_region, &mut mk_type);
199+
tcx.intern_substs(&result)
200+
}
201+
186202
fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
187203
tcx: TyCtxt<'a, 'gcx, 'tcx>,
188204
defs: &ty::Generics<'tcx>,
@@ -195,7 +211,15 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
195211
let parent_defs = tcx.item_generics(def_id);
196212
Substs::fill_item(substs, tcx, parent_defs, mk_region, mk_type);
197213
}
214+
Substs::fill_single(substs, defs, mk_region, mk_type)
215+
}
198216

217+
fn fill_single<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
218+
defs: &ty::Generics<'tcx>,
219+
mk_region: &mut FR,
220+
mk_type: &mut FT)
221+
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
222+
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> {
199223
// Handle Self first, before all regions.
200224
let mut types = defs.types.iter();
201225
if defs.parent.is_none() && defs.has_self {
@@ -275,15 +299,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
275299
tcx.mk_substs(target_substs.iter().chain(&self[defs.own_count()..]).cloned())
276300
}
277301

278-
pub fn extend_with_types(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
279-
types: &[Ty<'tcx>])
280-
-> &'tcx Substs<'tcx> {
281-
tcx.mk_substs(
282-
self[..].iter().cloned().chain(
283-
types.iter().map(|a| Kind::from(*a)))
284-
)
285-
}
286-
287302
pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics<'tcx>)
288303
-> &'tcx Substs<'tcx> {
289304
tcx.mk_substs(self.iter().take(generics.count()).cloned())

src/librustc_typeck/check/closure.rs

+7-59
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@
1313
use super::{check_fn, Expectation, FnCtxt};
1414

1515
use astconv::AstConv;
16-
use rustc::hir::def_id::DefId;
1716
use rustc::ty::{self, ToPolyTraitRef, Ty};
18-
use rustc::ty::subst::Substs;
19-
use rustc::util::common::MemoizationMap;
2017
use std::cmp;
2118
use syntax::abi::Abi;
2219
use rustc::hir;
2320

24-
use syntax::parse::token;
25-
2621
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2722
pub fn check_expr_closure(&self,
2823
expr: &hir::Expr,
@@ -45,48 +40,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4540
self.check_closure(expr, expected_kind, decl, body, expected_sig)
4641
}
4742

48-
fn declare_closure(&self, def_id: DefId) {
49-
let tcx = self.tcx.global_tcx();
50-
51-
tcx.generics.memoize(def_id, || {
52-
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
53-
let base_def_id = self.tcx.closure_base_def_id(def_id);
54-
let base_generics = tcx.item_generics(base_def_id);
55-
56-
// provide junk type parameter defs - the only place that
57-
// cares about anything but the length is instantiation,
58-
// and we don't do that for closures.
59-
let upvar_decls : Vec<_> = tcx.with_freevars(node_id, |fv| {
60-
fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
61-
index: (base_generics.count() as u32) + (i as u32),
62-
name: token::intern("<upvar>"),
63-
def_id: def_id,
64-
default_def_id: base_def_id,
65-
default: None,
66-
object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
67-
pure_wrt_drop: false,
68-
}).collect()
69-
});
70-
71-
tcx.alloc_generics(ty::Generics {
72-
parent: Some(base_def_id),
73-
parent_regions: base_generics.parent_regions +
74-
(base_generics.regions.len() as u32),
75-
parent_types: base_generics.parent_types +
76-
(base_generics.types.len() as u32),
77-
regions: vec![],
78-
types: upvar_decls,
79-
has_self: false,
80-
})
81-
});
82-
83-
tcx.item_types.memoize(def_id, || tcx.mk_closure(def_id, Substs::for_item(
84-
tcx, def_id,
85-
|def, _| tcx.mk_region(def.to_early_bound_region()),
86-
|def, _| tcx.mk_param_from_def(def)
87-
)));
88-
}
89-
9043
fn check_closure(&self,
9144
expr: &hir::Expr,
9245
opt_kind: Option<ty::ClosureKind>,
@@ -99,8 +52,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
9952
expected_sig);
10053

10154
let expr_def_id = self.tcx.map.local_def_id(expr.id);
102-
self.declare_closure(expr_def_id);
103-
10455
let mut fn_ty = AstConv::ty_of_closure(self,
10556
hir::Unsafety::Normal,
10657
decl,
@@ -110,18 +61,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
11061
// Create type variables (for now) to represent the transformed
11162
// types of upvars. These will be unified during the upvar
11263
// inference phase (`upvar.rs`).
113-
let num_upvars = self.tcx.with_freevars(expr.id, |fv| fv.len());
114-
let upvar_tys = self.next_ty_vars(num_upvars);
115-
116-
debug!("check_closure: expr.id={:?} upvar_tys={:?}",
117-
expr.id,
118-
upvar_tys);
119-
120-
let closure_type = self.tcx.mk_closure(
121-
expr_def_id,
122-
self.parameter_environment.free_substs.extend_with_types(self.tcx, &upvar_tys)
64+
let closure_type = self.tcx.mk_closure(expr_def_id,
65+
self.parameter_environment.free_substs.extend_to(self.tcx, expr_def_id,
66+
|_, _| span_bug!(expr.span, "closure has region param"),
67+
|_, _| self.infcx.next_ty_var()
68+
)
12369
);
12470

71+
debug!("check_closure: expr.id={:?} closure_type={:?}", expr.id, closure_type);
72+
12573
let fn_sig = self.tcx
12674
.liberate_late_bound_regions(self.tcx.region_maps.call_site_extent(expr.id, body.id),
12775
&fn_ty.sig);

src/librustc_typeck/collect.rs

+49-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ use std::cell::RefCell;
8080
use std::collections::hash_map::Entry::{Occupied, Vacant};
8181

8282
use syntax::{abi, ast, attr};
83-
use syntax::parse::token::keywords;
83+
use syntax::parse::token::{self, keywords};
8484
use syntax_pos::Span;
8585

8686
use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
@@ -134,6 +134,13 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx>
134134
intravisit::walk_item(self, item);
135135
}
136136

137+
fn visit_expr(&mut self, expr: &hir::Expr) {
138+
if let hir::ExprClosure(..) = expr.node {
139+
convert_closure(self.ccx, expr.id);
140+
}
141+
intravisit::walk_expr(self, expr);
142+
}
143+
137144
fn visit_ty(&mut self, ty: &hir::Ty) {
138145
if let hir::TyImplTrait(..) = ty.node {
139146
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>,
559566
ccx.tcx.predicates.borrow_mut().insert(def_id, struct_predicates.clone());
560567
}
561568

569+
fn convert_closure<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
570+
node_id: ast::NodeId)
571+
{
572+
let tcx = ccx.tcx;
573+
let def_id = tcx.map.local_def_id(node_id);
574+
let base_def_id = tcx.closure_base_def_id(def_id);
575+
let base_generics = generics_of_def_id(ccx, base_def_id);
576+
577+
// provide junk type parameter defs - the only place that
578+
// cares about anything but the length is instantiation,
579+
// and we don't do that for closures.
580+
let upvar_decls : Vec<_> = tcx.with_freevars(node_id, |fv| {
581+
fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
582+
index: (base_generics.count() as u32) + (i as u32),
583+
name: token::intern("<upvar>"),
584+
def_id: def_id,
585+
default_def_id: base_def_id,
586+
default: None,
587+
object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
588+
pure_wrt_drop: false,
589+
}).collect()
590+
});
591+
tcx.generics.borrow_mut().insert(def_id, tcx.alloc_generics(ty::Generics {
592+
parent: Some(base_def_id),
593+
parent_regions: base_generics.parent_regions + (base_generics.regions.len() as u32),
594+
parent_types: base_generics.parent_types + (base_generics.types.len() as u32),
595+
regions: vec![],
596+
types: upvar_decls,
597+
has_self: base_generics.has_self,
598+
}));
599+
600+
type_of_def_id(ccx, def_id);
601+
}
602+
562603
fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
563604
container: AssociatedItemContainer,
564605
id: ast::NodeId,
@@ -1504,6 +1545,13 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
15041545
}
15051546
}
15061547
}
1548+
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
1549+
ccx.tcx.mk_closure(def_id, Substs::for_item(
1550+
ccx.tcx, def_id,
1551+
|def, _| ccx.tcx.mk_region(def.to_early_bound_region()),
1552+
|def, _| ccx.tcx.mk_param_from_def(def)
1553+
))
1554+
}
15071555
x => {
15081556
bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
15091557
}

0 commit comments

Comments
 (0)