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
This commit is contained in:
parent
843e528fd0
commit
bee664f9d0
@ -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,
|
||||
|
31
src/test/run-pass/issue-28983.rs
Normal file
31
src/test/run-pass/issue-28983.rs
Normal file
@ -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 <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.
|
||||
|
||||
trait Test { type T; }
|
||||
|
||||
impl Test for u32 {
|
||||
type T = i32;
|
||||
}
|
||||
|
||||
pub mod export {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn issue_28983(t: <u32 as ::Test>::T) -> i32 { t*3 }
|
||||
}
|
||||
|
||||
// to test both exporting and importing functions, import
|
||||
// a function from ourselves.
|
||||
extern "C" {
|
||||
fn issue_28983(t: <u32 as Test>::T) -> i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(export::issue_28983(2), 6);
|
||||
assert_eq!(unsafe { issue_28983(3) }, 9);
|
||||
}
|
Loading…
Reference in New Issue
Block a user