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

Rust requires size for struct parameterized by PhantomData #71788

Closed
iwahbe opened this issue May 2, 2020 · 2 comments
Closed

Rust requires size for struct parameterized by PhantomData #71788

iwahbe opened this issue May 2, 2020 · 2 comments
Labels
C-bug Category: This is a bug.

Comments

@iwahbe
Copy link
Contributor

iwahbe commented May 2, 2020

Rust requires size for structs parameterized with PhantomData.

I'm honestly not sure if this is a bug or type system limitation.

I tried this code: playground

trait Trait{
    fn func() -> Struct<Self>;    
}

struct Struct<T>{
    _t: std::marker::PhantomData<*const T>,
}

I expected to see this happen: Compilation complete. std::marker::PhantomData<*const T> is zero-size. And *const T is known size.

Instead, this happened: The build failed.

Meta

rustc --version --verbose:

rustc 1.44.0-nightly (94d346360 2020-04-09)
binary: rustc
commit-hash: 94d346360da50f159e0dc777dc9bc3c5b6b51a00
commit-date: 2020-04-09
host: x86_64-unknown-linux-gnu
release: 1.44.0-nightly
LLVM version: 9.0
Backtrace

  Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `Self` cannot be known at compilation time
 --> src/main.rs:6:18
  |
6 |     fn func() -> Struct<Self>;
  |                  ^^^^^^^^^^^^- help: consider further restricting `Self`: `where Self: std::marker::Sized`
  |                  |
  |                  doesn't have a size known at compile-time
...
9 | struct Struct<T> {
  |               - required by this bound in `Struct`
  |
  = help: the trait `std::marker::Sized` is not implemented for `Self`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

@iwahbe iwahbe added the C-bug Category: This is a bug. label May 2, 2020
@lcnr
Copy link
Contributor

lcnr commented May 2, 2020

Unlike structs, traits do not implicitly add a Sized bound.
This means that your snippet can be thought of as:

trait Trait: ?Sized {
    fn func() -> Struct<Self>;    
}

struct Struct<T: Sized>{
    _t: std::marker::PhantomData<*const T>,
}

Which must not compile.

You can fix this by either adding an explicit ?Sized bound to Struct or a Sized bound to Trait.
i.e.

trait Trait {
    fn func() -> Struct<Self>;    
}

struct Struct<T: ?Sized>{
    _t: std::marker::PhantomData<*const T>,
}

@jonas-schievink
Copy link
Contributor

Closing as expected behavior

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants