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 · Fixed by #34986
Closed
Assignees
Labels
P-medium Medium priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@KarboniteKream
Copy link

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(<[[email protected]: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
Copy link
Contributor

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

@arielb1 arielb1 added regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 19, 2016
@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
Copy link
Contributor

arielb1 commented Jun 19, 2016

cc @soltanmm

@pnkfelix pnkfelix added the P-medium Medium priority label Jun 23, 2016
@pnkfelix
Copy link
Member

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

@arielb1 arielb1 added regression-from-stable-to-beta Performance or correctness regression from stable to beta. and removed regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. labels Jul 7, 2016
@arielb1
Copy link
Contributor

arielb1 commented Jul 7, 2016

1.11 is now beta

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Jul 21, 2016

perhaps related to #33364? maybe not

@arielb1
Copy link
Contributor

arielb1 commented Jul 21, 2016

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

@nikomatsakis
Copy link
Contributor

@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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Jul 22, 2016
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
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
Copy link
Contributor

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
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?
alexcrichton pushed a commit to alexcrichton/rust that referenced this issue Aug 8, 2016
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
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
Labels
P-medium Medium priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants