Skip to content
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

LLVM assertion when using move || { /* .. */ } #19141

Closed
japaric opened this issue Nov 20, 2014 · 0 comments · Fixed by #20244
Closed

LLVM assertion when using move || { /* .. */ } #19141

japaric opened this issue Nov 20, 2014 · 0 comments · Fixed by #20244
Labels
A-closures Area: Closures (`|…| { … }`) I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@japaric
Copy link
Member

japaric commented Nov 20, 2014

STR

fn main() {
    let n = 0u;

    let f = move || n += 1;
}

Output

rustc: /var/tmp/paludis/build/dev-lang-rust-scm/work/rust-scm/src/llvm/include/llvm/Support/Casting.h:237: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = llvm::PointerType; Y = llvm::Type; typename llvm::cast_retty<X, Y*>::ret_type = llvm::PointerType*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffeffff480 (LWP 12192)]
0x00007ffff6f638a7 in raise () from /lib64/libc.so.6
(gdb) backtrace
#0  0x00007ffff6f638a7 in raise () from /lib64/libc.so.6
#1  0x00007ffff6f64c3a in abort () from /lib64/libc.so.6
#2  0x00007ffff6f5c7fd in __assert_fail_base () from /lib64/libc.so.6
#3  0x00007ffff6f5c8b2 in __assert_fail () from /lib64/libc.so.6
#4  0x00007ffff261305c in ?? () from /usr/lib64/librustc_llvm-4e7c5e5c.so
#5  0x00007ffff33413ac in llvm::LoadInst::LoadInst(llvm::Value*, char const*, bool, llvm::Instruction*) () from /usr/lib64/librustc_llvm-4e7c5e5c.so
#6  0x00007ffff32a29bf in LLVMBuildLoad () from /usr/lib64/librustc_llvm-4e7c5e5c.so
#7  0x00007ffff7773334 in trans::builder::Builder$LT$$x27a$C$$x20$x27tcx$GT$::load::h3c2c0a39157367b2Gsr () from /usr/lib64/librustc_trans-4e7c5e5c.so
#8  0x00007ffff76f6f32 in trans::build::Load::hb999a33dee821b74Jnq () from /usr/lib64/librustc_trans-4e7c5e5c.so
#9  0x00007ffff772cc52 in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#10 0x00007ffff7720e0a in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#11 0x00007ffff76dd854 in trans::expr::trans_into::h7dc261a5d77d2dbciQh () from /usr/lib64/librustc_trans-4e7c5e5c.so
#12 0x00007ffff76ddadd in trans::controlflow::trans_block::h40e78d4cabd8c783p2d () from /usr/lib64/librustc_trans-4e7c5e5c.so
#13 0x00007ffff7790e50 in trans::base::trans_closure::h9baffc02e3bf0daf6Au () from /usr/lib64/librustc_trans-4e7c5e5c.so
#14 0x00007ffff7732f6e in trans::closure::trans_expr_fn::h04ecc83b7400adfaVWy () from /usr/lib64/librustc_trans-4e7c5e5c.so
#15 0x00007ffff771efca in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#16 0x00007ffff76dd746 in trans::expr::trans_into::h7dc261a5d77d2dbciQh () from /usr/lib64/librustc_trans-4e7c5e5c.so
#17 0x00007ffff77d64cd in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#18 0x00007ffff77d58b4 in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#19 0x00007ffff77881f4 in trans::_match::store_local::hdd8a0d2165cb659fx9x () from /usr/lib64/librustc_trans-4e7c5e5c.so
#20 0x00007ffff76dcd0e in trans::base::init_local::h0bd956a2c65b5d51NIt () from /usr/lib64/librustc_trans-4e7c5e5c.so
#21 0x00007ffff76dc332 in trans::controlflow::trans_stmt::h3a5fa88dc3d60c9fhXd () from /usr/lib64/librustc_trans-4e7c5e5c.so
#22 0x00007ffff76dd9d9 in trans::controlflow::trans_block::h40e78d4cabd8c783p2d () from /usr/lib64/librustc_trans-4e7c5e5c.so
#23 0x00007ffff7790e50 in trans::base::trans_closure::h9baffc02e3bf0daf6Au () from /usr/lib64/librustc_trans-4e7c5e5c.so
#24 0x00007ffff76d0a77 in trans::base::trans_fn::h114729a05667bb1dWMu () from /usr/lib64/librustc_trans-4e7c5e5c.so
#25 0x00007ffff76cdc8e in trans::base::trans_item::h7c2b438b1bce4863G8u () from /usr/lib64/librustc_trans-4e7c5e5c.so
#26 0x00007ffff779a408 in trans::base::trans_crate::he69e63600c94fe5506v () from /usr/lib64/librustc_trans-4e7c5e5c.so
#27 0x00007ffff7844945 in driver::driver::phase_4_translate_to_llvm::h81bcee50dff289e18oS () from /usr/lib64/librustc_trans-4e7c5e5c.so
#28 0x00007ffff7834105 in driver::driver::compile_input::h117f94c1b348a398YVR () from /usr/lib64/librustc_trans-4e7c5e5c.so
#29 0x00007ffff78b7cd7 in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#30 0x00007ffff78b62fc in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#31 0x00007ffff76c2f78 in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#32 0x00007ffff76c2e83 in ?? () from /usr/lib64/librustc_trans-4e7c5e5c.so
#33 0x00007ffff7bd6be2 in ?? () from /usr/lib64/libnative-4e7c5e5c.so
#34 0x00007ffff7390fec in ?? () from /usr/lib64/librustrt-4e7c5e5c.so
#35 0x00007ffff7390fd6 in rust_try () from /usr/lib64/librustrt-4e7c5e5c.so
#36 0x00007ffff733f843 in unwind::try::h03ead95328113b2fIZc () from /usr/lib64/librustrt-4e7c5e5c.so
#37 0x00007ffff733f70c in task::Task::run::hed7dc0cf620a0172y5b () from /usr/lib64/librustrt-4e7c5e5c.so
#38 0x00007ffff7bd69e7 in ?? () from /usr/lib64/libnative-4e7c5e5c.so
#39 0x00007ffff7340f35 in ?? () from /usr/lib64/librustrt-4e7c5e5c.so
#40 0x00007ffff1e0e294 in start_thread () from /lib64/libpthread.so.0
#41 0x00007ffff70181ed in clone () from /lib64/libc.so.6

