Skip to content

feat(build-std): Introduce builtin packages - #17396

Open
adamgemmell wants to merge 5 commits into
rust-lang:masterfrom
adamgemmell:dev/adagem01/builtin-sourcekind
Open

feat(build-std): Introduce builtin packages#17396
adamgemmell wants to merge 5 commits into
rust-lang:masterfrom
adamgemmell:dev/adagem01/builtin-sourcekind

Conversation

@adamgemmell

@adamgemmell adamgemmell commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

What does this PR try to resolve?

This PR, part of a stack split off from #16675, adds a new SourceKind variant called builtin, which will be used to represent builtin packages which will be used in the implementation of build-std=always as mentioned in the explicit builtin dependencies RFC. Later, dependencies on builtin packages will be able to be specified as part of the rest of the latter RFC.

This PR's scope is limited to what's needed in order for the resolver to satisfy dependencies on builtins given a registry which already knows about builtin packages, though no actual resolver changes are needed for this.

How to test and review this PR?

The PR introduces unit tests for all new behaviour and I recommend reading the commits in order. This is all dead code under Cargo's normal operation and there's no way to invoke cargo that uses SourceKind::Builtin at this point.

There is a very large amount of context behind build-std. Please feel free to spam me with questions and I can link to relevant bits of this context than reviewers needing to reread this context every time you need to review a build-std PR if you prefer.

This PR is part of a stack:

@rustbot rustbot added A-dependency-resolution Area: dependency resolution and the resolver A-lockfile Area: Cargo.lock issues S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 27, 2026
@rustbot

rustbot commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @epage, @weihanglo
  • @epage, @weihanglo expanded to epage, weihanglo
  • Random selection from epage, weihanglo

@weihanglo weihanglo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized I am probably looking at something that should/can be deferred. Let me know if it is the case.

View changes since this review

/// Creates a `SourceId` from a filesystem path representing a builtin package.
///
/// `path`: an absolute path.
pub fn for_builtin(path: &Path) -> CargoResult<SourceId> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do path.is_absolute() check here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already checked by into_url() in this function. Should be enough unless you think we need to canonicalize here?

I've added an e2e test with a relative source path that does a conversion in detect_sysroot_src_path which I'll post in a separate PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually nevermind, I tried that with a real workflow and overriding the sysroot with a relative source path doesn't work without build-std anyway. The into_url() check should be sufficient.

Comment thread crates/resolver-tests/tests/resolve.rs Outdated
let reg = registry(vec![pkg!(core)]);

assert_same(&res, &names(&["root", "core"]));
// No way to specify builtin deps - fails

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we comment them out instead of asserting the failure, if any?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done this for behaviour that's unimplemented as the failure case is basically random and annoying to assert on sometimes. Real fixes should assert properly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To elaborate a bit more, this makes rebasing easier for me and I think reads easier for the reviewer too, but let me know if you'd prefer otherwise

/// `path`: an absolute path.
pub fn for_builtin(path: &Path) -> CargoResult<SourceId> {
let url = path.into_url()?;
SourceId::new(SourceKind::Builtin, url, None)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about fn stable_hash and impl Hash for builtin sources?

Currently in this PR, we treat builtin sources unique if they comes from different paths. However, what if they actually come form the same Rust version?

BTW, stable_hash is more for serialization and and cross-machine reproducibility , and Hash impl is for internal runtime uniqueness

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention is there's only ever one Url that builtin SourceIds are constructed with and so only one builtin source. If we can ensure this then implementation is simpler, and we cut down the RFC scope a bit to ensure assumptions like this will be possible.

I'm not sure how best to enforce that in code however other than something awkward like caching a Builtin SourceId in the gctx and ensuring we only use that. We could modify impl Hash to not hash URLs if the kind is builtin, but I'm worried that would just mask when this assumption is broken.

@adamgemmell adamgemmell Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for a bit of context not included in this PR, the packages returned by the builtin source are not built - the real Units will still come from the separate std resolve, which in theory can support patching, source replacement or whatever else the main resolve currently supports.

To ensure there's only ever one Builtin source loaded I could modify impl Hash, Eq, Ord etc to not consider the URL for builtins.

We'd then add a sanity check in PackageRegistry::ensure_loaded() whenever the cached SourceId's Url differs from the one we're trying to load, but I'm not sure what could go wrong in the meantime before this check happens.

@weihanglo

Copy link
Copy Markdown
Member

BTW, if there is any prior discussion, would be great if you can share the specific comment links :)

@rustbot

This comment has been minimized.

/// A directory-based registry.
Directory,
/// Package sources distributed with the rust toolchain
Builtin,

@adamgemmell adamgemmell Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing comment from @epage regarding updating package_id_spec.rs #16675 (comment)

I opted to implement pkg id spec input/output in a separate PR after this sequence. We don't expect to see builtin pkg ids in cargo's output as they're not present in the resolve, and will be filtered from cargo metadata (see discussion at #16675 (comment))

View changes since the review

/// `path`: an absolute path.
pub fn for_builtin(path: &Path) -> CargoResult<SourceId> {
let url = path.into_url()?;
SourceId::new(SourceKind::Builtin, url, None)

@adamgemmell adamgemmell Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing comment from @epage regarding the fact that the URL in source ids is public facing: #16675 (comment)

Since then the URL used is a little more generic, and later work on the pkg id format will hide this further. The build-std goal task plan involves a thorough look at the output of each subcommand, so if this URL leaks later I expect to catch it.

View changes since the review

@adamgemmell
adamgemmell force-pushed the dev/adagem01/builtin-sourcekind branch from 77c8c93 to 9716028 Compare September 2, 2026 16:46
@rustbot

rustbot commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@adamgemmell adamgemmell mentioned this pull request Sep 3, 2026
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-dependency-resolution Area: dependency resolution and the resolver A-lockfile Area: Cargo.lock issues S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants