From 5f95fc1dff13b515f745be26062e9344403ee3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 25 Mar 2024 20:15:28 +0100 Subject: [PATCH] add test for Compiler panic using fn_traits #81974 Fixes https://github.com/rust-lang/rust/issues/81974 --- .../rust-call-abi-not-a-tuple-ice-81974.rs | 59 ++++++++++++++ ...rust-call-abi-not-a-tuple-ice-81974.stderr | 78 +++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs create mode 100644 tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs new file mode 100644 index 00000000000..6380449124f --- /dev/null +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs @@ -0,0 +1,59 @@ +// 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 { + cache: HashMap, + fun: fn(&mut CachedFun, A) -> B, +} + +impl CachedFun { + fn new(fun: fn(&mut Self, A) -> B) -> Self { + CachedFun { + cache: HashMap::new(), + fun, + } + } +} + +impl FnOnce for CachedFun +//~^ 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 FnMut for CachedFun +//~^ 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, x| x + 1; + let cachedcoso = CachedFun::new(pesce); + cachedcoso.call_once(1); + //~^ ERROR `i32` is not a tuple +} diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr new file mode 100644 index 00000000000..cceaddf7803 --- /dev/null +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -0,0 +1,78 @@ +error[E0059]: type parameter to bare `FnOnce` trait must be a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:24:12 + | +LL | impl FnOnce for CachedFun + | ^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | +note: required by a bound in `FnOnce` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0059]: type parameter to bare `FnMut` trait must be a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:38:12 + | +LL | impl FnMut for CachedFun + | ^^^^^^^^ the trait `Tuple` is not implemented for `A` + | +note: required by a bound in `FnMut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5 + | +LL | 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 + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:44:5 + | +LL | 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 + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: `A` is not a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:33:23 + | +LL | self.call_mut(a) + | -------- ^ the trait `Tuple` is not implemented for `A` + | | + | required by a bound introduced by this call + | +note: required by a bound in `call_mut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: `i32` is not a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:57:26 + | +LL | cachedcoso.call_once(1); + | --------- ^ the trait `Tuple` is not implemented for `i32` + | | + | required by a bound introduced by this call + | +note: required by a bound in `call_once` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0059, E0277. +For more information about an error, try `rustc --explain E0059`.