Version

PR #19113 on top of 399ff25

It also fails in the playpen, which has version:

rustc 0.13.0-dev (8ed288edb 2014-11-06 16:52:09 +0000)

I think we're not supposed to use the move keyword with boxed closures?

@huonw huonw added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-closures Area: Closures (`|…| { … }`) labels Nov 25, 2014
japaric pushed a commit to japaric/rust that referenced this issue Dec 26, 2014
bors added a commit that referenced this issue Dec 27, 2014
closes #19141
closes #20193
closes #20228

---

Currently whenever we encounter `let f = || {/* */}`, we *always* type check the RHS as a *boxed* closure. This is wrong when the RHS is `move || {/* */}` (because boxed closures can't capture by value) and generates all sort of badness during trans (see issues above). What we *should* do is always type check `move || {/* */}` as an *unboxed* closure, but ~~I *think* (haven't tried)~~ (2) this is not feasible right now because we have a limited form of kind (`Fn` vs `FnMut` vs `FnOnce`) inference that only works when there is an expected type (1).

In this PR, I've chosen to generate a type error whenever `let f = move || {/* */}` is encountered. The error asks the user to annotate the kind of the unboxed closure (e.g. `move |:| {/* */}`). Once annotated, the compiler will type check the RHS as an unboxed closure which is what the user wants.

r? @nikomatsakis 

(1) AIUI it only triggers in this scenario:

``` rust
fn is_uc<F>(_: F) where F: FnOnce() {}

fn main() {
    is_uc(|| {});  // type checked as unboxed closure with kind `FnOnce`
}
```

(2) I checked, and it's not possible because `check_unboxed_closure` expects a `kind` argument, but we can't supply that argument in this case (i.e. `let f = || {}`, what's the kind?). We could force the `FnOnce` kind in that case, but that's ad hoc. We should try to infer the kind depending on how the closure is used afterwards, but there is no inference mechanism to do that (at least, not right now).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants