diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index b2d7b83887e3..e4f6cb55324b 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2476,6 +2476,7 @@ fn set_global_section(ccx: &CrateContext, llval: ValueRef, i: &hir::Item) { pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { let _icx = push_ctxt("trans_item"); + let tcx = ccx.tcx(); let from_external = ccx.external_srcs().borrow().contains_key(&item.id); match item.node { @@ -2532,20 +2533,39 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { } } hir::ItemImpl(_, _, ref generics, _, _, ref impl_items) => { - meth::trans_impl(ccx, item.name, impl_items, generics, item.id); - } - hir::ItemMod(_) => { - // modules have no equivalent at runtime, they just affect - // the mangled names of things contained within + // Both here and below with generic methods, be sure to recurse and look for + // items that we need to translate. + if !generics.ty_params.is_empty() { + return; + } + + for impl_item in impl_items { + if let hir::ImplItemKind::Method(ref sig, ref body) = impl_item.node { + if sig.generics.ty_params.is_empty() { + let trans_everywhere = attr::requests_inline(&impl_item.attrs); + for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) { + let empty_substs = tcx.mk_substs(Substs::trans_empty()); + let def_id = tcx.map.local_def_id(impl_item.id); + let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val; + trans_fn(ccx, &sig.decl, body, llfn, empty_substs, + impl_item.id, &impl_item.attrs); + update_linkage(ccx, llfn, Some(impl_item.id), + if is_origin { + OriginalTranslation + } else { + InlinedCopy + }); + } + } + } + } } hir::ItemEnum(ref enum_definition, ref gens) => { if gens.ty_params.is_empty() { // sizes only make sense for non-generic types - enum_variant_size_lint(ccx, enum_definition, item.span, item.id); } } - hir::ItemConst(..) => {} hir::ItemStatic(_, m, ref expr) => { let g = match consts::trans_static(ccx, m, expr, item.id, &item.attrs) { Ok(g) => g, @@ -2554,13 +2574,16 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) { set_global_section(ccx, g, item); update_linkage(ccx, g, Some(item.id), OriginalTranslation); } - hir::ItemForeignMod(ref foreign_mod) => { - foreign::trans_foreign_mod(ccx, foreign_mod); - } - hir::ItemTrait(..) => {} - _ => { - // fall through + hir::ItemForeignMod(ref m) => { + if m.abi == Abi::RustIntrinsic || m.abi == Abi::PlatformIntrinsic { + return; + } + for fi in &m.items { + let lname = foreign::link_name(fi.name, &fi.attrs).to_string(); + ccx.item_symbols().borrow_mut().insert(fi.id, lname); + } } + _ => {} } } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 318c968692c7..daf8640ce94b 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -158,7 +158,7 @@ impl<'tcx> Callee<'tcx> { // those from the impl and those from the method: let impl_substs = vtable_impl.substs.with_method_from(&substs); let substs = tcx.mk_substs(impl_substs); - let mth = tcx.get_impl_method(impl_did, substs, mname); + let mth = meth::get_impl_method(tcx, impl_did, substs, mname); // Translate the function, bypassing Callee::def. // That is because default methods have the same ID as the diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 37de40efd3dd..592cb50930a5 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -463,31 +463,6 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, return bcx; } - -pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &hir::ForeignMod) { - let _icx = push_ctxt("foreign::trans_foreign_mod"); - for foreign_item in &foreign_mod.items { - let lname = link_name(foreign_item); - - if let hir::ForeignItemFn(ref decl, _) = foreign_item.node { - match foreign_mod.abi { - Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic => {} - abi => { - let ty = ccx.tcx().node_id_to_type(foreign_item.id); - register_foreign_item_fn(ccx, abi, ty, &lname, &foreign_item.attrs); - // Unlike for other items, we shouldn't call - // `base::update_linkage` here. Foreign items have - // special linkage requirements, which are handled - // inside `foreign::register_*`. - } - } - } - - ccx.item_symbols().borrow_mut().insert(foreign_item.id, - lname.to_string()); - } -} - /////////////////////////////////////////////////////////////////////////// // Rust functions with foreign ABIs // @@ -890,12 +865,12 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // This code is kind of a confused mess and needs to be reworked given // the massive simplifications that have occurred. -pub fn link_name(i: &hir::ForeignItem) -> InternedString { - match attr::first_attr_value_str_by_name(&i.attrs, "link_name") { +pub fn link_name(name: ast::Name, attrs: &[ast::Attribute]) -> InternedString { + match attr::first_attr_value_str_by_name(attrs, "link_name") { Some(ln) => ln.clone(), - None => match weak_lang_items::link_name(&i.attrs) { + None => match weak_lang_items::link_name(attrs) { Some(name) => name, - None => i.name.as_str(), + None => name.as_str(), } } } diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 5b052a8e6024..dad26900fdff 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -20,8 +20,7 @@ use middle::subst; use middle::traits::{self, ProjectionMode}; use trans::base::*; use trans::build::*; -use trans::callee::{Callee, Virtual, ArgVals, - trans_fn_pointer_shim, trans_fn_ref_with_substs}; +use trans::callee::{Callee, Virtual, ArgVals, trans_fn_pointer_shim}; use trans::closure; use trans::common::*; use trans::consts; @@ -37,130 +36,11 @@ use trans::value::Value; use middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use syntax::ast::{self, Name}; -use syntax::attr; use syntax::codemap::DUMMY_SP; -use rustc_front::hir; - // drop_glue pointer, size, align. const VTABLE_OFFSET: usize = 3; -/// The main "translation" pass for methods. Generates code -/// for non-monomorphized methods only. Other methods will -/// be generated once they are invoked with specific type parameters, -/// see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`. -pub fn trans_impl(ccx: &CrateContext, - name: ast::Name, - impl_items: &[hir::ImplItem], - generics: &hir::Generics, - id: ast::NodeId) { - let _icx = push_ctxt("meth::trans_impl"); - let tcx = ccx.tcx(); - - debug!("trans_impl(name={}, id={})", name, id); - - // Both here and below with generic methods, be sure to recurse and look for - // items that we need to translate. - if !generics.ty_params.is_empty() { - return; - } - - for impl_item in impl_items { - match impl_item.node { - hir::ImplItemKind::Method(ref sig, ref body) => { - if sig.generics.ty_params.is_empty() { - let trans_everywhere = attr::requests_inline(&impl_item.attrs); - for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) { - let llfn = get_item_val(ccx, impl_item.id); - let empty_substs = tcx.mk_substs(Substs::trans_empty()); - trans_fn(ccx, - &sig.decl, - body, - llfn, - empty_substs, - impl_item.id, - &impl_item.attrs); - update_linkage(ccx, - llfn, - Some(impl_item.id), - if is_origin { OriginalTranslation } else { InlinedCopy }); - } - } - } - _ => {} - } - } -} - -/// Compute the appropriate callee, give na method's ID, trait ID, -/// substitutions and a Vtable for that trait. -pub fn callee_for_trait_impl<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - method_id: DefId, - substs: &'tcx subst::Substs<'tcx>, - trait_id: DefId, - method_ty: Ty<'tcx>, - vtable: traits::Vtable<'tcx, ()>) - -> Callee<'tcx> { - let _icx = push_ctxt("meth::callee_for_trait_impl"); - match vtable { - traits::VtableImpl(vtable_impl) => { - let impl_did = vtable_impl.impl_def_id; - let mname = ccx.tcx().item_name(method_id); - // create a concatenated set of substitutions which includes - // those from the impl and those from the method: - let impl_substs = vtable_impl.substs.with_method_from(&substs); - let substs = ccx.tcx().mk_substs(impl_substs); - let mth = get_impl_method(ccx.tcx(), impl_did, substs, mname); - - // Translate the function, bypassing Callee::def. - // That is because default methods have the same ID as the - // trait method used to look up the impl method that ended - // up here, so calling Callee::def would infinitely recurse. - Callee::ptr(trans_fn_ref_with_substs(ccx, mth.method.def_id, - Some(method_ty), mth.substs)) - } - traits::VtableClosure(vtable_closure) => { - // The substitutions should have no type parameters remaining - // after passing through fulfill_obligation - let trait_closure_kind = ccx.tcx().lang_items.fn_trait_kind(trait_id).unwrap(); - let llfn = closure::trans_closure_method(ccx, - vtable_closure.closure_def_id, - vtable_closure.substs, - trait_closure_kind); - let fn_ptr_ty = match method_ty.sty { - ty::TyFnDef(_, _, fty) => ccx.tcx().mk_ty(ty::TyFnPtr(fty)), - _ => unreachable!("expected fn item type, found {}", - method_ty) - }; - Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty)) - } - traits::VtableFnPointer(fn_ty) => { - let trait_closure_kind = ccx.tcx().lang_items.fn_trait_kind(trait_id).unwrap(); - let llfn = trans_fn_pointer_shim(ccx, trait_closure_kind, fn_ty); - let fn_ptr_ty = match method_ty.sty { - ty::TyFnDef(_, _, fty) => ccx.tcx().mk_ty(ty::TyFnPtr(fty)), - _ => unreachable!("expected fn item type, found {}", - method_ty) - }; - Callee::ptr(immediate_rvalue(llfn, fn_ptr_ty)) - } - traits::VtableObject(ref data) => { - Callee { - data: Virtual(traits::get_vtable_index_of_object_method( - ccx.tcx(), data, method_id)), - ty: method_ty - } - } - traits::VtableBuiltin(..) | - traits::VtableDefaultImpl(..) | - traits::VtableParam(..) => { - ccx.sess().bug( - &format!("resolved vtable bad vtable {:?} in trans", - vtable)); - } - } -} - /// Extracts a method from a trait object's vtable, at the /// specified index, and casts it to the given type. pub fn get_virtual_method<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,