rust-lang / rust-lang/rust

Derive macros that emit unsafe code can't rely on mentioning the field type twice

Open
#148,793 18 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-macros A-proc-macros C-bug I-lang-radar T-lang
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

This is a different issue from https://github.com/rust-lang/rust/issues/148423.

Some derive macros need to reason about the properties of the types of a struct's fields, in order to emit correct unsafe code. This is usually done by emitting code that mentions the type name, and asserts that those types implement certain traits.

This relies on the assumption that, by repeating the same tokens twice, those repeated tokens will refer to the same type. This assumption is false in the face of nondeterministic proc macros that expand to types.

#[derive(SomeTrait)]
struct Thing {
    field: make_type!(),
}

In code such as above, the derive macro might expand to code that checks whether the type make_type!() has certain properties or not. However, if make_type!() is nondeterministic, it might cause the macro to check one type, while the struct actually contains a different type. This causes the macro to make assumptions that are false. If the macro emits unsafe code, this can lead to unsoundness.

This issue affects bytemuck, zerocopy, and probably many other crates. See those two links for working reproducers that demonstrate UB.

See also #147103, for a similar issue in std, although that case didn't cause unsoundness.

Meta

Affects rust 1.91.0.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the working reproducers linked from the bytemuck and zerocopy issues, then compare the related standard-library case in #147103. Done requires a compiler-level approach that prevents repeated nondeterministic proc-macro expansions from making derive-generated unsafe assumptions about a different field type.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.