Change:
Repro: ICE:
tracks a number of cases that throw the same error.
A couple of hints - it looks like it happens when structure size is actually smaller or equal to register of architecture. I had the similar report for failing on iOS with the following sample: It fails on and if + <= 64 bits, i.e. they are u16 or u32. When switching to armv7 it fails if + <= 32 bits
after 6 hours bisecting the verdict is - , part of
sigh I actually saw that when I was working on but didn't come up with a test case that would trigger a problem here and then forgot about it. Will look into this.
will fix hit the upcoming beta?
Sorry, fixing a few regressions in LLVM that affected rust had higher priority for me than this issue (because LLVM is very close to its 3.6 release), so I couldn't devote much time to this issue yet. But given that the beta is still ~3 weeks away, I'm positive that I'll get around to have it fixed by then.
Hmm, beta is on week of Feb 16 (i.e. next week), isn't it?
Yes. Although, as someone hitting that bug, I'd be okay if that were flagged as a known bug and would prefer if semantic issues were cared about first.
I have nothing against fixing regressions, still be extremely happy to see it fixed as I will be stuck on beta1 following 6 weeks till beta2 or rc1.
:tada: thanks a lot!

Discussion:
} }; <ins> let rustfn_ty = Type::from_ref(llvm::LLVMTypeOf(llrustfn)).element_type(); let mut rust_param_tys = rustfn_ty.func_params().into_iter(); </ins> // Push Rust return pointer, using null if it will be unused. let rust_uses_outptr = match tys.fn_sig.output { ty::FnConverging(ret_ty) => type_of::return_uses_outptr(ccx, ret_ty), ty::FnDiverging => false }; let return_alloca: Option<ValueRef>; <del> let llrust_ret_ty = tys.llsig.llret_ty; let llrust_retptr_ty = llrust_ret_ty.ptr_to(); </del> <ins> let llrust_ret_ty = if rust_uses_outptr { rust_param_tys.next().expect("Missing return type!").element_type() } else { rustfn_ty.return_type() }; </ins> if rust_uses_outptr { // Rust expects to use an outpointer. If the foreign fn // also uses an outpointer, we can reuse it, but the types

debug!("out pointer, foreign={}", ccx.tn().val_to_string(llforeign_outptr)); let llrust_retptr = <del> builder.bitcast(llforeign_outptr, llrust_retptr_ty); </del> <ins> builder.bitcast(llforeign_outptr, llrust_ret_ty.ptr_to()); </ins> debug!("out pointer, foreign={} (casted)", ccx.tn().val_to_string(llrust_retptr)); llrust_args.push(llrust_retptr);

// a pointer and Rust does not or vice versa. for i in 0..tys.fn_sig.inputs.len() { let rust_ty = tys.fn_sig.inputs[i]; <del> let llrust_ty = tys.llsig.llarg_tys[i]; </del> let rust_indirect = type_of::arg_is_indirect(ccx, rust_ty); <ins> let llty = rust_param_tys.next().expect("Not enough parameter types!"); let llrust_ty = if rust_indirect { llty.element_type() } else { llty }; </ins> let llforeign_arg_ty = tys.fn_ty.arg_tys[i]; let foreign_indirect = llforeign_arg_ty.is_indirect();

// Foreign ABI requires an out pointer, but Rust doesn't. // Store Rust return value. let llforeign_outptr_casted = <del> builder.bitcast(llforeign_outptr, llrust_retptr_ty); </del> <ins> builder.bitcast(llforeign_outptr, llrust_ret_ty.ptr_to()); </ins> builder.store(llrust_ret_val, llforeign_outptr_casted); builder.ret_void(); }

<ins> // 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. #[repr(C)] pub struct Foo(u32); // ICE trigger, bad handling of differing types between rust and external ABIs pub extern fn bar() -> Foo { Foo(0) } fn main() {} </ins>