Skip to content

Commit 02adaca

Browse files
committed
librustc: Implement unboxed closures with mutable receivers
1 parent 5ddc7b4 commit 02adaca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1905
-384
lines changed

src/libcore/ops.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,19 +749,23 @@ pub trait DerefMut<Result>: Deref<Result> {
749749
#[lang="fn"]
750750
pub trait Fn<Args,Result> {
751751
/// This is called when the call operator is used.
752+
#[rust_call_abi_hack]
752753
fn call(&self, args: Args) -> Result;
753754
}
754755

755756
/// A version of the call operator that takes a mutable receiver.
756757
#[lang="fn_mut"]
757758
pub trait FnMut<Args,Result> {
758759
/// This is called when the call operator is used.
760+
#[rust_call_abi_hack]
759761
fn call_mut(&mut self, args: Args) -> Result;
760762
}
761763

762764
/// A version of the call operator that takes a by-value receiver.
763765
#[lang="fn_once"]
764766
pub trait FnOnce<Args,Result> {
765767
/// This is called when the call operator is used.
768+
#[rust_call_abi_hack]
766769
fn call_once(self, args: Args) -> Result;
767770
}
771+

src/libcore/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub use ops::{BitAnd, BitOr, BitXor};
3535
pub use ops::{Drop, Deref, DerefMut};
3636
pub use ops::{Shl, Shr};
3737
pub use ops::{Index, IndexMut};
38+
pub use ops::{Fn, FnMut, FnOnce};
3839
pub use option::{Option, Some, None};
3940
pub use result::{Result, Ok, Err};
4041

src/librustc/front/feature_gate.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
6767
("quad_precision_float", Removed),
6868

6969
("rustc_diagnostic_macros", Active),
70+
("unboxed_closures", Active),
7071

7172
// A temporary feature gate used to enable parser extensions needed
7273
// to bootstrap fix for #5723.
@@ -327,6 +328,12 @@ impl<'a> Visitor<()> for Context<'a> {
327328
ast::ExprUnary(ast::UnBox, _) => {
328329
self.gate_box(e.span);
329330
}
331+
ast::ExprUnboxedFn(..) => {
332+
self.gate_feature("unboxed_closures",
333+
e.span,
334+
"unboxed closures are a work-in-progress \
335+
feature with known bugs");
336+
}
330337
_ => {}
331338
}
332339
visit::walk_expr(self, e, ());

src/librustc/lint/builtin.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,9 @@ impl LintPass for Stability {
14511451
typeck::MethodStatic(def_id) => {
14521452
def_id
14531453
}
1454+
typeck::MethodStaticUnboxedClosure(def_id) => {
1455+
def_id
1456+
}
14541457
typeck::MethodParam(typeck::MethodParam {
14551458
trait_id: trait_id,
14561459
method_num: index,

src/librustc/metadata/common.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,11 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
138138
tag_table_vtable_map = 0x50,
139139
tag_table_adjustments = 0x51,
140140
tag_table_moves_map = 0x52,
141-
tag_table_capture_map = 0x53
141+
tag_table_capture_map = 0x53,
142+
tag_table_unboxed_closure_type = 0x54,
142143
}
143144
static first_astencode_tag: uint = tag_ast as uint;
144-
static last_astencode_tag: uint = tag_table_capture_map as uint;
145+
static last_astencode_tag: uint = tag_table_unboxed_closure_type as uint;
145146
impl astencode_tag {
146147
pub fn from_uint(value : uint) -> Option<astencode_tag> {
147148
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
@@ -155,6 +156,10 @@ pub static tag_item_trait_method_sort: uint = 0x60;
155156

156157
pub static tag_item_impl_type_basename: uint = 0x61;
157158

159+
pub static tag_crate_triple: uint = 0x66;
160+
161+
pub static tag_dylib_dependency_formats: uint = 0x67;
162+
158163
// Language items are a top-level directory (for speed). Hierarchy:
159164
//
160165
// tag_lang_items
@@ -199,10 +204,6 @@ pub static tag_plugin_registrar_fn: uint = 0x8b;
199204
pub static tag_exported_macros: uint = 0x8c;
200205
pub static tag_macro_def: uint = 0x8d;
201206

202-
pub static tag_crate_triple: uint = 0x66;
203-
204-
pub static tag_dylib_dependency_formats: uint = 0x67;
205-
206207
pub static tag_method_argument_names: uint = 0x8e;
207208
pub static tag_method_argument_name: uint = 0x8f;
208209

@@ -211,7 +212,6 @@ pub static tag_reachable_extern_fn_id: uint = 0x91;
211212

212213
pub static tag_items_data_item_stability: uint = 0x92;
213214

214-
215215
#[deriving(Clone, Show)]
216216
pub struct LinkMeta {
217217
pub crate_name: String,
@@ -223,3 +223,7 @@ pub static tag_region_param_def_ident: uint = 0x91;
223223
pub static tag_region_param_def_def_id: uint = 0x92;
224224
pub static tag_region_param_def_space: uint = 0x93;
225225
pub static tag_region_param_def_index: uint = 0x94;
226+
227+
pub static tag_unboxed_closures: uint = 0x95;
228+
pub static tag_unboxed_closure: uint = 0x96;
229+
pub static tag_unboxed_closure_type: uint = 0x97;

src/librustc/metadata/encoder.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
209209
ebml_w.end_tag();
210210
}
211211

212+
pub fn write_closure_type(ecx: &EncodeContext,
213+
ebml_w: &mut Encoder,
214+
closure_type: &ty::ClosureTy) {
215+
let ty_str_ctxt = &tyencode::ctxt {
216+
diag: ecx.diag,
217+
ds: def_to_string,
218+
tcx: ecx.tcx,
219+
abbrevs: &ecx.type_abbrevs
220+
};
221+
tyencode::enc_closure_ty(ebml_w.writer, ty_str_ctxt, closure_type);
222+
}
223+
212224
pub fn write_type(ecx: &EncodeContext,
213225
ebml_w: &mut Encoder,
214226
typ: ty::t) {
@@ -1618,6 +1630,26 @@ fn encode_macro_defs(ecx: &EncodeContext,
16181630
ebml_w.end_tag();
16191631
}
16201632

1633+
fn encode_unboxed_closures<'a>(
1634+
ecx: &'a EncodeContext,
1635+
ebml_w: &'a mut Encoder) {
1636+
ebml_w.start_tag(tag_unboxed_closures);
1637+
for (unboxed_closure_id, unboxed_closure_type) in
1638+
ecx.tcx.unboxed_closure_types.borrow().iter() {
1639+
if unboxed_closure_id.krate != LOCAL_CRATE {
1640+
continue
1641+
}
1642+
1643+
ebml_w.start_tag(tag_unboxed_closure);
1644+
encode_def_id(ebml_w, *unboxed_closure_id);
1645+
ebml_w.start_tag(tag_unboxed_closure_type);
1646+
write_closure_type(ecx, ebml_w, unboxed_closure_type);
1647+
ebml_w.end_tag();
1648+
ebml_w.end_tag();
1649+
}
1650+
ebml_w.end_tag();
1651+
}
1652+
16211653
struct ImplVisitor<'a,'b,'c> {
16221654
ecx: &'a EncodeContext<'b>,
16231655
ebml_w: &'a mut Encoder<'c>,
@@ -1787,6 +1819,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
17871819
native_lib_bytes: u64,
17881820
plugin_registrar_fn_bytes: u64,
17891821
macro_defs_bytes: u64,
1822+
unboxed_closure_bytes: u64,
17901823
impl_bytes: u64,
17911824
misc_bytes: u64,
17921825
item_bytes: u64,
@@ -1801,6 +1834,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
18011834
native_lib_bytes: 0,
18021835
plugin_registrar_fn_bytes: 0,
18031836
macro_defs_bytes: 0,
1837+
unboxed_closure_bytes: 0,
18041838
impl_bytes: 0,
18051839
misc_bytes: 0,
18061840
item_bytes: 0,
@@ -1873,6 +1907,11 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
18731907
encode_macro_defs(&ecx, krate, &mut ebml_w);
18741908
stats.macro_defs_bytes = ebml_w.writer.tell().unwrap() - i;
18751909

1910+
// Encode the types of all unboxed closures in this crate.
1911+
i = ebml_w.writer.tell().unwrap();
1912+
encode_unboxed_closures(&ecx, &mut ebml_w);
1913+
stats.unboxed_closure_bytes = ebml_w.writer.tell().unwrap() - i;
1914+
18761915
// Encode the def IDs of impls, for coherence checking.
18771916
i = ebml_w.writer.tell().unwrap();
18781917
encode_impls(&ecx, krate, &mut ebml_w);
@@ -1911,6 +1950,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
19111950
println!(" native bytes: {}", stats.native_lib_bytes);
19121951
println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
19131952
println!(" macro def bytes: {}", stats.macro_defs_bytes);
1953+
println!(" unboxed closure bytes: {}", stats.unboxed_closure_bytes);
19141954
println!(" impl bytes: {}", stats.impl_bytes);
19151955
println!(" misc bytes: {}", stats.misc_bytes);
19161956
println!(" item bytes: {}", stats.item_bytes);

src/librustc/metadata/tydecode.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ fn data_log_string(data: &[u8], pos: uint) -> String {
130130
buf
131131
}
132132

133+
pub fn parse_ty_closure_data(data: &[u8],
134+
crate_num: ast::CrateNum,
135+
pos: uint,
136+
tcx: &ty::ctxt,
137+
conv: conv_did)
138+
-> ty::ClosureTy {
139+
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
140+
parse_closure_ty(&mut st, conv)
141+
}
142+
133143
pub fn parse_ty_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx: &ty::ctxt,
134144
conv: conv_did) -> ty::t {
135145
debug!("parse_ty_data {}", data_log_string(data, pos));
@@ -420,6 +430,10 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
420430
assert_eq!(next(st), ']');
421431
return ty::mk_struct(st.tcx, did, substs);
422432
}
433+
'k' => {
434+
let did = parse_def(st, NominalType, |x,y| conv(x,y));
435+
return ty::mk_unboxed_closure(st.tcx, did);
436+
}
423437
'e' => {
424438
return ty::mk_err();
425439
}
@@ -502,12 +516,14 @@ fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy {
502516
let store = parse_trait_store(st, |x,y| conv(x,y));
503517
let bounds = parse_bounds(st, |x,y| conv(x,y));
504518
let sig = parse_sig(st, |x,y| conv(x,y));
519+
let abi = parse_abi_set(st);
505520
ty::ClosureTy {
506521
fn_style: fn_style,
507522
onceness: onceness,
508523
store: store,
509524
bounds: bounds.builtin_bounds,
510-
sig: sig
525+
sig: sig,
526+
abi: abi,
511527
}
512528
}
513529

src/librustc/metadata/tyencode.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
284284
enc_substs(w, cx, substs);
285285
mywrite!(w, "]");
286286
}
287+
ty::ty_unboxed_closure(def) => {
288+
mywrite!(w, "k{}", (cx.ds)(def));
289+
}
287290
ty::ty_err => {
288291
mywrite!(w, "e");
289292
}
@@ -316,14 +319,15 @@ pub fn enc_bare_fn_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::BareFnTy) {
316319
enc_fn_sig(w, cx, &ft.sig);
317320
}
318321

319-
fn enc_closure_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::ClosureTy) {
322+
pub fn enc_closure_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::ClosureTy) {
320323
enc_fn_style(w, ft.fn_style);
321324
enc_onceness(w, ft.onceness);
322325
enc_trait_store(w, cx, ft.store);
323326
let bounds = ty::ParamBounds {builtin_bounds: ft.bounds,
324327
trait_bounds: Vec::new()};
325328
enc_bounds(w, cx, &bounds);
326329
enc_fn_sig(w, cx, &ft.sig);
330+
enc_abi(w, ft.abi);
327331
}
328332

329333
fn enc_fn_sig(w: &mut MemWriter, cx: &ctxt, fsig: &ty::FnSig) {

0 commit comments

Comments
 (0)