From c7367fd35d3337c9d9967418b33416dbf6a6e66c Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 7 Oct 2026 15:58:08 +0100 Subject: [PATCH 1/4] refactor(target-info): Make a Workspace optional when finding the std source path There's scope for improving this logic to avoid unnecessary rustc calls in the future but I'd prefer to have the users of it merged before trying to optimise. --- benches/benchsuite/benches/resolve.rs | 2 +- src/compiler/build_context/target_info.rs | 24 +++++++++++------------ src/ops/cargo_clean.rs | 2 +- src/ops/cargo_compile/mod.rs | 2 +- src/ops/cargo_fetch.rs | 2 +- src/ops/cargo_fix/mod.rs | 7 +++++-- src/ops/cargo_metadata.rs | 2 +- src/ops/cargo_tree/mod.rs | 2 +- src/util/command_prelude.rs | 2 +- 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/benches/benchsuite/benches/resolve.rs b/benches/benchsuite/benches/resolve.rs index b41c39ba0fe..1b7e50bd849 100644 --- a/benches/benchsuite/benches/resolve.rs +++ b/benches/benchsuite/benches/resolve.rs @@ -25,7 +25,7 @@ struct ResolveInfo<'gctx> { fn do_resolve<'gctx>(gctx: &'gctx GlobalContext, ws_root: &Path) -> ResolveInfo<'gctx> { let requested_kinds = [CompileKind::Host]; let ws = Workspace::new(&ws_root.join("Cargo.toml"), gctx).unwrap(); - let mut target_data = RustcTargetData::new(&ws, &requested_kinds).unwrap(); + let mut target_data = RustcTargetData::new(gctx, Some(&ws), &requested_kinds).unwrap(); let cli_features = CliFeatures::from_command_line(&[], false, true).unwrap(); let pkgs = cargo::ops::Packages::Default; let specs = pkgs.to_package_id_specs(&ws).unwrap(); diff --git a/src/compiler/build_context/target_info.rs b/src/compiler/build_context/target_info.rs index 4f5daab4afb..e13e262d4f0 100644 --- a/src/compiler/build_context/target_info.rs +++ b/src/compiler/build_context/target_info.rs @@ -989,11 +989,11 @@ pub struct RustcTargetData<'gctx> { impl<'gctx> RustcTargetData<'gctx> { #[tracing::instrument(skip_all)] pub fn new( - ws: &Workspace<'gctx>, + gctx: &'gctx GlobalContext, + ws: Option<&Workspace<'gctx>>, requested_kinds: &[CompileKind], ) -> CargoResult> { - let gctx = ws.gctx(); - let rustc = gctx.load_global_rustc(Some(ws))?; + let rustc = gctx.load_global_rustc(ws)?; let mut target_config = HashMap::default(); let mut target_info = HashMap::default(); let target_applies_to_host = gctx.target_applies_to_host()?; @@ -1054,16 +1054,14 @@ impl<'gctx> RustcTargetData<'gctx> { .iter() .filter_map(|d| d.artifact()?.target()?.to_compile_kind()) } - let all_kinds = requested_kinds - .iter() - .copied() - .chain(ws.members().flat_map(|p| { - p.manifest() - .default_kind() - .into_iter() - .chain(p.manifest().forced_kind()) - .chain(artifact_targets(p)) - })); + let members = ws.into_iter().flat_map(|ws| ws.members()); + let all_kinds = requested_kinds.iter().copied().chain(members.flat_map(|p| { + p.manifest() + .default_kind() + .into_iter() + .chain(p.manifest().forced_kind()) + .chain(artifact_targets(p)) + })); for kind in all_kinds { res.merge_compile_kind(kind)?; } diff --git a/src/ops/cargo_clean.rs b/src/ops/cargo_clean.rs index 6647be50b25..36ca8f86122 100644 --- a/src/ops/cargo_clean.rs +++ b/src/ops/cargo_clean.rs @@ -195,7 +195,7 @@ fn clean_specs( ) -> CargoResult<()> { // Clean specific packages. let requested_kinds = CompileKind::from_requested_targets(clean_ctx.gctx, targets)?; - let target_data = RustcTargetData::new(ws, &requested_kinds)?; + let target_data = RustcTargetData::new(ws.gctx(), Some(ws), &requested_kinds)?; let (pkg_set, resolve) = ops::resolve_ws(ws, dry_run)?; let prof_dir_name = profiles.get_dir_name(); let host_layout = Layout::new(ws, None, &prof_dir_name, true, true)?; diff --git a/src/ops/cargo_compile/mod.rs b/src/ops/cargo_compile/mod.rs index bf55ba1858c..a0847dd96ec 100644 --- a/src/ops/cargo_compile/mod.rs +++ b/src/ops/cargo_compile/mod.rs @@ -294,7 +294,7 @@ pub fn create_bcx<'a, 'gctx>( } gctx.validate_term_config()?; - let mut target_data = RustcTargetData::new(ws, &build_config.requested_kinds)?; + let mut target_data = RustcTargetData::new(gctx, Some(ws), &build_config.requested_kinds)?; let specs = spec.to_package_id_specs(ws)?; let has_dev_units = { diff --git a/src/ops/cargo_fetch.rs b/src/ops/cargo_fetch.rs index 731a3775a20..d25e2444d99 100644 --- a/src/ops/cargo_fetch.rs +++ b/src/ops/cargo_fetch.rs @@ -34,7 +34,7 @@ pub fn fetch<'a>( let gctx = ws.gctx(); let build_config = BuildConfig::new(gctx, jobs, keep_going, &options.targets, UserIntent::Build)?; - let mut data = RustcTargetData::new(ws, &build_config.requested_kinds)?; + let mut data = RustcTargetData::new(ws.gctx(), Some(ws), &build_config.requested_kinds)?; let mut fetched_packages = HashSet::default(); let mut deps_to_fetch = ws.members().map(|p| p.package_id()).collect::>(); let mut to_download = Vec::new(); diff --git a/src/ops/cargo_fix/mod.rs b/src/ops/cargo_fix/mod.rs index 90aeb7a4b21..940ad943041 100644 --- a/src/ops/cargo_fix/mod.rs +++ b/src/ops/cargo_fix/mod.rs @@ -150,8 +150,11 @@ pub fn fix( ) -> CargoResult<()> { check_version_control(gctx, opts)?; - let mut target_data = - RustcTargetData::new(original_ws, &opts.compile_opts.build_config.requested_kinds)?; + let mut target_data = RustcTargetData::new( + gctx, + Some(original_ws), + &opts.compile_opts.build_config.requested_kinds, + )?; let specs = opts.compile_opts.spec.to_package_id_specs(&original_ws)?; let members: Vec<&Package> = original_ws diff --git a/src/ops/cargo_metadata.rs b/src/ops/cargo_metadata.rs index b283e5dd604..a6f91756ddf 100644 --- a/src/ops/cargo_metadata.rs +++ b/src/ops/cargo_metadata.rs @@ -144,7 +144,7 @@ fn build_resolve_graph( &metadata_opts.filter_platforms, CompileKindFallback::JustHost, )?; - let mut target_data = RustcTargetData::new(ws, &requested_kinds)?; + let mut target_data = RustcTargetData::new(ws.gctx(), Some(ws), &requested_kinds)?; // Resolve entire workspace. let specs = Packages::All(Vec::new()).to_package_id_specs(ws)?; let force_all = if metadata_opts.filter_platforms.is_empty() { diff --git a/src/ops/cargo_tree/mod.rs b/src/ops/cargo_tree/mod.rs index 95e1110a3a2..76d32cebcc4 100644 --- a/src/ops/cargo_tree/mod.rs +++ b/src/ops/cargo_tree/mod.rs @@ -148,7 +148,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() // TODO: Target::All is broken with -Zfeatures=itarget. To handle that properly, // `FeatureResolver` will need to be taught what "all" means. let requested_kinds = CompileKind::from_requested_targets(ws.gctx(), &requested_targets)?; - let mut target_data = RustcTargetData::new(ws, &requested_kinds)?; + let mut target_data = RustcTargetData::new(ws.gctx(), Some(ws), &requested_kinds)?; let specs = opts.packages.to_package_id_specs(ws)?; let has_dev = if opts .edge_kinds diff --git a/src/util/command_prelude.rs b/src/util/command_prelude.rs index ddd2dbc73f5..c3a4f902fc1 100644 --- a/src/util/command_prelude.rs +++ b/src/util/command_prelude.rs @@ -1416,7 +1416,7 @@ fn get_packages() -> CargoResult> { let ws = Workspace::new(&find_root_manifest_for_wd(gctx.cwd())?, &gctx)?; let requested_kinds = CompileKind::from_requested_targets(ws.gctx(), &[])?; - let mut target_data = RustcTargetData::new(&ws, &requested_kinds)?; + let mut target_data = RustcTargetData::new(&gctx, Some(&ws), &requested_kinds)?; // `cli_features.all_features` must be true in case that `specs` is empty. let cli_features = CliFeatures::new_all(true); let has_dev_units = HasDevUnits::Yes; From cdb9142eab4dbe60df69835f9a02e82e2644edd0 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Thu, 8 Oct 2026 11:34:53 +0100 Subject: [PATCH 2/4] test(builtin-dep): Test resolve contents using cargo metadata --- tests/testsuite/builtin_dep.rs | 41 +++++++++++++++++++++++++++++++++ tests/testsuite/standard_lib.rs | 6 ++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/tests/testsuite/builtin_dep.rs b/tests/testsuite/builtin_dep.rs index 806511263f0..9cbc08e417d 100644 --- a/tests/testsuite/builtin_dep.rs +++ b/tests/testsuite/builtin_dep.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use crate::prelude::*; use cargo_test_support::{project, str}; @@ -21,8 +23,10 @@ fn builtin_dep_accepted() { ) .build(); + let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/testsuite/mock-std/library"); p.cargo("check") .masquerade_as_nightly_cargo(&["builtin-dependencies"]) + .env("__CARGO_TESTS_ONLY_SRC_ROOT", &root) .with_status(101) .with_stderr_data(str![[r#" @@ -70,6 +74,43 @@ Caused by: .run(); } +#[cargo_test] +fn resolve_contents() { + crate::standard_lib::publish_mock_std_registry_packages(); + + let p = project() + .file("src/lib.rs", "#![no_std]") + .file( + "Cargo.toml", + r#" + cargo-features = ["builtin-dependencies"] + + [package] + name = "foo" + version = "0.1.0" + edition = "2021" + + [dependencies] + core = { builtin = true } + "#, + ) + .build(); + + let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/testsuite/mock-std/library"); + p.cargo("metadata") + .masquerade_as_nightly_cargo(&["builtin-dependencies"]) + .env("__CARGO_TESTS_ONLY_SRC_ROOT", &root) + .with_status(101) + .with_stderr_data(str![[r#" + +thread [..] panicked at [..] +not yet implemented: builtin source +[NOTE] run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +"#]]) + .run(); +} + #[cargo_test] fn patching_with_builtins_requires_feature_gate() { let p = project() diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index 43f3b46bdbc..12f22e08767 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -17,7 +17,7 @@ struct Setup { real_sysroot: String, } -fn setup() -> Setup { +pub(crate) fn publish_mock_std_registry_packages() { // Our mock sysroot requires a few packages from crates.io, so make sure // they're "published" to crates.io. Also edit their code a bit to make sure // that they have access to our custom crates with custom apis. @@ -83,6 +83,10 @@ fn setup() -> Setup { .add_dep(Dependency::new("rustc-std-workspace-std", "*").optional(true)) .feature("mockbuild", &["rustc-std-workspace-std"]) .publish(); +} + +fn setup() -> Setup { + publish_mock_std_registry_packages(); let p = ProjectBuilder::new(paths::root().join("rustc-wrapper")) .file( From 04673d1686b2f04ab9cbcf309359ef65b580e692 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Fri, 21 Aug 2026 12:05:43 +0100 Subject: [PATCH 3/4] feat(sources): Add builtin source --- src/compiler/standard_lib.rs | 2 +- src/resolver/encode.rs | 3 +- src/sources/builtin.rs | 128 +++++++++++++++++++++++++ src/sources/mod.rs | 2 + src/sources/path.rs | 5 +- src/workspace/source_id.rs | 11 ++- tests/testsuite/builtin_dep.rs | 166 ++++++++++++++++++++++++++++++--- 7 files changed, 298 insertions(+), 19 deletions(-) create mode 100644 src/sources/builtin.rs diff --git a/src/compiler/standard_lib.rs b/src/compiler/standard_lib.rs index 319e9a9fab0..b398c741ff4 100644 --- a/src/compiler/standard_lib.rs +++ b/src/compiler/standard_lib.rs @@ -218,7 +218,7 @@ fn generate_roots( Ok(()) } -fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult { +pub(crate) fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult { if let Some(s) = target_data.gctx.get_env_os("__CARGO_TESTS_ONLY_SRC_ROOT") { return Ok(s.into()); } diff --git a/src/resolver/encode.rs b/src/resolver/encode.rs index 3bc4d0921af..2106db70e40 100644 --- a/src/resolver/encode.rs +++ b/src/resolver/encode.rs @@ -661,7 +661,8 @@ pub fn encodable_package_id( } fn encodable_source_id(id: SourceId, version: ResolveVersion) -> Option { - if id.is_path() { + // Lockfile support for builtins isn't yet implemented. + if id.is_path() || id.is_builtin() { None } else { Some( diff --git a/src/sources/builtin.rs b/src/sources/builtin.rs new file mode 100644 index 00000000000..697db9c2944 --- /dev/null +++ b/src/sources/builtin.rs @@ -0,0 +1,128 @@ +use crate::{ + CargoResult, GlobalContext, + compiler::{CompileKind, RustcTargetData, standard_lib::detect_sysroot_src_path}, + sources::{ + IndexSummary, RecursivePathSource, + source::{MaybePackage, QueryKind, Source}, + }, + workspace::{Dependency, Package, PackageId, SourceId}, +}; + +/// A builtin source represents standard library packages used in build-std, which are "built into" +/// the toolchain. +/// +/// It's a thin wrapper around a [`RecursivePathSource`] located in the sysroot's library source +/// path. +pub struct BuiltinSource<'gctx> { + /// The unique identifier for this source + source_id: SourceId, + /// The underlying path source which discovers packages + path_source: RecursivePathSource<'gctx>, +} + +impl<'gctx> BuiltinSource<'gctx> { + pub fn new(source_id: SourceId, gctx: &'gctx GlobalContext) -> CargoResult { + let target_data = RustcTargetData::new(gctx, None, &[CompileKind::Host])?; + let path = detect_sysroot_src_path(&target_data)?; + let path_source = RecursivePathSource::new(&path, source_id, gctx); + Ok(Self { + source_id, + path_source, + }) + } +} + +#[async_trait::async_trait(?Send)] +impl<'gctx> Source for BuiltinSource<'gctx> { + /// All builtin dependencies are opaque, so this will return a summary without any dependencies when queried + async fn query( + &self, + dep: &Dependency, + kind: QueryKind, + f: &mut dyn FnMut(IndexSummary), + ) -> CargoResult<()> { + if !dep.source_id().is_builtin() { + // Avoid loading packages in the path source if it's not needed + return Ok(()); + } + self.path_source.query(dep, kind, f).await + } + + fn supports_checksums(&self) -> bool { + self.path_source.supports_checksums() + } + + fn requires_precise(&self) -> bool { + self.path_source.requires_precise() + } + + fn source_id(&self) -> SourceId { + self.source_id + } + + async fn download(&self, id: PackageId) -> CargoResult { + self.path_source.download(id).await + } + + async fn finish_download(&self, id: PackageId, data: Vec) -> CargoResult { + self.path_source.finish_download(id, data).await + } + + fn fingerprint(&self, pkg: &Package) -> CargoResult { + self.path_source.fingerprint(pkg) + } + + fn describe(&self) -> String { + self.source_id.to_string() + } + + fn invalidate_cache(&self) { + self.path_source.invalidate_cache(); + } + + fn set_quiet(&mut self, quiet: bool) { + self.path_source.set_quiet(quiet); + } +} + +#[cfg(test)] +mod test { + use std::path::Path; + + use crate::{ + GlobalContext, + sources::IndexSummary, + util::{VersionReqMatchMode, data_structures::HashMap}, + workspace::{Dependency, SourceId}, + }; + + #[test] + fn builtin_source() { + let mut gctx = GlobalContext::default().unwrap(); + let mock_std_root = + Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/testsuite/mock-std/library"); + let env = HashMap::from_iter([( + "__CARGO_TESTS_ONLY_SRC_ROOT".to_string(), + mock_std_root.display().to_string(), + )]); + gctx.set_env(env); + + let source_id = SourceId::for_builtin().unwrap(); + let dep = Dependency::new_override("core".into(), source_id); + + let source = dep.source_id().load(&gctx).unwrap(); + let results = + crate::util::block_on(source.query_vec(&dep, crate::sources::source::QueryKind::Exact)) + .unwrap(); + + assert_eq!(results.len(), 1); + let result = results[0].clone(); + if let IndexSummary::Candidate(s) = result { + assert!(dep.matches(&s, VersionReqMatchMode::Default)); + assert!(s.dependencies().is_empty()); + assert!(s.source_id().is_builtin()) + } else { + panic!("no candidate found"); + }; + } +} diff --git a/src/sources/mod.rs b/src/sources/mod.rs index 5d92c92770b..999d4cf2b58 100644 --- a/src/sources/mod.rs +++ b/src/sources/mod.rs @@ -26,6 +26,7 @@ //! //! [source replacement]: https://doc.rust-lang.org/nightly/cargo/reference/source-replacement.html +pub use self::builtin::BuiltinSource; pub use self::config::SourceConfigMap; pub use self::directory::DirectorySource; pub use self::git::GitSource; @@ -37,6 +38,7 @@ pub use self::registry::{ }; pub use self::replaced::ReplacedSource; +pub mod builtin; pub mod config; pub mod directory; pub mod git; diff --git a/src/sources/path.rs b/src/sources/path.rs index 4c53888f8b1..d92c7984471 100644 --- a/src/sources/path.rs +++ b/src/sources/path.rs @@ -1189,12 +1189,15 @@ fn read_nested_packages( // Registry sources are not allowed to have `path=` dependencies because // they're all translated to actual registry dependencies. // + // The standard library source intentionally does not include some test crates leading to broken + // dev-dependencies links. The main directory walk already gets all the packages we need. + // // We normalize the path here ensure that we don't infinitely walk around // looking for crates. By normalizing we ensure that we visit this crate at // most once. // // TODO: filesystem/symlink implications? - if !source_id.is_registry() { + if !source_id.is_registry() && !source_id.is_builtin() { for p in nested.iter() { let path = paths::normalize_path(&path.join(p)); let result = diff --git a/src/workspace/source_id.rs b/src/workspace/source_id.rs index 137f1ff7309..27e0efab1c2 100644 --- a/src/workspace/source_id.rs +++ b/src/workspace/source_id.rs @@ -1,7 +1,9 @@ use crate::context; use crate::sources::registry::CRATES_IO_HTTP_INDEX; use crate::sources::source::Source; -use crate::sources::{CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY, DirectorySource}; +use crate::sources::{ + BuiltinSource, CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY, DirectorySource, +}; use crate::sources::{GitSource, PathSource, RegistrySource}; use crate::util::data_structures::HashSet; use crate::util::interning::InternedString; @@ -395,6 +397,11 @@ impl SourceId { matches!(self.inner.kind, SourceKind::Git(_)) } + /// Returns `true` if this source is builtin. + pub fn is_builtin(self) -> bool { + matches!(self.inner.kind, SourceKind::Builtin) + } + /// Creates an implementation of `Source` corresponding to this ID. pub fn load<'a>(self, gctx: &'a GlobalContext) -> CargoResult> { trace!("loading SourceId; {}", self); @@ -411,7 +418,7 @@ impl SourceId { } Ok(Box::new(PathSource::new(&path, self, gctx))) } - SourceKind::Builtin => todo!("builtin source"), + SourceKind::Builtin => Ok(Box::new(BuiltinSource::new(self, gctx)?)), SourceKind::Registry | SourceKind::SparseRegistry => { Ok(Box::new(RegistrySource::remote(self, gctx)?)) } diff --git a/tests/testsuite/builtin_dep.rs b/tests/testsuite/builtin_dep.rs index 9cbc08e417d..965895f409c 100644 --- a/tests/testsuite/builtin_dep.rs +++ b/tests/testsuite/builtin_dep.rs @@ -6,7 +6,7 @@ use cargo_test_support::{project, str}; #[cargo_test] fn builtin_dep_accepted() { let p = project() - .file("src/lib.rs", "use core;") + .file("src/lib.rs", "#![no_std]") .file( "Cargo.toml", r#" @@ -27,12 +27,11 @@ fn builtin_dep_accepted() { p.cargo("check") .masquerade_as_nightly_cargo(&["builtin-dependencies"]) .env("__CARGO_TESTS_ONLY_SRC_ROOT", &root) - .with_status(101) .with_stderr_data(str![[r#" - -thread [..] panicked at [..] -not yet implemented: builtin source -[NOTE] run with `RUST_BACKTRACE=1` environment variable to display a backtrace +[LOCKING] 1 package to highest compatible version +[CHECKING] core v0.0.0 (builtin builtin://.) +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s "#]]) .run(); @@ -100,14 +99,153 @@ fn resolve_contents() { p.cargo("metadata") .masquerade_as_nightly_cargo(&["builtin-dependencies"]) .env("__CARGO_TESTS_ONLY_SRC_ROOT", &root) - .with_status(101) - .with_stderr_data(str![[r#" - -thread [..] panicked at [..] -not yet implemented: builtin source -[NOTE] run with `RUST_BACKTRACE=1` environment variable to display a backtrace - -"#]]) + .with_stdout_data( + str![[r#" +{ + "build_directory": "[ROOT]/foo/target", + "metadata": null, + "packages": [ + { + "authors": [ + "Alex Crichton " + ], + "categories": [], + "default_run": null, + "dependencies": [], + "description": null, + "documentation": null, + "edition": "2018", + "features": {}, + "homepage": null, + "id": "builtin://.#core", + "keywords": [], + "license": null, + "license_file": null, + "links": null, + "manifest_path": "[..]/tests/testsuite/mock-std/library/core/Cargo.toml", + "metadata": null, + "name": "core", + "publish": null, + "readme": null, + "repository": null, + "rust_version": null, + "source": "builtin://.", + "targets": [ + { + "crate_types": [ + "lib" + ], + "doc": true, + "doctest": true, + "edition": "2018", + "kind": [ + "lib" + ], + "name": "core", + "src_path": "[..]/tests/testsuite/mock-std/library/core/src/lib.rs", + "test": true + } + ], + "version": "0.0.0" + }, + { + "authors": [], + "categories": [], + "default_run": null, + "dependencies": [ + { + "features": [], + "kind": null, + "name": "core", + "optional": false, + "registry": null, + "rename": null, + "req": "*", + "source": "builtin://.", + "target": null, + "uses_default_features": true + } + ], + "description": null, + "documentation": null, + "edition": "2021", + "features": {}, + "homepage": null, + "id": "path+[ROOTURL]/foo#0.1.0", + "keywords": [], + "license": null, + "license_file": null, + "links": null, + "manifest_path": "[ROOT]/foo/Cargo.toml", + "metadata": null, + "name": "foo", + "publish": null, + "readme": null, + "repository": null, + "rust_version": null, + "source": null, + "targets": [ + { + "crate_types": [ + "lib" + ], + "doc": true, + "doctest": true, + "edition": "2021", + "kind": [ + "lib" + ], + "name": "foo", + "src_path": "[ROOT]/foo/src/lib.rs", + "test": true + } + ], + "version": "0.1.0" + } + ], + "resolve": { + "nodes": [ + { + "dependencies": [], + "deps": [], + "features": [], + "id": "builtin://.#core" + }, + { + "dependencies": [ + "builtin://.#core" + ], + "deps": [ + { + "dep_kinds": [ + { + "kind": null, + "target": null + } + ], + "name": "core", + "pkg": "builtin://.#core" + } + ], + "features": [], + "id": "path+[ROOTURL]/foo#0.1.0" + } + ], + "root": "path+[ROOTURL]/foo#0.1.0" + }, + "target_directory": "[ROOT]/foo/target", + "version": 1, + "workspace_default_members": [ + "path+[ROOTURL]/foo#0.1.0" + ], + "workspace_members": [ + "path+[ROOTURL]/foo#0.1.0" + ], + "workspace_root": "[ROOT]/foo" +} +"#]] + .is_json(), + ) .run(); } From 7b77571d745ff267c78748a385a26f0ddc1bb19f Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 7 Oct 2026 16:52:38 +0100 Subject: [PATCH 4/4] feat(builtin-dep): Skip unit generation for builtin dependencies --- src/compiler/unit_dependencies.rs | 1 + tests/testsuite/builtin_dep.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/unit_dependencies.rs b/src/compiler/unit_dependencies.rs index be8e9a4c7b9..1e7833e9228 100644 --- a/src/compiler/unit_dependencies.rs +++ b/src/compiler/unit_dependencies.rs @@ -1138,6 +1138,7 @@ impl<'a, 'gctx> State<'a, 'gctx> { let kind = unit.kind; self.resolve() .deps(pkg_id) + .filter(|(id, _)| !id.source_id().is_builtin()) .filter_map(|(id, deps)| { assert!(!deps.is_empty()); let deps: Vec<_> = deps diff --git a/tests/testsuite/builtin_dep.rs b/tests/testsuite/builtin_dep.rs index 965895f409c..aba27b2f198 100644 --- a/tests/testsuite/builtin_dep.rs +++ b/tests/testsuite/builtin_dep.rs @@ -29,7 +29,6 @@ fn builtin_dep_accepted() { .env("__CARGO_TESTS_ONLY_SRC_ROOT", &root) .with_stderr_data(str![[r#" [LOCKING] 1 package to highest compatible version -[CHECKING] core v0.0.0 (builtin builtin://.) [CHECKING] foo v0.1.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s