Skip to content

Commit 3fbfad3

Browse files
committed
Auto merge of #21604 - nikomatsakis:closure-move-indiv-vars, r=eddyb
r? @eddyb
2 parents 1a51eb9 + ced1062 commit 3fbfad3

30 files changed

+644
-480
lines changed

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#![feature(lang_items, unsafe_destructor)]
7171
#![feature(box_syntax)]
7272
#![feature(optin_builtin_traits)]
73+
#![feature(unboxed_closures)]
7374
#![allow(unknown_features)] #![feature(int_uint)]
7475
#![feature(core)]
7576
#![feature(hash)]

src/libcore/ops.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,7 @@ impl<F,A,R> FnOnce<A,R> for F
11831183
#[unstable(feature = "core",
11841184
reason = "uncertain about variadic generics, input versus associated types")]
11851185
#[cfg(not(stage0))]
1186+
#[rustc_paren_sugar]
11861187
pub trait Fn<Args> {
11871188
type Output;
11881189

@@ -1195,6 +1196,7 @@ pub trait Fn<Args> {
11951196
#[unstable(feature = "core",
11961197
reason = "uncertain about variadic generics, input versus associated types")]
11971198
#[cfg(not(stage0))]
1199+
#[rustc_paren_sugar]
11981200
pub trait FnMut<Args> {
11991201
type Output;
12001202

@@ -1207,6 +1209,7 @@ pub trait FnMut<Args> {
12071209
#[unstable(feature = "core",
12081210
reason = "uncertain about variadic generics, input versus associated types")]
12091211
#[cfg(not(stage0))]
1212+
#[rustc_paren_sugar]
12101213
pub trait FnOnce<Args> {
12111214
type Output;
12121215

src/librustc/lint/builtin.rs

+1
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ impl LintPass for UnusedAttributes {
670670
// FIXME: #19470 this shouldn't be needed forever
671671
"old_orphan_check",
672672
"old_impl_check",
673+
"rustc_paren_sugar", // FIXME: #18101 temporary unboxed closure hack
673674
];
674675

675676
static CRATE_ATTRS: &'static [&'static str] = &[

src/librustc/metadata/common.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
140140
tag_table_moves_map = 0x52,
141141
tag_table_capture_map = 0x53,
142142
tag_table_closures = 0x54,
143-
tag_table_upvar_borrow_map = 0x55,
143+
tag_table_upvar_capture_map = 0x55,
144144
tag_table_capture_modes = 0x56,
145145
tag_table_object_cast_map = 0x57,
146146
}
@@ -265,3 +265,5 @@ pub const tag_polarity: uint = 0xb4;
265265
pub const tag_macro_defs: uint = 0xb5;
266266
pub const tag_macro_def: uint = 0xb6;
267267
pub const tag_macro_def_body: uint = 0xb7;
268+
269+
pub const tag_paren_sugar: uint = 0xb8;

src/librustc/metadata/decoder.rs

+7
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety {
371371
}
372372
}
373373

374+
fn parse_paren_sugar(item_doc: rbml::Doc) -> bool {
375+
let paren_sugar_doc = reader::get_doc(item_doc, tag_paren_sugar);
376+
reader::doc_as_u8(paren_sugar_doc) != 0
377+
}
378+
374379
fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
375380
let polarity_doc = reader::get_doc(item_doc, tag_polarity);
376381
if reader::doc_as_u8(polarity_doc) != 0 {
@@ -400,8 +405,10 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
400405
let bounds = trait_def_bounds(item_doc, tcx, cdata);
401406
let unsafety = parse_unsafety(item_doc);
402407
let associated_type_names = parse_associated_type_names(item_doc);
408+
let paren_sugar = parse_paren_sugar(item_doc);
403409

404410
ty::TraitDef {
411+
paren_sugar: paren_sugar,
405412
unsafety: unsafety,
406413
generics: generics,
407414
bounds: bounds,

src/librustc/metadata/encoder.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13171317
encode_item_variances(rbml_w, ecx, item.id);
13181318
let trait_def = ty::lookup_trait_def(tcx, def_id);
13191319
encode_unsafety(rbml_w, trait_def.unsafety);
1320+
encode_paren_sugar(rbml_w, trait_def.paren_sugar);
13201321
encode_associated_type_names(rbml_w, trait_def.associated_type_names.as_slice());
13211322
encode_generics(rbml_w, ecx, &trait_def.generics, tag_item_generics);
13221323
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
@@ -1697,6 +1698,11 @@ fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) {
16971698
rbml_w.wr_tagged_u8(tag_unsafety, byte);
16981699
}
16991700

1701+
fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
1702+
let byte: u8 = if paren_sugar {1} else {0};
1703+
rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
1704+
}
1705+
17001706
fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
17011707
rbml_w.start_tag(tag_associated_type_names);
17021708
for &name in names.iter() {

src/librustc/middle/astencode.rs

+25-41
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,6 @@ fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
518518
(*fv).encode(rbml_w).unwrap();
519519
}
520520

