diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 6b9f1559d37..95e9e8581bd 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -27,6 +27,7 @@ use trans::monomorphize; use trans::type_::Type; use trans::type_of::*; use trans::type_of; +use middle::infer; use middle::ty::{self, Ty}; use middle::subst::Substs; @@ -254,6 +255,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, _ => ccx.sess().bug("trans_native_call called on non-function type") }; let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig); + let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig); let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]); let fn_type = cabi::compute_abi_info(ccx, &llsig.llarg_tys, @@ -558,8 +560,6 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext, -> ValueRef { let _icx = push_ctxt("foreign::register_foreign_fn"); - let tys = foreign_types_for_id(ccx, node_id); - let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys); let t = ccx.tcx().node_id_to_type(node_id); let cconv = match t.sty { ty::TyBareFn(_, ref fn_ty) => { @@ -567,6 +567,8 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext, } _ => panic!("expected bare fn in register_rust_fn_with_foreign_abi") }; + let tys = foreign_types_for_fn_ty(ccx, t); + let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys); let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty); add_argument_attributes(&tys, llfn); debug!("register_rust_fn_with_foreign_abi(node_id={}, llfn_ty={}, llfn={})", @@ -937,11 +939,6 @@ fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -fn foreign_types_for_id<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - id: ast::NodeId) -> ForeignTypes<'tcx> { - foreign_types_for_fn_ty(ccx, ccx.tcx().node_id_to_type(id)) -} - fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> ForeignTypes<'tcx> { let fn_sig = match ty.sty { @@ -949,6 +946,7 @@ fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type") }; let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig); + let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig); let llsig = foreign_signature(ccx, &fn_sig, &fn_sig.inputs); let fn_ty = cabi::compute_abi_info(ccx, &llsig.llarg_tys, diff --git a/src/test/run-pass/issue-28983.rs b/src/test/run-pass/issue-28983.rs new file mode 100644 index 00000000000..658e9e14ee2 --- /dev/null +++ b/src/test/run-pass/issue-28983.rs @@ -0,0 +1,31 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Test { type T; } + +impl Test for u32 { + type T = i32; +} + +pub mod export { + #[no_mangle] + pub extern "C" fn issue_28983(t: ::T) -> i32 { t*3 } +} + +// to test both exporting and importing functions, import +// a function from ourselves. +extern "C" { + fn issue_28983(t: ::T) -> i32; +} + +fn main() { + assert_eq!(export::issue_28983(2), 6); + assert_eq!(unsafe { issue_28983(3) }, 9); +}