Skip to content

Support enum as type of static variable with #[linkage] #565

Closed
@pcc

Description

@pcc

Proposal

The status quo for working with weak function symbols in Rust is to define them as weak data symbols and then transmute them to function pointers (see the implementation of weak!). This is not only ugly, but is also incompatible with platforms where a data symbol does not have the same bitwise representation as a function symbol at the same address, as anticipated by the unsafe code guidelines for function pointers, which mention that not all platforms use identical representations. For example, the pointer authentication ABI uses some of the high-order bits of a function pointer for a signature based on the function type.

This proposal aims to accommodate such platforms by making the function type part of the declaration, while at the same time allowing the implementation of weak! and other users of #[linkage] to be simplified by avoiding the need to transmute.

Specifically, the proposal is to allow declarations such as the following:

extern "C" {
    #[linkage = "extern_weak"]
    static foo: Option<unsafe extern "C" fn()>;

     #[linkage = "extern_weak"]
     static bar: Option<&'static i8>;
}

The static variable foo shall have the value Some(foo) if foo is defined, or None if foo is not defined; likewise for bar.

More formally, a static variable with a linkage attribute may be permitted to have an enumerator type with two variants, where one of the variants has no fields, and the other has a single field of one of the following non-nullable types:

  • Reference type
  • Function pointer type
    The variants can appear in either order.

The value of the variable shall be initialized to the variant without a field if the symbol is not defined, or to the variant with a field if the symbol is defined, where the field has the same value that it would receive if a static variable or function of the same name and of the field's type were declared without the #[linkage] attribute.

This can be implemented simply by allowing such an enum as the type of the static variable, because their in-memory representations are pointer sized and match how references to extern weak symbols are resolved by the linker or dynamic loader: zero if undefined, non-zero if defined.

Mentors or Reviewers

Process

The main points of the Major Change Process are as follows:

  • File an issue describing the proposal.
  • A compiler team member or contributor who is knowledgeable in the area can second by writing @rustbot second.
    • Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a -C flag, then full team check-off is required.
    • Compiler team members can initiate a check-off via @rfcbot fcp merge on either the MCP or the PR.
  • Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.

You can read more about Major Change Proposals on forge.

Comments

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-compilerAdd this label so rfcbot knows to poll the compiler teammajor-changeA proposal to make a major change to rustcmajor-change-acceptedA major change proposal that was accepted

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions