From bee664f9d0135c1e5125b5d80f44bed5d29a4584 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 12 Oct 2015 21:50:57 +0300 Subject: [PATCH] normalize the types of foreign functions This is needed as item types are allowed to be unnormalized. Fixes an ICE that occurs when foreign function signatures contained an associated type. Fixes #28983 --- src/librustc_trans/trans/foreign.rs | 12 +++++------ src/test/run-pass/issue-28983.rs | 31 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/issue-28983.rs diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 6b9f1559d3793..95e9e8581bd61 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 0000000000000..658e9e14ee2e0 --- /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); +}