Skip to content

Add lint for Apple cfgs that might want to be more general #13939

Open
@madsmtm

Description

@madsmtm

What it does

A lot of code in the ecosystem had to be updated once Rust added support for visionOS, and even now, 6 months later, there's still a lot of crates that don't yet have good support for this. This is a shame, because the target is very similar to iOS, which a lot of crates do support.

I'm thinking that perhaps adding a lint for cfg(all(target_os = "macos", target_os = "ios")) (and similar) to suggest cfg(target_vendor = "apple") instead might bump more crate authors to use the more general cfg.

Specifically the platforms iOS, tvOS, visionOS and watchOS are very similar internally, and using cfg(all(target_vendor = "apple", not(target_os = "macos"))) to represent those (or just cfg(target_vendor = "apple") when also including macOS) would be a nice improvement in almost all cases.

Advantage

  • Get more crate authors to make their crates support the less common platforms visionOS, tvOS and watchOS by default (provided they support iOS already).
  • Decrease maintenance burden once Apple inevitably adds a new OS that is very similar to the existing ones.
  • Decrease total lines of code needed to support these OS'es (target_vendor = "apple" is shorter than writing all of them out).

Drawbacks

  • It might trigger in places where people really don't want to be generic over all Apple platforms (e.g. code that is specific to e.g. tvOS). Such code is relatively rare.
  • cfg(target_vendor = "apple") is also planned to maybe be deprecated one day, though not before cfg(target_family = "darwin"), but it will possibly be more churn for the ecosystem to update then.

Example

#[cfg(all(target_os = "linux", target_os = "macos", target_os = "ios"))]
type Foo;

#[cfg(target_os = "ios")]
type Bar;

#[cfg(all(target_vendor = "apple", not(target_os = "ios")))]
type Foobar;

#[cfg(target_os = "macos")]
type Barbar;

Could be written as:

// Made more general to include tvOS, visionOS and watchOS
#[cfg(all(target_os = "linux", target_vendor = "apple"))]
type Foo;

// Made more general to include tvOS, visionOS and watchOS
#[cfg(all(target_vendor = "apple", not(target_os = "macos")))]
type Bar;

// Not triggered here, the user is clearly aware of `target_vendor = "apple"`
#[cfg(all(target_vendor = "apple", not(target_os = "ios")))]
type Foobar;

// Not triggered here, macOS is sufficiently different that we usually don't want to blanket support all Apple targets there
#[cfg(target_os = "macos")]
type Barbar;

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions