Skip to content

Trait upcasting support incomplete in ?Sized contexts #139808

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

Closed
gslancaster opened this issue Apr 14, 2025 · 2 comments
Closed

Trait upcasting support incomplete in ?Sized contexts #139808

gslancaster opened this issue Apr 14, 2025 · 2 comments

Comments

@gslancaster
Copy link

I tried this code (brief version):

trait Foo {
    fn trait_obj(&self) -> &dyn Foo {
        self // E0277 here
    }
}

I expected this code to compile with Rust 1.86, given the new upcasting support.

Instead, the compiler gives E0277.

Why should this code now work? Self must be either:

  • A (Sized) concrete type implementing Foo, or
  • A (!Sized) trait object type of Foo or some subtrait thereof.

In either case, it should now be possible to cast to a Foo trait object, but the compiler is not allowing it yet. It's
like some part of the upcasting support is missing.

The problem occurs with stable 1.86. As of time of writing, the problem still occurs with nightly (1.88).

Another, more verbose, example, showing the same issue in a generic context, with explanatory comments:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7e2e4ee0e645105cbff33fa49d317a8d

@gslancaster gslancaster added the C-bug Category: This is a bug. label Apr 14, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 14, 2025
@compiler-errors
Copy link
Member

Why should this code now work? Self must be either:

  • A (Sized) concrete type implementing Foo, or
  • A (!Sized) trait object type of Foo or some subtrait thereof.

This is not a bug. You may implement Foo for [T] (or some unsized struct type), for example, in which case it cannot be unsized into dyn Foo.

@gslancaster
Copy link
Author

gslancaster commented Apr 14, 2025

I think I understand: not all !Sized types are trait objects, so there is a 3rd case, where trait upcasting does not work.

To code up your counter-example:

trait Foo {
    fn trait_obj(&self) -> &dyn Foo;
}

impl<T> Foo for [T] {
    fn trait_obj(&self) -> &dyn Foo {
        self // E0277 here now
    }    
}

I wish I knew how to say in Rust that a (Self or generic) type is either Sized or a trait object, thus will work with the new trait upcasting -- it would make the feature significantly more usable for me.

Anyway, this is moving it away from a bug report into a more general discussion, which is not appropriate, so I will close it there.

@jieyouxu jieyouxu removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants