Skip to content

transmute_undefined_repr: no lint when transmuting into a single-field struct without #[repr(transparent)] #17869

Open

Description

@bardiharborow

Summary

transmute_undefined_repr doesn't fire on a transmute between a type and a single-field struct that has the default representation. A common case is &str to &Wrapper where struct Wrapper(str).

The layout of a repr(Rust) struct isn't guaranteed, even when it has only one field. The Reference says the default representation gives no guarantees about data layout. The Nomicon says only #[repr(C)] or #[repr(transparent)] give a layout you can rely on. So this transmute relies on how the compiler currently lays the type out, which is what this lint is meant to catch.

The cause is reduce_ty: a struct whose only non-zero-sized field is T reduces to T before the repr is checked. def.repr().inhibit_struct_field_reordering() is only checked for structs with more than one non-zero-sized field. Because of this, &str -> &Wrapper is analysed as &str -> &str.

This seems to be deliberate. #8503 described one-field structs as intentionally not linted, and #8547 made one-element tuples behave the same way. I'd like to suggest changing that: only treat a single-field struct as its field when it is #[repr(transparent)], or #[repr(C)] with that field first. In every other case, report an undefined layout as the lint does today. The lint is in nursery, so this seems like the right place to be strict, but I understand it may create a lot of new warnings in existing code (see #8496).

This came up in a real crate. A #[repr(transparent)] was missing on one of many otherwise identical wrapper types whose from_borrowed_unchecked transmutes &str -> &Self (ruma/ruma#2625). Nothing in clippy pointed it out.

Lint Name

transmute_undefined_repr

Reproducer

I tried this code:

pub struct Name(str);

pub fn from_str(s: &str) -> &Name {
    unsafe { std::mem::transmute::<&str, &Name>(s) }
}

with cargo clippy -- -D clippy::transmute_undefined_repr.

I expected to see this happen: an error saying that &Name has an undefined layout, with a suggestion to add #[repr(transparent)] to Name.

Instead, this happened: no error from transmute_undefined_repr. The only warning was the unrelated dead_code warning for the unread field.

The same thing happens with sized fields: pub struct Meters(pub f64) with transmute::<&f64, &Meters> doesn't trigger the lint either.

Version

rustc 1.99.0 (b940084d7 2026-09-28)
binary: rustc
commit-hash: b940084d7eb6a299eb4bfeb8e34901bc051e7ac4
commit-date: 2026-09-28
host: aarch64-apple-darwin
release: 1.99.0
LLVM version: 23.1.1

Activity

  1. added
    C-bugCategory: Clippy is not doing the correct thing
    I-false-negativeIssue: The lint should have been triggered on code, but wasn't
    on Oct 13, 2026
  2. bhirahatees-periyasamy commented on Oct 13, 2026

    @bhirahatees-periyasamy
    Contributor

    @rustbot claim

  3. bhirahatees-periyasamy commented on Oct 13, 2026

    @bhirahatees-periyasamy
    Contributor

    @rustbot release-assignment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-negativeIssue: The lint should have been triggered on code, but wasn't

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions