Skip to content

Are (non-free) generic constants guaranteed to be evaluated? #112090

Closed
rust-lang/reference
#1497
@joshlf

Description

@joshlf

Reposted from rust-lang/unsafe-code-guidelines#409 at the suggestion of @digama0

Thanks to this suggestion by @gootorov, we're considering doing something like the following in zerocopy:

pub trait MaybeTransmutableInto<T: FromBytes>: Sized + AsBytes {
    const REF_TRANSMUTABLE_INTO: () = assert!(
        mem::size_of::<Self>() == mem::size_of::<T>()
            && mem::align_of::<Self>() >= mem::align_of::<T>()
    );

    fn transmute_ref_into(&self) -> &T {
        let _: () = <Self as MaybeTransmutableInto<T>>::REF_TRANSMUTABLE_INTO;
        unsafe { mem::transmute(self) }
    }
}

The nightly reference guarantees that "free constants are always evaluated at compile time." However, that's not quite what we have here - we evaluate the constant REF_TRANSMUTABLE_INTO but assign it to a runtime variable (let _: () = ...). If we replaced let _ with const _, that would be a free constant, but it would never compile (even when we wanted it to) because a constant in a function body isn't allowed to reference types which are generic in that context.

What I want to know is: Is this constant guaranteed to be evaluated so long as transmute_ref_into is used?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)T-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions