Skip to content

Lift restriction on calling extern C functions, and propagate ABI as part of extern fn type #5759

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -1311,19 +1311,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
// Extract the function signature from `in_fty`.
let fn_sty = structure_of(fcx, f.span, fn_ty);

// FIXME(#3678) For now, do not permit calls to C abi functions.
match fn_sty {
ty::ty_bare_fn(ty::BareFnTy {abis, _}) => {
if !abis.is_rust() {
fcx.tcx().sess.span_err(
call_expr.span,
fmt!("Calls to C ABI functions are not (yet) \
supported; be patient, dear user"));
}
}
_ => {}
}

let fn_sig = match fn_sty {
ty::ty_bare_fn(ty::BareFnTy {sig: sig, _}) |
ty::ty_closure(ty::ClosureTy {sig: sig, _}) => sig,
@@ -3607,7 +3594,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
};
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::unsafe_fn,
abis: AbiSet::Rust(),
abis: AbiSet::Intrinsic(),
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: inputs,
output: output}
33 changes: 25 additions & 8 deletions src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
@@ -134,8 +134,8 @@ impl AstConv for CrateCtxt {
Some(&ast_map::node_item(item, _)) => {
ty_of_item(self, item)
}
Some(&ast_map::node_foreign_item(foreign_item, _, _, _)) => {
ty_of_foreign_item(self, foreign_item)
Some(&ast_map::node_foreign_item(foreign_item, abis, _, _)) => {
ty_of_foreign_item(self, foreign_item, abis)
}
ref x => {
self.tcx.sess.bug(fmt!("unexpected sort of item \
@@ -932,7 +932,20 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: @ast::foreign_item) {
// As above, this call populates the type table with the converted
// type of the foreign item. We simply write it into the node type
// table.
let tpt = ty_of_foreign_item(ccx, i);

// For reasons I cannot fully articulate, I do so hate the AST
// map, and I regard each time that I use it as a personal and
// moral failing, but at the moment it seems like the only
// convenient way to extract the ABI. - ndm
let abis = match ccx.tcx.items.find(&i.id) {
Some(&ast_map::node_foreign_item(_, abis, _, _)) => abis,
ref x => {
ccx.tcx.sess.bug(fmt!("unexpected sort of item \
in get_item_ty(): %?", (*x)));
}
};

let tpt = ty_of_foreign_item(ccx, i, abis);
write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
ccx.tcx.tcache.insert(local_def(i.id), tpt);
}
@@ -1103,14 +1116,17 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
}
}

pub fn ty_of_foreign_item(ccx: &CrateCtxt, it: @ast::foreign_item)
-> ty::ty_param_bounds_and_ty {
pub fn ty_of_foreign_item(ccx: &CrateCtxt,
it: @ast::foreign_item,
abis: AbiSet) -> ty::ty_param_bounds_and_ty
{
match it.node {
ast::foreign_item_fn(ref fn_decl, _, ref generics) => {
ty_of_foreign_fn_decl(ccx,
fn_decl,
local_def(it.id),
generics)
generics,
abis)
}
ast::foreign_item_const(t) => {
ty::ty_param_bounds_and_ty {
@@ -1197,7 +1213,8 @@ pub fn ty_generics(ccx: &CrateCtxt,
pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
decl: &ast::fn_decl,
def_id: ast::def_id,
ast_generics: &ast::Generics)
ast_generics: &ast::Generics,
abis: AbiSet)
-> ty::ty_param_bounds_and_ty {
let ty_generics = ty_generics(ccx, None, ast_generics, 0);
let region_param_names = RegionParamNames::from_generics(ast_generics);
@@ -1208,7 +1225,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
let t_fn = ty::mk_bare_fn(
ccx.tcx,
ty::BareFnTy {
abis: AbiSet::Rust(),
abis: abis,
purity: ast::unsafe_fn,
sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: input_tys,