Skip to content

Cargo should allow features/optional-dependencies to be private or public, private by default #7769

@infinity0

Description

@infinity0
Contributor

A feature of a crate is part of its public API, but many crate authors don't realise this and constantly re-arrange their features. This in fact breaks semver, because someone depending on e.g. cc/rayon (present in version 1.0.37) will have this broken by cc version 1.0.47 which does not have this feature. What one should actually be depending on is the parallel feature which points to rayon in version 1.0.37, but points instead to num_cpus, jobserver in version 1.0.47 thereby retaining semver compatibility.

However the fact that the "public/private"-ness of features is not even typically discussed, means that many crate authors are unaware of this, and freely add and remove features/optional-dependencies from their crates without thinking about semver compatibility.

Not sure if this is related to #6129 or not - that issue seems more to be about the --extern flag to rustc.

Activity

added
C-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`
on Jan 6, 2020
infinity0

infinity0 commented on Jan 6, 2020

@infinity0
ContributorAuthor

After reading RFC 1977 it is clear that is a different though related proposal, about leaking child dependencies out of your (rust-language-level) API. By contrast, this issue is about restricting the visibility of your (crate-level) API, which is not otherwise restrictable today.

However it does propose a new public field which could be confusing, so I'd suggest to rename that field to allow_public rather than public, e.g. a sample Cargo.toml using both ideas would look like:

public_features = ["parallel"]
# ^ public optional dependencies would go here as well, as the --features flag does

[features]
parallel = ["num_cpus", "jobserver"]

[dependencies.jobserver]
version = "0.1.16"
optional = true
allow_public = true

Otherwise if you use public = true for jobserver it could perhaps suggest to someone that "jobserver" is a public optional dependency, whereas we want it to be private.

added
A-featuresArea: features — conditional compilation
on Feb 2, 2020
epage

epage commented on Apr 20, 2022

@epage
Contributor

I think the main issue here is with implicit features caused by optional dependencies as it should be more clear that explicit features are part of the API.

The latest stable release has cargo weak and namespaced features which is now documented as the default approach. While we have an issue changing the default for weak features (#10556), we've talked some about about changing the default for namespacing but not as sure on that.

Seeing as my understanding of the need in this issue is resolved (hiding implicit features), I'm going to close this. If there is something I missed, feel free to say so. If there is something more (like removing implicit features completely), please open a new issue.

infinity0

infinity0 commented on Apr 25, 2022

@infinity0
ContributorAuthor

it should be more clear that explicit features are part of the API.

If this is true, then crates.io should be detecting when people upload crates changing its explicit API features in a way that breaks semver. Does it do that at the moment?

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

    A-featuresArea: features — conditional compilationC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ehuss@epage@infinity0

        Issue actions

          Cargo should allow features/optional-dependencies to be private or public, private by default · Issue #7769 · rust-lang/cargo