The following code prevents mem::MaybeUninit and mem::transmute from creating values.
trait Ty<'a> {
type V;
}
trait SIter: for<'a> Ty<'a> {
fn f<F>(&self, f: F)
where
F: for<'r> Fn(<Self as Ty<'r>>::V);
}
struct S<I>(I);
impl<'a, I: Ty<'a>> Ty<'a> for S<I> {
type V = <I as Ty<'a>>::V;
}
trait Is<'a> {
type V;
}
impl<'a, T> Is<'a> for T {
type V = T;
}
impl<I: SIter, Item> SIter for S<I>
where
// for<'r> Self: Ty<'r, V = <I as Ty<'r>>::V>,
for<'r> S<I>: Ty<'r, V = Item>,
for<'r> I: Ty<'r, V = Item>,
// for<'r> <Self as Ty<'r>>::V: Is<'r, V = <I as Ty<'r>>::V>,
{
fn f<F>(&self, f: F)
where
F: Fn(<Self as Ty>::V),
{
self.0.f(|item| unsafe {
// let item: <Self as Ty>::V = std::mem::transmute_copy(&item);
let item: <Self as Ty>::V = std::mem::MaybeUninit::uninit().assume_init();
// let item: <Self as Ty>::V = loop {};
f(item)
})
}
}
(Playground)
Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/lib.rs:40:15
|
40 | f(item)
| ^^^^ expected associated type, found type parameter
|
= note: expected type `<S<I> as Ty<'_>>::V`
found type `Item`
error[E0277]: expected a `std::ops::Fn<(Item,)>` closure, found `F`
--> src/lib.rs:40:13
|
40 | f(item)
| ^^^^^^^ expected an `Fn<(Item,)>` closure, found `F`
|
= help: the trait `std::ops::Fn<(Item,)>` is not implemented for `F`
= help: consider adding a `where F: std::ops::Fn<(Item,)>` bound
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
The code works fine without any unsafe if I remove all lifetimes from it.
trait Ty {
type V;
}
trait SIter: Ty {
fn f<F>(&self, f: F)
where
F: Fn(<Self as Ty>::V);
}
struct S<I>(I);
impl<I: Ty> Ty for S<I> {
type V = <I as Ty>::V;
}
// trait Is<'a> {
// type V;
// }
// impl<'a, T> Is<'a> for T {
// type V = T;
// }
impl<I: SIter> SIter for S<I>
where
// for<'r> Self: Ty<'r, V = <I as Ty<'r>>::V>,
// for<'r> S<I>: Ty<'r, V = Item>,
// for<'r> I: Ty<'r, V = Item>,
// for<'r> <Self as Ty<'r>>::V: Is<'r, V = <I as Ty<'r>>::V>,
{
fn f<F>(&self, f: F)
where
F: Fn(<Self as Ty>::V),
{
self.0.f(|item| unsafe {
// let item: <Self as Ty>::V = std::mem::transmute_copy(&item);
// let item: <Self as Ty>::V = std::mem::MaybeUninit::uninit().assume_init();
// let item: <Self as Ty>::V = loop {};
f(item)
})
}
}
(Playground)
The following code prevents
mem::MaybeUninitandmem::transmutefrom creating values.(Playground)
Errors:
The code works fine without any unsafe if I remove all lifetimes from it.
(Playground)