Skip to content

Rust requires size for struct parameterized by PhantomData #71788

@iwahbe

Description

@iwahbe
Contributor

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.

Activity

lcnr

lcnr commented on May 2, 2020

@lcnr
Contributor

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

jonas-schievink commented on May 2, 2020

@jonas-schievink
Contributor

Closing as expected behavior

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jonas-schievink@iwahbe@lcnr

        Issue actions

          Rust requires size for struct parameterized by PhantomData · Issue #71788 · rust-lang/rust