Skip to content

mem::size_of::<T> not const - use of type variable from outer function #56794

Open
@frehberg

Description

@frehberg

The following CDR-serde implementation defines functions to serialize data-types such as u16, u32 etc. It is using an abstract function to align write-position, to match with multiple of mem::size_of(), where T is a primitive int or float type.

As the bytesize is known at compile time, I would like to declare the value as const, using the following patch ://github.com/frehberg/cdr-rs/pull/1

impl<W, E> Serializer<W, E>
where
    W: Write,
    E: ByteOrder,
{
....
  fn write_padding_of<T>(&mut self) -> Result<()> {
        // Calculate the required padding to align with 1-byte, 2-byte, 4-byte, 8-byte boundaries
        // Instead of using the slow modulo operation '%', the faster bit-masking is used
        const PADDING: [u8; 8] = [0; 8];
        const ALIGNMENT: usize = std::mem::size_of::<T>();
        const MASK = ALIGNMENT - 1; // mask like 0x0, 0x1, 0x3, 0x7
        match (self.pos as usize) & MASK {
            0 => Ok(()),
            n @ 1...7 => {
                let amt = ALIGNMENT - n;
                self.pos += amt as u64;
                self.writer.write_all(&PADDING[..amt]).map_err(Into::into)
            }
            _ => unreachable!(),
        }
    }

but compiler yields with error

error: Could not compile `cdr`.
warning: build failed, waiting for other jobs to finish...
error[E0401]: can't use type parameters from outer function
  --> src/ser.rs:51:54
47 |     fn write_padding_of<T>(&mut self) -> Result<()> {
   |        ---------------- - type variable from outer function
   |        |
   |        try adding a local type parameter in this method instead
...
51 |         const ALIGNMENT: usize = std::mem::size_of::<T>();
   |                                                      ^ use of type variable from outer function
For more information about this error, try `rustc --explain E0401`.
error: Could not compile `cdr`.

As the generic function is not exported by lib, and it is instanciated only from inside the crate, I am wondering why the compiler is not able to derive the type of parameter T.

Any idea?

EDIT the explanation of E0401 does not fit to this code

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-diagnosticsArea: Messages for errors, warnings, and lintsC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions