60 lines
1.5 KiB
Rust
60 lines
1.5 KiB
Rust
|
// ICE argument to function with "rust-call" ABI is not a tuple
|
||
|
// issue: rust-lang/rust#81974
|
||
|
|
||
|
#![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>
|
||
|
//~^ ERROR type parameter to bare `FnOnce` trait must be a tuple
|
||
|
where
|
||
|
A: Eq + Hash + Clone,
|
||
|
B: Clone,
|
||
|
{
|
||
|
type Output = B;
|
||
|
extern "rust-call" fn call_once(mut self, a: A) -> Self::Output {
|
||
|
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
|
||
|
self.call_mut(a)
|
||
|
//~^ ERROR `A` is not a tuple
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<A, B> FnMut<A> for CachedFun<A, B>
|
||
|
//~^ ERROR type parameter to bare `FnMut` trait must be a tuple
|
||
|
where
|
||
|
A: Eq + Hash + Clone,
|
||
|
B: Clone,
|
||
|
{
|
||
|
extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output {
|
||
|
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
|
||
|
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);
|
||
|
//~^ ERROR `i32` is not a tuple
|
||
|
}
|