auto merge of #16655 : pcwalton/rust/unboxed-closures-unboxing-shims, r=luqmana

Closes #16591.

r? @luqmana
This commit is contained in:
bors 2014-08-22 13:35:51 +00:00
commit c9cf3b3cc4
3 changed files with 82 additions and 11 deletions

View File

@ -288,7 +288,7 @@ fn resolve_default_method_vtables(bcx: &Block,
/// `Trait` so that a by-value self method can be called.
pub fn trans_unboxing_shim(bcx: &Block,
llshimmedfn: ValueRef,
method: &ty::Method,
fty: &ty::BareFnTy,
method_id: ast::DefId,
substs: subst::Substs)
-> ValueRef {
@ -297,29 +297,29 @@ pub fn trans_unboxing_shim(bcx: &Block,
let tcx = bcx.tcx();
// Transform the self type to `Box<self_type>`.
let self_type = *method.fty.sig.inputs.get(0);
let self_type = *fty.sig.inputs.get(0);
let boxed_self_type = ty::mk_uniq(tcx, self_type);
let boxed_function_type = ty::FnSig {
binder_id: method.fty.sig.binder_id,
inputs: method.fty.sig.inputs.iter().enumerate().map(|(i, typ)| {
binder_id: fty.sig.binder_id,
inputs: fty.sig.inputs.iter().enumerate().map(|(i, typ)| {
if i == 0 {
boxed_self_type
} else {
*typ
}
}).collect(),
output: method.fty.sig.output,
output: fty.sig.output,
variadic: false,
};
let boxed_function_type = ty::BareFnTy {
fn_style: method.fty.fn_style,
abi: method.fty.abi,
fn_style: fty.fn_style,
abi: fty.abi,
sig: boxed_function_type,
};
let boxed_function_type =
ty::mk_bare_fn(tcx, boxed_function_type).subst(tcx, &substs);
let function_type =
ty::mk_bare_fn(tcx, method.fty.clone()).subst(tcx, &substs);
ty::mk_bare_fn(tcx, (*fty).clone()).subst(tcx, &substs);
let function_name = ty::with_path(tcx, method_id, |path| {
link::mangle_internal_name_by_path_and_seq(path, "unboxing_shim")

View File

@ -515,13 +515,65 @@ fn get_vtable(bcx: &Block,
bcx,
closure_def_id);
let llfn = trans_fn_ref_with_vtables(
let mut llfn = trans_fn_ref_with_vtables(
bcx,
closure_def_id,
ExprId(0),
callee_substs,
callee_substs.clone(),
VecPerParamSpace::empty());
{
let unboxed_closures = bcx.tcx()
.unboxed_closures
.borrow();
let closure_info =
unboxed_closures.find(&closure_def_id)
.expect("get_vtable(): didn't find \
unboxed closure");
if closure_info.kind == ty::FnOnceUnboxedClosureKind {
// Untuple the arguments and create an unboxing shim.
let mut new_inputs = vec![
ty::mk_unboxed_closure(bcx.tcx(),
closure_def_id,
ty::ReStatic)
];
match ty::get(closure_info.closure_type
.sig
.inputs[0]).sty {
ty::ty_tup(ref elements) => {
for element in elements.iter() {
new_inputs.push(*element)
}
}
ty::ty_nil => {}
_ => {
bcx.tcx().sess.bug("get_vtable(): closure \
type wasn't a tuple")
}
}
let closure_type = ty::BareFnTy {
fn_style: closure_info.closure_type.fn_style,
abi: Rust,
sig: ty::FnSig {
binder_id: closure_info.closure_type
.sig
.binder_id,
inputs: new_inputs,
output: closure_info.closure_type.sig.output,
variadic: false,
},
};
debug!("get_vtable(): closure type is {}",
closure_type.repr(bcx.tcx()));
llfn = trans_unboxing_shim(bcx,
llfn,
&closure_type,
closure_def_id,
callee_substs);
}
}
(vec!(llfn)).move_iter()
}
_ => ccx.sess().bug("get_vtable: expected a static origin"),
@ -603,7 +655,7 @@ fn emit_vtable_methods(bcx: &Block,
if m.explicit_self == ty::ByValueExplicitSelfCategory {
fn_ref = trans_unboxing_shim(bcx,
fn_ref,
&*m,
&m.fty,
m_id,
substs.clone());
}

View File

@ -0,0 +1,19 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(unboxed_closures, unboxed_closure_sugar)]
use std::ops::FnOnce;
fn main() {
let task: Box<|: int| -> int> = box |: x| x;
assert!(task.call_once((1234i,)) == 1234i);
}