Custom pointer and unsized types
⚓ Rust 📅 2025-09-28 👤 surdeus 👁️ 13I need a smart pointer type that is basically a wrapper around Rc. Trying to make it work with unsized types I came across the following problem (Playground):
use std::rc::Rc;
struct Ptr<T: ?Sized>(Rc<T>);
impl<T: ?Sized> Ptr<T> {
fn new(value: T) -> Self
where
T: Sized,
{
Self(Rc::new(value))
}
// Workaround for the lack of CoerceUnsized in stable rust.
fn into_unsized<U>(self) -> Ptr<U>
where
U: ?Sized,
Rc<T>: MyCoerceUnsized<U>,
{
Ptr(self.0.coerce())
}
}
trait MyCoerceUnsized<U: ?Sized>: Sized {
fn coerce(self) -> Rc<U>;
}
impl<A1, A2, R, F> MyCoerceUnsized<dyn Fn(A1, A2) -> R> for Rc<F>
where
F: 'static + Fn(A1, A2) -> R,
{
fn coerce(self) -> Rc<dyn Fn(A1, A2) -> R> {
self
}
}
fn tst1<F: 'static + Fn(&mut i32, &mut i32)>(f: F) -> Ptr<dyn Fn(&mut i32, &mut i32)> {
// Error:
// expected struct `Ptr<dyn for<'a, 'b> Fn(&'a mut i32, &'b mut i32)>`
// found struct `Ptr<dyn Fn(&mut i32, &mut i32)>`
Ptr::new(f).into_unsized()
}
// This fails too.
fn tst2<F: 'static + for<'a, 'b> Fn(&'a mut i32, &'b mut i32)>(
f: F,
) -> Ptr<dyn Fn(&mut i32, &mut i32)> {
Ptr::new(f).into_unsized()
}
// And so does this.
fn tst3<F: 'static + for<'a, 'b> Fn(&'a mut i32, &'b mut i32)>(
f: F,
) -> Ptr<dyn for<'a, 'b> Fn(&mut i32, &mut i32)> {
Ptr::new(f).into_unsized()
}
// This works.
fn tst4<F: 'static + Fn(i32, i32)>(f: F) -> Ptr<dyn Fn(i32, i32)> {
Ptr::new(f).into_unsized()
}
Am I missing something or is it a compiler bug?
2 posts - 2 participants
🏷️ Rust_feed