Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dyn Upcasting for unsized generics #119360

Closed
dhardy opened this issue Dec 27, 2023 · 3 comments
Closed

dyn Upcasting for unsized generics #119360

dhardy opened this issue Dec 27, 2023 · 3 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@dhardy
Copy link
Contributor

dhardy commented Dec 27, 2023

This fails:

#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
use std::any::Any;

fn box_to_any<T: Any + ?Sized>(x: Box<T>) -> Box<dyn Any>
where
    T: CoerceUnsized<dyn Any>,
{
    x as Box<dyn Any>
}

with:

error[E0277]: the size for values of type T cannot be known at compilation time

note: required for the cast from Box<T> to Box<(dyn Any + 'static)>

Dyn upcasting adds support for upcasting trait objects dyn A where A: Any to dyn Any, but not just any type (e.g. str cannot be cast to dyn Any).

For whatever reason, the bound T: Any + ?Sized is not enough to support the cast: [i32] implements Any (strange) yet cannot be cast to dyn Any (if it could this would break memory safety since the impl of Any returns a single TypeId for all [i32] regardless of length).

The additional T: CoerceUnsized<dyn Any> looks like it should be enough to satisfy the coercion in the method, yet it is not. It should be?

I guess this should be categorised as a bug in #18598, but it could be a bug in #65991 or even a feature request.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 27, 2023
@dhardy
Copy link
Contributor Author

dhardy commented Dec 27, 2023

Motivation

Enable Box::downcast to be generic over all types which can support it: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=863a1a05e024c3f2d73cba48690ae551. (This would of course be breaking and a separate issue/RFC. Just wanted to add for context.)

@compiler-errors
Copy link
Member

compiler-errors commented Dec 27, 2023

The correct bound is T: Unsize<dyn Any>. T: CoerceUnsized<U> does not imply Box<T>: CoerceUnsized<Box<U>>, and Box<T>: CoerceUnsized<Box<U>> is implemented only if T: Unsize<U>.

@dhardy
Copy link
Contributor Author

dhardy commented Dec 28, 2023

Thanks

@dhardy dhardy closed this as completed Dec 28, 2023
@saethlin saethlin added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Dec 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

4 participants