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

where Self: Sized on trait method doesn't work as expected when implementing for unsized types. #57900

Open
crlf0710 opened this issue Jan 25, 2019 · 7 comments
Labels
A-traits Area: Trait system A-typesystem Area: The type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@crlf0710
Copy link
Member

I've got this code

trait Foo {
    fn bar(&self) -> Self where Self: Sized;
}

impl Foo for str {
//    fn bar(&self) -> Self { unimplemented!() }
}

the error is:

error[E0046]: not all trait items implemented, missing: `bar`
 --> src/lib.rs:5:1

However, since str is not Sized, i don't think bar needs to be implemented. if i remove the "//", i'll got:

error[E0277]: the size for values of type `str` cannot be known at compilation time
 --> src/lib.rs:6:22

So although this trait fits object safety rules, i still can't implement it for unsized types.

@Centril Centril added the A-typesystem Area: The type system label Jan 25, 2019
@RustyYato
Copy link
Contributor

As a work around, you can split off everything that needs Sized into another trait. like so

trait ObjectSafe {
    // some functions
}
trait NotObjectSafe: ObjectSafe + Sized {
    // more functions
}

@crlf0710
Copy link
Member Author

Yes, i think this is a reasonable workaround. But it will be nice to get this limitation removed

@RustyYato
Copy link
Contributor

Yes, I agree, this is an annoying limitation.

@crlf0710
Copy link
Member Author

@rustbot modify labels to +A-traits +C-bug

@rustbot rustbot added A-traits Area: Trait system C-bug Category: This is a bug. labels Dec 24, 2019
@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Mar 2, 2020
@QuineDot
Copy link

QuineDot commented May 7, 2022

The original example can be worked around with the trivial bounds RFC (you still cannot call the implementation).

That said, I still feel that the approximation of using Sized instead of some NotDyn trait should be fixed; said trait could be a supertrait of Sized for backwards compatibility. The reason (well, beyond semantics) being, sometimes you do want to call some generic method on a str implementation (imagine the method was -> () in the example).

@kupiakos
Copy link
Contributor

kupiakos commented Jun 8, 2022

For reference, you can also work around this on stable with an unused HRTB:

trait Foo {
    fn bar(&self) -> Self where Self: Sized;
}

impl Foo for str {
    fn bar(&self) -> Self where for<'a> str: Sized { unimplemented!() }
}

@crlf0710 crlf0710 added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Jun 13, 2022
@grothesque
Copy link

grothesque commented Nov 30, 2023

@QuineDot wrote:

That said, I still feel that the approximation of using Sized instead of some NotDyn trait should be fixed; said trait could be a supertrait of Sized for backwards compatibility. The reason (well, beyond semantics) being, sometimes you do want to call some generic method on a str implementation (imagine the method was -> () in the example).

Perhaps this approximation is not a huge problem in practice when using the language, but in my experience it can be a big problem when learning about trait objects in Rust. It was one of the big blockers for me.

Although I read all the available official documentation (and many other texts) on trait objects and object safety, I kept being fundamentally confused about the relation of Self: Sized and trait objects. It's not like I did not understand why and how trait objects are unsized, but rather that I had the feeling that requiring Self: Sized is too strong when all one wants is excluding trait objects. However, since this point was never discussed, I thought that it is my understanding that must be flawed.

It's only once I found @QuineDot's analysis that my doubts disappeared and I realized that my understanding was actually correct. (Thanks!)

I assume that I am not the first or last to suffer from this difficulty, and suggest tackling it in some way. One could start by adding clarification to the definition of object safety.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system A-typesystem Area: The type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants