Skip to content

PrivateMethods' items aren't private, they are accessible via MaskElement #537

Description

@obi1kenobi

A surprising new SemVer breakage case was discovered earlier this week, affecting sealed traits' associated items (consts, types, functions with or without receivers — everything) being accessible to subtraits. This is non-obvious and usually isn't intended by the authors of such code, which can lead to accidental breakage.

portable-simd has such an at-risk pattern here

mod private_methods {
    pub impl(super) trait PrivateMethods {
        fn valid<const N: usize>(values: Simd<Self, N>) -> bool
        where
            Self: SimdElement;

        fn eq(self, other: Self) -> bool;

        fn to_usize(self) -> usize;
        fn max_unsigned() -> u64;

        type Unsigned: SimdElement;

        const TRUE: Self;

        const FALSE: Self;
    }
}

Despite the name PrivateMethods, all of those items and methods are accessible downstream (including in downstream crates) via any pub subtrait of PrivateMethods, such as the adjacent MaskElement:

pub impl(self) unsafe trait MaskElement:
    SimdElement<Mask = Self> + SimdCast + PrivateMethods {}

Stabilizing MaskElement could lead to accidentally stabilizing all those PrivateMethods items too, which seems undesirable.

This is a sibling issue of rust-lang/rust#158654 which flags an analogous concern in the Rust standard library itself.

Hat tip to @jhpratt for looping me in to look at the SemVer breakage and suggesting that we scan portable-simd for this pattern. I used AI tools for the scan, but wrote this issue fully by hand otherwise.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions