I'm dealing with this code, but for simplicity, I'll go with the following code: Rust Playground
fn main() {
let mut f = match 1 {
1 => (1..10).into_iter().map(|x| x + 1),
2 => (1..10).into_iter().map(|x| x + 2),
_ => (1..10).into_iter().map(|x| x + 3),
};
dbg!(f.next());
}
This won't work since closures are distinct unnamed types. So we'll need dyn Trait to continue.
Plain dyn Trait
still won't work, since that type should be put behind a pointer type. [1]
- first try: borrowed dyn trait Rust Playground
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:4:19
|
3 | let mut f: &mut dyn Iterator<Item = i32> = match 1 {
| ________________________________________________-
4 | | 1 => &mut (1..10).into_iter().map(|x| x),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
| | creates a temporary value which is freed while still in use
5 | | 2 => &mut (1..10).into_iter().map(|x| x + 1),
6 | | _ => &mut (1..10).into_iter().map(|x| x + 2),
7 | | };
| |_____- borrow later used here
-
second try: owned type via Box Rust Playground , and it definitely works but overkills due to the cost of needless heap allocation.
-
third try: looking for crates that provide stacked allocation functionality, but Miri complains
// stack_dst = "0.7.2"
use stack_dst::ValueA;
fn main() {
type Dyn = ValueA<dyn Iterator<Item = i32>, [u64; 2]>;
let mut f = match 1 {
1 => Dyn::new_stable((1..10).map(|x| x), |p| p as _).unwrap(),
2 => Dyn::new_stable((1..10).map(|x| x + 1), |p| p as _).unwrap(),
_ => Dyn::new_stable((1..10).map(|x| x + 2), |p| p as _).unwrap(),
};
dbg!(f.next());
}
// works, but is detected as UB by Miri
error: Undefined Behavior: dereferencing pointer failed: 0x27f80[noalloc] is a dangling pointer (it has no provenance)
--> /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/stack_dst-0.7.2/src/value.rs:166:18
|
166 | unsafe { &mut *self.as_ptr() }
| ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x27f80[noalloc] is a dangling pointer (it has no provenance)
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `<stack_dst::ValueA<dyn std::iter::Iterator<Item = i32>, [u64; 2]> as std::ops::DerefMut>::deref_mut` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/stack_dst-0.7.
2/src/value.rs:166:18: 166:37
= note: inside `stack_dst::value::trait_impls::<impl std::iter::Iterator for stack_dst::ValueA<dyn std::iter::Iterator<Item = i32>, [u64; 2]>>::next` at /root/.cargo/registry/src/rsproxy.c
n-0dccff568467c15b/stack_dst-0.7.2/src/value/trait_impls.rs:25:9: 25:17
// smallbox = "0.8"
fn main() {
use smallbox::{smallbox, space::S2, SmallBox};
type Dyn = SmallBox<dyn Iterator<Item = i32>, S2>;
let mut f: Dyn = match 1 {
1 => smallbox!((1..10).map(|x| x)),
2 => smallbox!((1..10).map(|x| x + 1)),
_ => smallbox!((1..10).map(|x| x + 2)),
};
dbg!(f.next());
}
/// works, but is detected as UB by Miri
error: Undefined Behavior: dereferencing pointer failed: 0x26bd0[noalloc] is a dangling pointer (it has no provenance)
--> /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/smallbox-0.8.1/src/smallbox.rs:368:18
|
368 | unsafe { &mut *self.as_mut_ptr() }
| ^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x26bd0[noalloc] is a dangling pointer (it has no provenance)
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `<smallbox::SmallBox<dyn std::iter::Iterator<Item = i32>, smallbox::space::S2> as std::ops::DerefMut>::deref_mut` at /root/.cargo/registry/src/rsproxy.cn-0dccff568467c15b/sm
allbox-0.8.1/src/smallbox.rs:368:18: 368:41
-
Will
dyn* Trait
, the kinda like owned pointer type, solve this? ↩︎