Skip to content

Rust doesn't know type is sized #50824

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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, covers all const contexts (static, const fn, ...) A-diagnostics Area: Messages for errors, warnings, and lints A-type-system Area: 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-type-system Area: Type system C-bug Category: This is a bug. A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) 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.

@LunaBorowska
Copy link
Contributor

LunaBorowska 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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-diagnostics Area: Messages for errors, warnings, and lints A-type-system Area: Type system C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

7 participants