Skip to content

Commit

Permalink
Auto merge of #29001 - arielb1:normalized-foreign, r=eddyb
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Oct 14, 2015
2 parents b28a550 + bee664f commit 18268bf
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
12 changes: 5 additions & 7 deletions src/librustc_trans/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -558,15 +560,15 @@ 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) => {
llvm_calling_convention(ccx, fn_ty.abi)
}
_ => 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={})",
Expand Down Expand Up @@ -937,18 +939,14 @@ 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 {
ty::TyBareFn(_, ref fn_ty) => &fn_ty.sig,
_ => 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,
Expand Down
31 changes: 31 additions & 0 deletions src/test/run-pass/issue-28983.rs
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 18268bf

Please sign in to comment.