521-
fn encode_capture_mode(rbml_w: &mut Encoder, cm: ast::CaptureClause) {
522-
cm.encode(rbml_w).unwrap();
523-
}
524-
525521
trait rbml_decoder_helper {
526522
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
527523
-> ty::Freevar;
@@ -559,6 +555,15 @@ impl tr for ty::UpvarBorrow {
559555
}
560556
}
561557

558+
impl tr for ty::UpvarCapture {
559+
fn tr(&self, dcx: &DecodeContext) -> ty::UpvarCapture {
560+
match *self {
561+
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
562+
ty::UpvarCapture::ByRef(ref data) => ty::UpvarCapture::ByRef(data.tr(dcx)),
563+
}
564+
}
565+
}
566+
562567
// ______________________________________________________________________
563568
// Encoding and decoding of MethodCallee
564569

@@ -1210,34 +1215,20 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
12101215
});
12111216

12121217
for freevar in fv.iter() {
1213-
match tcx.capture_mode(id) {
1214-
ast::CaptureByRef => {
1215-
rbml_w.tag(c::tag_table_upvar_borrow_map, |rbml_w| {
1216-
rbml_w.id(id);
1217-
rbml_w.tag(c::tag_table_val, |rbml_w| {
1218-
let var_id = freevar.def.def_id().node;
1219-
let upvar_id = ty::UpvarId {
1220-
var_id: var_id,
1221-
closure_expr_id: id
1222-
};
1223-
let upvar_borrow = tcx.upvar_borrow_map.borrow()[upvar_id].clone();
1224-
var_id.encode(rbml_w);
1225-
upvar_borrow.encode(rbml_w);
1226-
})
1227-
})
1228-
}
1229-
_ => {}
1230-
}
1231-
}
1232-
}
1233-
1234-
for &cm in tcx.capture_modes.borrow().get(&id).iter() {
1235-
rbml_w.tag(c::tag_table_capture_modes, |rbml_w| {
1236-
rbml_w.id(id);
1237-
rbml_w.tag(c::tag_table_val, |rbml_w| {
1238-
encode_capture_mode(rbml_w, *cm);
1218+
rbml_w.tag(c::tag_table_upvar_capture_map, |rbml_w| {
1219+
rbml_w.id(id);
1220+
rbml_w.tag(c::tag_table_val, |rbml_w| {
1221+
let var_id = freevar.def.def_id().node;
1222+
let upvar_id = ty::UpvarId {
1223+
var_id: var_id,
1224+
closure_expr_id: id
1225+
};
1226+
let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
1227+
var_id.encode(rbml_w);
1228+
upvar_capture.encode(rbml_w);
1229+
})
12391230
})
1240-
})
1231+
}
12411232
}
12421233

12431234
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
@@ -1911,21 +1902,14 @@ fn decode_side_tables(dcx: &DecodeContext,
19111902
}).unwrap().into_iter().collect();
19121903
dcx.tcx.freevars.borrow_mut().insert(id, fv_info);
19131904
}
1914-
c::tag_table_upvar_borrow_map => {
1905+
c::tag_table_upvar_capture_map => {
19151906
let var_id: ast::NodeId = Decodable::decode(val_dsr).unwrap();
19161907
let upvar_id = ty::UpvarId {
19171908
var_id: dcx.tr_id(var_id),
19181909
closure_expr_id: id
19191910
};
1920-
let ub: ty::UpvarBorrow = Decodable::decode(val_dsr).unwrap();
1921-
dcx.tcx.upvar_borrow_map.borrow_mut().insert(upvar_id, ub.tr(dcx));
1922-
}
1923-
c::tag_table_capture_modes => {
1924-
let capture_mode = val_dsr.read_capture_mode();
1925-
dcx.tcx
1926-
.capture_modes
1927-
.borrow_mut()
1928-
.insert(id, capture_mode);
1911+
let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
1912+
dcx.tcx.upvar_capture_map.borrow_mut().insert(upvar_id, ub.tr(dcx));
19291913
}
19301914
c::tag_table_tcache => {
19311915
let type_scheme = val_dsr.read_type_scheme(dcx);

src/librustc/middle/expr_use_visitor.rs

+24-42
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,9 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
366366
consume_id: ast::NodeId,
367367
consume_span: Span,
368368
cmt: mc::cmt<'tcx>) {
369+
debug!("delegate_consume(consume_id={}, cmt={})",
370+
consume_id, cmt.repr(self.tcx()));
371+
369372
let mode = copy_or_move(self.typer, &cmt, DirectRefMove);
370373
self.delegate.consume(consume_id, consume_span, cmt, mode);
371374
}
@@ -1208,53 +1211,32 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
12081211
debug!("walk_captures({})", closure_expr.repr(self.tcx()));
12091212

12101213
ty::with_freevars(self.tcx(), closure_expr.id, |freevars| {
1211-
match self.tcx().capture_mode(closure_expr.id) {
1212-
ast::CaptureByRef => {
1213-
self.walk_by_ref_captures(closure_expr, freevars);
1214-
}
1215-
ast::CaptureByValue => {
1216-
self.walk_by_value_captures(closure_expr, freevars);
1214+
for freevar in freevars.iter() {
1215+
let id_var = freevar.def.def_id().node;
1216+
let upvar_id = ty::UpvarId { var_id: id_var,
1217+
closure_expr_id: closure_expr.id };
1218+
let upvar_capture = self.typer.upvar_capture(upvar_id).unwrap();
1219+
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
1220+
closure_expr.span,
1221+
freevar.def));
1222+
match upvar_capture {
1223+
ty::UpvarCapture::ByValue => {
1224+
let mode = copy_or_move(self.typer, &cmt_var, CaptureMove);
1225+
self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
1226+
}
1227+
ty::UpvarCapture::ByRef(upvar_borrow) => {
1228+
self.delegate.borrow(closure_expr.id,
1229+
closure_expr.span,
1230+
cmt_var,
1231+
upvar_borrow.region,
1232+
upvar_borrow.kind,
1233+
ClosureCapture(freevar.span));
1234+
}
12171235
}
12181236
}
12191237
});
12201238
}
12211239

