use back::abi;
-use lib::llvm::llvm;
-use lib::llvm::ValueRef;
-use lib;
+use llvm;
+use llvm::ValueRef;
use metadata::csearch;
+use middle::subst::VecPerParamSpace;
use middle::subst;
use middle::trans::base::*;
use middle::trans::build::*;
use std::c_str::ToCStr;
use std::gc::Gc;
-use syntax::abi::Rust;
+use syntax::abi::{Rust, RustCall};
use syntax::parse::token;
use syntax::{ast, ast_map, visit};
+use syntax::ast_util::PostExpansionMethod;
/**
The main "translation" pass for methods. Generates code
return;
}
for method in methods.iter() {
- if method.generics.ty_params.len() == 0u {
+ if method.pe_generics().ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id);
- trans_fn(ccx, &*method.decl, &*method.body,
- llfn, ¶m_substs::empty(), method.id, []);
+ trans_fn(ccx,
+ &*method.pe_fn_decl(),
+ &*method.pe_body(),
+ llfn,
+ ¶m_substs::empty(),
+ method.id,
+ [],
+ TranslateItems);
} else {
let mut v = TransItemVisitor{ ccx: ccx };
visit::walk_method_helper(&mut v, &**method, ());
};
match origin {
- typeck::MethodStatic(did) => {
+ typeck::MethodStatic(did) |
+ typeck::MethodStaticUnboxedClosure(did) => {
Callee {
bcx: bcx,
- data: Fn(callee::trans_fn_ref(bcx, did, MethodCall(method_call)))
+ data: Fn(callee::trans_fn_ref(bcx,
+ did,
+ MethodCall(method_call))),
}
}
typeck::MethodParam(typeck::MethodParam {
ast_map::NodeTraitMethod(method) => {
let ident = match *method {
ast::Required(ref m) => m.ident,
- ast::Provided(ref m) => m.ident
+ ast::Provided(ref m) => m.pe_ident()
};
ident.name
}
let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
PointerCast(bcx, llfn, llty)
}
+ typeck::vtable_unboxed_closure(_) => {
+ bcx.tcx().sess.bug("can't call a closure vtable in a static way");
+ }
_ => {
fail!("vtable_param left in monomorphized \
function's vtable substs");
*meth_did
}
-fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
- method_call: MethodCall,
- trait_id: ast::DefId,
- n_method: uint,
- vtbl: typeck::vtable_origin)
- -> Callee<'a> {
+fn trans_monomorphized_callee<'a>(
+ bcx: &'a Block<'a>,
+ method_call: MethodCall,
+ trait_id: ast::DefId,
+ n_method: uint,
+ vtbl: typeck::vtable_origin)
+ -> Callee<'a> {
let _icx = push_ctxt("meth::trans_monomorphized_callee");
match vtbl {
typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
Callee { bcx: bcx, data: Fn(llfn) }
}
+ typeck::vtable_unboxed_closure(closure_def_id) => {
+ // The static region and type parameters are lies, but we're in
+ // trans so it doesn't matter.
+ //
+ // FIXME(pcwalton): Is this true in the case of type parameters?
+ let callee_substs = get_callee_substitutions_for_unboxed_closure(
+ bcx,
+ closure_def_id);
+
+ let llfn = trans_fn_ref_with_vtables(bcx,
+ closure_def_id,
+ MethodCall(method_call),
+ callee_substs,
+ VecPerParamSpace::empty());
+
+ Callee {
+ bcx: bcx,
+ data: Fn(llfn),
+ }
+ }
typeck::vtable_param(..) => {
bcx.tcx().sess.bug(
"vtable_param left in monomorphized function's vtable substs");
debug!("(translating trait callee) loading method");
// Replace the self type (&Self or Box<Self>) with an opaque pointer.
let llcallee_ty = match ty::get(callee_ty).sty {
- ty::ty_bare_fn(ref f) if f.abi == Rust => {
- type_of_rust_fn(ccx, true, f.sig.inputs.slice_from(1), f.sig.output)
+ ty::ty_bare_fn(ref f) if f.abi == Rust || f.abi == RustCall => {
+ type_of_rust_fn(ccx,
+ Some(Type::i8p(ccx)),
+ f.sig.inputs.slice_from(1),
+ f.sig.output,
+ f.abi)
}
_ => {
ccx.sess().bug("meth::trans_trait_callee given non-bare-rust-fn");
};
}
+/// Creates the self type and (fake) callee substitutions for an unboxed
+/// closure with the given def ID. The static region and type parameters are
+/// lies, but we're in trans so it doesn't matter.
+fn get_callee_substitutions_for_unboxed_closure(bcx: &Block,
+ def_id: ast::DefId)
+ -> subst::Substs {
+ let self_ty = ty::mk_unboxed_closure(bcx.tcx(), def_id);
+ subst::Substs::erased(
+ VecPerParamSpace::new(Vec::new(),
+ vec![
+ ty::mk_rptr(bcx.tcx(),
+ ty::ReStatic,
+ ty::mt {
+ ty: self_ty,
+ mutbl: ast::MutMutable,
+ })
+ ],
+ Vec::new()))
+}
+
/// Creates a returns a dynamic vtable for the given type and vtable origin.
/// This is used only for objects.
fn get_vtable(bcx: &Block,
typeck::vtable_static(id, substs, sub_vtables) => {
emit_vtable_methods(bcx, id, substs, sub_vtables).move_iter()
}
+ typeck::vtable_unboxed_closure(closure_def_id) => {
+ let callee_substs =
+ get_callee_substitutions_for_unboxed_closure(
+ bcx,
+ closure_def_id);
+
+ let llfn = trans_fn_ref_with_vtables(
+ bcx,
+ closure_def_id,
+ ExprId(0),
+ callee_substs,
+ VecPerParamSpace::empty());
+
+ (vec!(llfn)).move_iter()
+ }
_ => ccx.sess().bug("get_vtable: expected a static origin"),
}
});
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
});
llvm::LLVMSetInitializer(vt_gvar, tbl);
- llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
- lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
+ llvm::LLVMSetGlobalConstant(vt_gvar, llvm::True);
+ llvm::SetLinkage(vt_gvar, llvm::InternalLinkage);
vt_gvar
}
}
ExprId(0),
substs.clone(),
vtables.clone());
- if m.explicit_self == ast::SelfValue {
+ if m.explicit_self == ty::ByValueExplicitSelfCategory {
fn_ref = trans_unboxing_shim(bcx,
fn_ref,
&*m,