Skip to content

Commit bee664f

Browse files
committed
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
1 parent 843e528 commit bee664f

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/librustc_trans/trans/foreign.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use trans::monomorphize;
2727
use trans::type_::Type;
2828
use trans::type_of::*;
2929
use trans::type_of;
30+
use middle::infer;
3031
use middle::ty::{self, Ty};
3132
use middle::subst::Substs;
3233

@@ -254,6 +255,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
254255
_ => ccx.sess().bug("trans_native_call called on non-function type")
255256
};
256257
let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
258+
let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);
257259
let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]);
258260
let fn_type = cabi::compute_abi_info(ccx,
259261
&llsig.llarg_tys,
@@ -558,15 +560,15 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
558560
-> ValueRef {
559561
let _icx = push_ctxt("foreign::register_foreign_fn");
560562

561-
let tys = foreign_types_for_id(ccx, node_id);
562-
let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
563563
let t = ccx.tcx().node_id_to_type(node_id);
564564
let cconv = match t.sty {
565565
ty::TyBareFn(_, ref fn_ty) => {
566566
llvm_calling_convention(ccx, fn_ty.abi)
567567
}
568568
_ => panic!("expected bare fn in register_rust_fn_with_foreign_abi")
569569
};
570+
let tys = foreign_types_for_fn_ty(ccx, t);
571+
let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
570572
let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
571573
add_argument_attributes(&tys, llfn);
572574
debug!("register_rust_fn_with_foreign_abi(node_id={}, llfn_ty={}, llfn={})",
@@ -937,18 +939,14 @@ fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
937939
}
938940
}
939941

940-
fn foreign_types_for_id<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
941-
id: ast::NodeId) -> ForeignTypes<'tcx> {
942-
foreign_types_for_fn_ty(ccx, ccx.tcx().node_id_to_type(id))
943-
}
944-
945942
fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
946943
ty: Ty<'tcx>) -> ForeignTypes<'tcx> {
947944
let fn_sig = match ty.sty {
948945
ty::TyBareFn(_, ref fn_ty) => &fn_ty.sig,
949946
_ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type")
950947
};
951948
let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
949+
let fn_sig = infer::normalize_associated_type(ccx.tcx(), &fn_sig);
952950
let llsig = foreign_signature(ccx, &fn_sig, &fn_sig.inputs);
953951
let fn_ty = cabi::compute_abi_info(ccx,
954952
&llsig.llarg_tys,

src/test/run-pass/issue-28983.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Test { type T; }
12+
13+
impl Test for u32 {
14+
type T = i32;
15+
}
16+
17+
pub mod export {
18+
#[no_mangle]
19+
pub extern "C" fn issue_28983(t: <u32 as ::Test>::T) -> i32 { t*3 }
20+
}
21+
22+
// to test both exporting and importing functions, import
23+
// a function from ourselves.
24+
extern "C" {
25+
fn issue_28983(t: <u32 as Test>::T) -> i32;
26+
}
27+
28+
fn main() {
29+
assert_eq!(export::issue_28983(2), 6);
30+
assert_eq!(unsafe { issue_28983(3) }, 9);
31+
}

0 commit comments

Comments
 (0)