1222-
fn walk_by_ref_captures(&mut self,
1223-
closure_expr: &ast::Expr,
1224-
freevars: &[ty::Freevar]) {
1225-
for freevar in freevars.iter() {
1226-
let id_var = freevar.def.def_id().node;
1227-
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
1228-
closure_expr.span,
1229-
freevar.def));
1230-
1231-
// Lookup the kind of borrow the callee requires, as
1232-
// inferred by regionbk
1233-
let upvar_id = ty::UpvarId { var_id: id_var,
1234-
closure_expr_id: closure_expr.id };
1235-
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
1236-
1237-
self.delegate.borrow(closure_expr.id,
1238-
closure_expr.span,
1239-
cmt_var,
1240-
upvar_borrow.region,
1241-
upvar_borrow.kind,
1242-
ClosureCapture(freevar.span));
1243-
}
1244-
}
1245-
1246-
fn walk_by_value_captures(&mut self,
1247-
closure_expr: &ast::Expr,
1248-
freevars: &[ty::Freevar]) {
1249-
for freevar in freevars.iter() {
1250-
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
1251-
closure_expr.span,
1252-
freevar.def));
1253-
let mode = copy_or_move(self.typer, &cmt_var, CaptureMove);
1254-
self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
1255-
}
1256-
}
1257-
12581240
fn cat_captured_var(&mut self,
12591241
closure_id: ast::NodeId,
12601242
closure_span: Span,

0 commit comments

Comments
 (0)