Skip to content

Commit

Permalink
Revamp foreign code not to consider the Rust modes. This requires
Browse files Browse the repository at this point in the history
adjusting a few foreign functions that were declared with by-ref
mode.  This also allows us to remove by-val mode in the near future.

With copy mode, though, we have to be careful because Rust will implicitly pass
somethings by pointer but this may not be the C ABI rules.  For example, rust
will pass a struct Foo as a Foo*.  So I added some code into the adapters to
fix this (though the C ABI rules may put the pointer back, oh well).

This patch also includes a lint mode for the use of by-ref mode
in foreign functions as the semantics of this have changed.
  • Loading branch information
nikomatsakis committed Mar 13, 2013
1 parent 4d8ddff commit efc7f82
Show file tree
Hide file tree
Showing 18 changed files with 492 additions and 161 deletions.
4 changes: 2 additions & 2 deletions src/libcore/rt/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct Thread {
impl Thread {
static fn start(main: ~fn()) -> Thread {
fn substart(main: &fn()) -> *raw_thread {
unsafe { rust_raw_thread_start(main) }
unsafe { rust_raw_thread_start(&main) }
}
let raw = substart(main);
Thread {
Expand All @@ -39,6 +39,6 @@ impl Drop for Thread {
}

extern {
pub unsafe fn rust_raw_thread_start(f: &fn()) -> *raw_thread;
pub unsafe fn rust_raw_thread_start(f: &(&fn())) -> *raw_thread;
pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread);
}
4 changes: 2 additions & 2 deletions src/libcore/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mod rustrt {
pub unsafe fn rust_lock_little_lock(lock: rust_little_lock);
pub unsafe fn rust_unlock_little_lock(lock: rust_little_lock);

pub unsafe fn rust_raw_thread_start(f: &fn()) -> *raw_thread;
pub unsafe fn rust_raw_thread_start(f: &(&fn())) -> *raw_thread;
pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread);
}
}
Expand All @@ -72,7 +72,7 @@ pub fn run_in_bare_thread(f: ~fn()) {
let closure: &fn() = || {
f()
};
let thread = rustrt::rust_raw_thread_start(closure);
let thread = rustrt::rust_raw_thread_start(&closure);
rustrt::rust_raw_thread_join_delete(thread);
chan.send(());
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@ pub mod llvm {
/** Prepares inline assembly. */
pub unsafe fn LLVMInlineAsm(Ty: TypeRef, AsmString: *c_char,
Constraints: *c_char, SideEffects: Bool,
AlignStack: Bool, Dialect: AsmDialect)
AlignStack: Bool, Dialect: c_uint)
-> ValueRef;
}
}
Expand Down
24 changes: 23 additions & 1 deletion src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub enum lint {
deprecated_self,
deprecated_mutable_fields,
deprecated_drop,
foreign_mode,

managed_heap_memory,
owned_heap_memory,
Expand Down Expand Up @@ -182,6 +183,13 @@ pub fn get_lint_dict() -> LintDict {
default: warn
}),

(@~"foreign_mode",
@LintSpec {
lint: foreign_mode,
desc: "warn about deprecated uses of modes in foreign fns",
default: warn
}),

(@~"deprecated_pattern",
@LintSpec {
lint: deprecated_pattern,
Expand Down Expand Up @@ -753,6 +761,20 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {

fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
decl: &ast::fn_decl) {
// warn about `&&` mode on foreign functions, both because it is
// deprecated and because its semantics have changed recently:
for decl.inputs.eachi |i, arg| {
match ty::resolved_mode(cx, arg.mode) {
ast::by_val | ast::by_copy => {}
ast::by_ref => {
cx.sess.span_lint(
foreign_mode, fn_id, fn_id, arg.ty.span,
fmt!("foreign function uses `&&` mode \
on argument %u", i));
}
}
}

let tys = vec::map(decl.inputs, |a| a.ty );
for vec::each(vec::append_one(tys, decl.output)) |ty| {
match ty.node {
Expand Down Expand Up @@ -785,7 +807,7 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
if attr::foreign_abi(it.attrs) !=
either::Right(ast::foreign_abi_rust_intrinsic) => {
for nmod.items.each |ni| {
match /*bad*/copy ni.node {
match ni.node {
ast::foreign_item_fn(ref decl, _, _) => {
check_foreign_fn(cx, it.id, decl);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,

let llfty = T_fn(~[], T_void());
let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile,
alignstack, dia);
alignstack, dia as c_uint);

Call(cx, v, ~[])
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ pub fn trans_arg_expr(bcx: block,

if formal_ty.ty != arg_datum.ty {
// this could happen due to e.g. subtyping
let llformal_ty = type_of::type_of_explicit_arg(ccx, formal_ty);
let llformal_ty = type_of::type_of_explicit_arg(ccx, &formal_ty);
debug!("casting actual type (%s) to match formal (%s)",
bcx.val_str(val), bcx.llty_str(llformal_ty));
val = PointerCast(bcx, val, llformal_ty);
Expand Down
Loading

0 comments on commit efc7f82

Please sign in to comment.