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

Encountered error `Unimplemented` selecting `Binder(<[closure ...] as Fn()>)` during trans #34349

Closed
KarboniteKream opened this Issue Jun 18, 2016 · 12 comments

Comments

Projects
None yet
5 participants
@KarboniteKream
Copy link

KarboniteKream commented Jun 18, 2016

I was going over the examples on Rust by Example (section 8.2.2) when I encountered the following error:
Encountered error 'Unimplemented' selecting 'Binder(<[closure@bug.rs:11:17: 14:6 farewell:&mut std::string::String] as std::ops::Fn<()>>)' during trans.

In the apply() function, if I replace Fn() with FnMut() or FnOnce(), the code works (with FnMut() it fails of course), but if I keep Fn(), the compiler panics.

If I remove the inc() call, the compiler also doesn't panic.

Source code
fn main() {
    let inc = || {};
    inc();

    fn apply<F>(f: F) where F: Fn() {
        f()
    }

    let mut farewell = "goodbye".to_owned();
    let diary = || {
        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
    };

    apply(diary);
}
Stack trace
thread 'rustc' panicked at 'Box<Any>', src/libsyntax/errors/mod.rs:545
stack backtrace:
   1:     0x7f7a1327724f - <unknown>
   2:     0x7f7a13284e3b - <unknown>
   3:     0x7f7a132849d8 - <unknown>
   4:     0x7f7a1324ad9e - std::panicking::rust_panic_with_hook::h5fd54c69674f2610
   5:     0x7f7a10c81288 - <unknown>
   6:     0x7f7a10c810f5 - <unknown>
   7:     0x7f7a10c80ebf - <unknown>
   8:     0x7f7a10d225ac - <unknown>
   9:     0x7f7a10c94848 - <unknown>
  10:     0x7f7a10d168ae - _<rustc_trans..collector..MirNeighborCollector<'a, 'tcx> as rustc..mir..visit..Visitor<'tcx>>::visit_operand::h2cab09bf7cc9d690
  11:     0x7f7a10d14866 - _<rustc_trans..collector..MirNeighborCollector<'a, 'tcx> as rustc..mir..visit..Visitor<'tcx>>::visit_terminator_kind::h209a1accd24a8c16
  12:     0x7f7a10d13010 - <unknown>
  13:     0x7f7a10d0c95a - <unknown>
  14:     0x7f7a10d0d696 - <unknown>
  15:     0x7f7a10cd2a33 - <unknown>
  16:     0x7f7a10cbf9f9 - rustc_trans::base::trans_crate::hca67d2711539a441
  17:     0x7f7a137be6ff - rustc_driver::driver::phase_4_translate_to_llvm::h5f028163cc963293
  18:     0x7f7a137bc58d - <unknown>
  19:     0x7f7a137b8ced - <unknown>
  20:     0x7f7a137b24b9 - <unknown>
  21:     0x7f7a1377b8af - rustc_driver::driver::compile_input::h5e5e4501615d7d4b
  22:     0x7f7a137678a4 - rustc_driver::run_compiler::h9bfe8b5b10d5224d
  23:     0x7f7a1376497e - <unknown>
  24:     0x7f7a1329493b - <unknown>
  25:     0x7f7a132948de - __rust_maybe_catch_panic
  26:     0x7f7a13765464 - <unknown>
  27:     0x7f7a13282f64 - <unknown>
  28:     0x7f7a0bd10473 - start_thread
  29:     0x7f7a12ed169c - clone
  30:                0x0 - <unknown>
Version

rustc 1.11.0-nightly (5c2a5d4 2016-06-11)
binary: rustc
commit-hash: 5c2a5d4
commit-date: 2016-06-11
host: x86_64-pc-windows-gnu
release: 1.11.0-nightly

The same problem occurs on Linux, also Nightly.

@eefriedman

This comment has been minimized.

Copy link
Contributor

eefriedman commented Jun 18, 2016

Looks like a regression; 1.9 outputs the correct "trait bound is not satisfied" error.

@arielb1 arielb1 changed the title Encountered error `Unimplemented` selecting `Binder(...)` during trans Encountered error `Unimplemented` selecting `Binder(<[closure ...] as Fn()>)` during trans Jun 19, 2016

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jun 19, 2016

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Jun 23, 2016

assigning P-medium to keep it out of brson's sight

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 7, 2016

1.11 is now beta

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 21, 2016

perhaps related to #33364? maybe not

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 21, 2016

The issue is that upvar inference mutates the closure_kinds map while calling trait selection.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 22, 2016

@arielb1 so I looked into this some. Is the problem related to caching? That is, we solve the trait once with closure_kinds set to Fn, and then cache the result?

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 22, 2016

Because basically I think things are largely working as they are supposed to -- and an error would be expected, except that I think a cache is kicking in. Disabling caching for these sorts of predicates would probably fix the problem (I'll try it), though of course it'd be nice in a way if we could surface the closure kind up into the key (not sure how that would work though).

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 22, 2016

OK, I have a simple patch that fixes this. It moves the computation of the closure-kind into a temporary table; the final results are copied into the main table only when done. The result is that the ClosureKind obligation is not resolved until the final results are available, as expected.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 22, 2016

Doing final testing now, hopefully have a PR up soon.

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Jul 22, 2016

Avoid writing a temporary closure kind
We used to write a temporary closure kind into the inference table, but
this could lead to obligations being incorrectled resolved before
inference had completed. This result could then be cached, leading to
further trouble. This patch avoids writing any closure kind until the
computation is complete.

Fixes rust-lang#34349.

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Jul 22, 2016

Avoid writing a temporary closure kind
We used to write a temporary closure kind into the inference table, but
this could lead to obligations being incorrectled resolved before
inference had completed. This result could then be cached, leading to
further trouble. This patch avoids writing any closure kind until the
computation is complete.

Fixes rust-lang#34349.
@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 23, 2016

@nikomatsakis

Last time I checked the problem wasn't caching, but that the "[closure ...]: Fn" obligation, left over from type-checking, was incorrectly marked as resolved.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 26, 2016

Last time I checked the problem wasn't caching, but that the "[closure ...]: Fn" obligation, left over from type-checking, was incorrectly marked as resolved.

That is what I meant by caching, basically.

bors added a commit that referenced this issue Jul 31, 2016

Auto merge of #34986 - nikomatsakis:issue-34349, r=arielb1
Avoid writing a temporary closure kind

We used to write a temporary closure kind into the inference table, but
this could lead to obligations being incorrectled resolved before
inference had completed. This result could then be cached, leading to
further trouble. This patch avoids writing any closure kind until the
computation is complete.

Fixes #34349.

r? @arielb1 -- what do you think?

@bors bors closed this in #34986 Jul 31, 2016

alexcrichton added a commit to alexcrichton/rust that referenced this issue Aug 8, 2016

Avoid writing a temporary closure kind
We used to write a temporary closure kind into the inference table, but
this could lead to obligations being incorrectled resolved before
inference had completed. This result could then be cached, leading to
further trouble. This patch avoids writing any closure kind until the
computation is complete.

Fixes rust-lang#34349.

pmatos pushed a commit to LinkiTools/rust that referenced this issue Sep 27, 2016

Avoid writing a temporary closure kind
We used to write a temporary closure kind into the inference table, but
this could lead to obligations being incorrectled resolved before
inference had completed. This result could then be cached, leading to
further trouble. This patch avoids writing any closure kind until the
computation is complete.

Fixes rust-lang#34349.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.