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 doesn't know type is sized #50824

Closed
joshlf opened this issue May 17, 2018 · 7 comments
Closed

Rust doesn't know type is sized #50824

joshlf opened this issue May 17, 2018 · 7 comments
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-diagnostics Area: Messages for errors, warnings, and lints A-typesystem Area: The type system C-bug Category: This is a bug.

Comments

@joshlf
Copy link
Contributor

joshlf commented May 17, 2018

rustc is telling me that T needs to be Sized when it is clearly already Sized. This code:

#![feature(const_fn)]

const fn size_of<T: Sized>() -> (usize, T) where T: Sized {
    (::std::mem::size_of::<T>(), ::std::mem::transmute([0u8; ::std::mem::size_of::<T>()]))
}

(playground link)

Produces this error:

error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied
 --> src/main.rs:4:62
  |
4 |     (::std::mem::size_of::<T>(), ::std::mem::transmute([0u8; ::std::mem::size_of::<T>()]))
  |                                                              ^^^^^^^^^^^^^^^^^^^^^^^^ `T` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `T`
  = help: consider adding a `where T: std::marker::Sized` bound
  = note: required by `std::mem::size_of`

Obviously T: Sized and where T: Sized are redundant, but I did it to demonstrate that neither is sufficient. The same error appears if only one of the bounds is used, or if neither are used.

@Centril
Copy link
Contributor

Centril commented May 17, 2018

(The definition above of size_of can cause UB because you can't invent an arbitrary T by zeroing the bitpattern...)

Seems like a bug re. the trait bounds.

Reducing a bit (tested on nightly and stable):

#![crate_type = "lib"]

use std::mem::{size_of, transmute};

fn bug<T>() -> (usize, T) {
    (
        size_of::<T>(),
        transmute(
            [0u8; size_of::<T>()]
        )
    )
}

@Centril Centril added A-typesystem Area: The type system C-bug Category: This is a bug. A-const-eval Area: constant evaluation (mir interpretation) labels May 17, 2018
@joshlf
Copy link
Contributor Author

joshlf commented May 17, 2018

(The definition above of size_of can cause UB because you can't invent an arbitrary T by zeroing the bitpattern...)

Lol yes sorry for the blatantly unsafe code. I was playing around with getting type inference to work in a macro. That code was never intended to actually be run.

@hanna-kruppe
Copy link
Contributor

This is a known and expected bug but I can never find the canonical issue for it. Maybe #50308 or #43408

@kennytm kennytm added the A-diagnostics Area: Messages for errors, warnings, and lints label May 17, 2018
@bgeron
Copy link

bgeron commented May 19, 2018

The error seems to appear when Rust is forced to compute with values inside types. Further minimised example: (play)

fn size_of<T>() -> T where T: Sized {
    let v : [u8; ::std::mem::size_of::<T>()] = unimplemented!();
    v
}

@bgeron
Copy link

bgeron commented May 19, 2018

The error message given for this is:

   Compiling playground v0.0.1 (file:///playground)
error[E0277]: the trait bound `T: std::marker::Sized` is not satisfied
 --> src/lib.rs:4:18
  |
4 |     let v : [u8; ::std::mem::size_of::<T>()] = unimplemented!();
  |                  ^^^^^^^^^^^^^^^^^^^^^^^^ `T` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `T`
  = help: consider adding a `where T: std::marker::Sized` bound
  = note: required by `std::mem::size_of`

warning: unreachable expression
 --> src/lib.rs:5:5
  |
5 |     v
  |     ^
  |
  = note: #[warn(unreachable_code)] on by default

There is no error about v being of the wrong type. Presumably, this is because Rust hasn't yet gotten to the stage where it can compare types for equality.

@KamilaBorowska
Copy link
Contributor

KamilaBorowska commented May 21, 2018

As a workaround, you can do this instead:

use std::mem;

unsafe fn example<T>() -> (usize, T) {
    (mem::size_of::<T>(), mem::zeroed())
}

This is unsafe, because not every type has 0 as a valid value. Still a bug, don't get me wrong.

@oli-obk
Copy link
Contributor

oli-obk commented Jan 28, 2019

This is just another symptom of #43408 I believe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-diagnostics Area: Messages for errors, warnings, and lints A-typesystem Area: The type system C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

7 participants