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

Compiler panic using fn_traits #81974

Closed
AlecsFerra opened this issue Feb 10, 2021 · 3 comments · Fixed by #123051
Closed

Compiler panic using fn_traits #81974

AlecsFerra opened this issue Feb 10, 2021 · 3 comments · Fixed by #123051
Labels
A-closures Area: Closures (`|…| { … }`) C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-unboxed_closures `#![feature(unboxed_closures)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@AlecsFerra
Copy link

Code

#![feature(unboxed_closures)]
#![feature(fn_traits)]

use std::collections::HashMap;
use std::hash::Hash;

struct CachedFun<A, B>{
  cache: HashMap<A, B>,
  fun: fn(&mut CachedFun<A, B>, A) -> B
}

impl<A: Eq + Hash, B> CachedFun<A, B> {
    fn new(fun: fn(&mut Self, A) -> B) -> Self {
        CachedFun {
            cache: HashMap::new(),
            fun
        }
    }
}

impl<A, B> FnOnce<A> for CachedFun<A, B> where
    A: Eq + Hash + Clone,
    B: Clone,
{
    type Output = B;
    extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
        self.call_mut(a)
    }
}


impl<A, B> FnMut<A> for CachedFun<A, B> where
    A: Eq + Hash + Clone,
    B: Clone,
{
    extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
        self.cache.get(&a)
            .map(|a| a.clone())
            .unwrap_or_else(|| {
                let b = (self.fun)(self, a.clone());
                self.cache.insert(a, b.clone());
                b
            })
    }
}

fn main() -> () {
    let pesce = |y: &mut CachedFun<i32, i32>, x| x + 1;
    let cachedcoso = CachedFun::new(pesce);
    cachedcoso.call_once(1);
}

playground

Meta

rustc --version --verbose:

 Build using the Nightly version: 1.52.0-nightly (2021-02-09 097bc6a84f2280a889b9)

Error output

error: internal compiler error: /rustc/097bc6a84f2280a889b9ab4b544f27851a978927/compiler/rustc_middle/src/ty/layout.rs:2693:21: argument to function with "rust-call" ABI is not a tuple

thread 'rustc' panicked at 'Box<Any>', /rustc/097bc6a84f2280a889b9ab4b544f27851a978927/library/std/src/panic.rs:59:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Note: I have the same issue even without a closure or by using the mut call

@AlecsFerra AlecsFerra added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 10, 2021
@jonas-schievink jonas-schievink added the requires-nightly This issue requires a nightly compiler in some way. label Feb 10, 2021
@CraftSpider
Copy link
Contributor

Note: This is a known issue with type-checking generic rust-call fns, I fixed this same issue for non-generic cases a bit ago. The reason I didn't fix it at the time is that as far as I could tell, the only way to fix this in the generic case would have been to add a new kind of WF predicate, for 'is a tuple', which was out of scope for my fix. There may be a better way to do this for someone more familiar with the obligation system.

Here's the place where type-checking should be happening but isn't:

// FIXME(CraftSpider) Add a check on parameter expansion, so we don't just make the ICE happen later on

@jonas-schievink
Copy link
Contributor

"rust-call" should just be removed in favor of lang items, I don't really see much value in fixing it since it only exists to make closures more efficient internally

@estebank estebank added A-closures Area: Closures (`|…| { … }`) F-unboxed_closures `#![feature(unboxed_closures)]` labels Feb 10, 2021
fanninpm added a commit to fanninpm/glacier that referenced this issue Feb 11, 2021
Most likely low-priority; feel free to ignore

Issue: rust-lang/rust#81974
@Dylan-DPC
Copy link
Member

This doesn't ICE any more and fails to compile with:

error[[E0059]](https://doc.rust-lang.org/nightly/error_codes/E0059.html): type parameter to bare `FnOnce` trait must be a tuple
  --> src/main.rs:21:12
   |
21 | impl<A, B> FnOnce<A> for CachedFun<A, B> where
   |            ^^^^^^^^^ the trait `Tuple` is not implemented for `A`
   |
note: required by a bound in `FnOnce`
  --> /rustc/39c6804b92aa202369e402525cee329556bc1db0/library/core/src/ops/function.rs:242:1
help: consider further restricting this bound
   |
22 |     A: Eq + Hash + Clone + std::marker::Tuple,
   |                          ++++++++++++++++++++

error[[E0059]](https://doc.rust-lang.org/nightly/error_codes/E0059.html): type parameter to bare `FnMut` trait must be a tuple
  --> src/main.rs:32:12
   |
32 | impl<A, B> FnMut<A> for CachedFun<A, B> where
   |            ^^^^^^^^ the trait `Tuple` is not implemented for `A`
   |
note: required by a bound in `FnMut`
  --> /rustc/39c6804b92aa202369e402525cee329556bc1db0/library/core/src/ops/function.rs:163:1
help: consider further restricting this bound
   |
33 |     A: Eq + Hash + Clone + std::marker::Tuple,
   |                          ++++++++++++++++++++

error[[E0277]](https://doc.rust-lang.org/nightly/error_codes/E0277.html): functions with the "rust-call" ABI must take a single non-self tuple argument
  --> src/main.rs:26:5
   |
26 |     extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
   |
help: consider further restricting this bound
   |
22 |     A: Eq + Hash + Clone + std::marker::Tuple,
   |                          ++++++++++++++++++++

error[[E0277]](https://doc.rust-lang.org/nightly/error_codes/E0277.html): functions with the "rust-call" ABI must take a single non-self tuple argument
  --> src/main.rs:36:5
   |
36 |     extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A`
   |
help: consider further restricting this bound
   |
33 |     A: Eq + Hash + Clone + std::marker::Tuple,
   |                          ++++++++++++++++++++

Some errors have detailed explanations: E0059, E0277.
For more information about an error, try `rustc --explain E0059`.

@cjgillot cjgillot added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Apr 30, 2023
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Mar 25, 2024
workingjubilee added a commit to workingjubilee/rustc that referenced this issue Mar 25, 2024
@bors bors closed this as completed in 5f95fc1 Mar 26, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Mar 26, 2024
Rollup merge of rust-lang#123051 - matthiaskrgr:casetest, r=workingjubilee

did I mention that tests are super cool?

Fixes rust-lang#81974
Fixes rust-lang#84727
Fixes rust-lang#92979
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-unboxed_closures `#![feature(unboxed_closures)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. 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.

6 participants