diff --git a/Cargo.lock b/Cargo.lock index af30753a04c..a943b8b8c40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3015,7 +3015,7 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustfix" -version = "0.8.7" +version = "0.8.8" dependencies = [ "anyhow", "proptest", diff --git a/crates/rustfix/Cargo.toml b/crates/rustfix/Cargo.toml index 7b3d95a401a..21a70a59a0b 100644 --- a/crates/rustfix/Cargo.toml +++ b/crates/rustfix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustfix" -version = "0.8.7" +version = "0.8.8" authors = [ "Pascal Hertleif ", "Oliver Schneider ", diff --git a/crates/rustfix/src/lib.rs b/crates/rustfix/src/lib.rs index a1e2c47cfeb..0283d1a937d 100644 --- a/crates/rustfix/src/lib.rs +++ b/crates/rustfix/src/lib.rs @@ -167,8 +167,6 @@ pub fn collect_suggestions( } } - let snippets = diagnostic.spans.iter().map(span_to_snippet).collect(); - let solutions: Vec<_> = diagnostic .children .iter() @@ -204,7 +202,7 @@ pub fn collect_suggestions( } else { Some(Suggestion { message: diagnostic.message.clone(), - snippets, + snippets: diagnostic.spans.iter().map(span_to_snippet).collect(), solutions, }) } diff --git a/crates/rustfix/src/replace.rs b/crates/rustfix/src/replace.rs index ed467dcbac1..4cdc7c01fbf 100644 --- a/crates/rustfix/src/replace.rs +++ b/crates/rustfix/src/replace.rs @@ -24,7 +24,7 @@ impl State { } /// Span with a change [`State`]. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq)] struct Span { /// Start of this span in parent data start: usize, @@ -34,6 +34,17 @@ struct Span { data: State, } +impl std::fmt::Debug for Span { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let state = match self.data { + State::Initial => "initial", + State::Replaced(_) => "replaced", + State::Inserted(_) => "inserted", + }; + write!(f, "({}, {}: {state})", self.start, self.end) + } +} + /// A container that allows easily replacing chunks of its data #[derive(Debug, Clone, Default)] pub struct Data { @@ -97,102 +108,82 @@ impl Data { // [^empty]: Leading and trailing ones might be empty if we replace // the whole chunk. As an optimization and without loss of generality we // don't add empty parts. - let new_parts = { - let Some(index_of_part_to_split) = self.parts.iter().position(|p| { - !p.data.is_inserted() && p.start <= range.start && p.end >= range.end - }) else { - if tracing::enabled!(tracing::Level::DEBUG) { - let slices = self - .parts - .iter() - .map(|p| { - ( - p.start, - p.end, - match p.data { - State::Initial => "initial", - State::Replaced(..) => "replaced", - State::Inserted(..) => "inserted", - }, - ) - }) - .collect::>(); - tracing::debug!( - "no single slice covering {}..{}, current slices: {:?}", - range.start, - range.end, - slices, - ); - } + let Some(index_of_part_to_split) = self + .parts + .iter() + .position(|p| !p.data.is_inserted() && p.start <= range.start && p.end >= range.end) + else { + tracing::debug!( + "no single slice covering {}..{}, current slices: {:?}", + range.start, + range.end, + self.parts, + ); + return Err(Error::MaybeAlreadyReplaced(range)); + }; - return Err(Error::MaybeAlreadyReplaced(range)); - }; + let part_to_split = &self.parts[index_of_part_to_split]; - let part_to_split = &self.parts[index_of_part_to_split]; - - // If this replacement matches exactly the part that we would - // otherwise split then we ignore this for now. This means that you - // can replace the exact same range with the exact same content - // multiple times and we'll process and allow it. - // - // This is currently done to alleviate issues like - // rust-lang/rust#51211 although this clause likely wants to be - // removed if that's fixed deeper in the compiler. - if part_to_split.start == range.start && part_to_split.end == range.end { - if let State::Replaced(ref replacement) = part_to_split.data { - if &**replacement == data { - return Ok(()); - } + // If this replacement matches exactly the part that we would + // otherwise split then we ignore this for now. This means that you + // can replace the exact same range with the exact same content + // multiple times and we'll process and allow it. + // + // This is currently done to alleviate issues like + // rust-lang/rust#51211 although this clause likely wants to be + // removed if that's fixed deeper in the compiler. + if part_to_split.start == range.start && part_to_split.end == range.end { + if let State::Replaced(ref replacement) = part_to_split.data { + if &**replacement == data { + return Ok(()); } } + } - if part_to_split.data != State::Initial { - return Err(Error::AlreadyReplaced); - } - - let mut new_parts = Vec::with_capacity(self.parts.len() + 2); + if part_to_split.data != State::Initial { + return Err(Error::AlreadyReplaced); + } - // Previous parts - if let Some(ps) = self.parts.get(..index_of_part_to_split) { - new_parts.extend_from_slice(ps); - } + let mut new_parts = Vec::with_capacity(self.parts.len() + 2); - // Keep initial data on left side of part - if range.start > part_to_split.start { - new_parts.push(Span { - start: part_to_split.start, - end: range.start, - data: State::Initial, - }); - } + // Previous parts + if let Some(ps) = self.parts.get(..index_of_part_to_split) { + new_parts.extend_from_slice(ps); + } - // New part + // Keep initial data on left side of part + if range.start > part_to_split.start { new_parts.push(Span { - start: range.start, - end: range.end, - data: if insert_only { - State::Inserted(data.into()) - } else { - State::Replaced(data.into()) - }, + start: part_to_split.start, + end: range.start, + data: State::Initial, }); + } - // Keep initial data on right side of part - if range.end < part_to_split.end { - new_parts.push(Span { - start: range.end, - end: part_to_split.end, - data: State::Initial, - }); - } - - // Following parts - if let Some(ps) = self.parts.get(index_of_part_to_split + 1..) { - new_parts.extend_from_slice(ps); - } + // New part + new_parts.push(Span { + start: range.start, + end: range.end, + data: if insert_only { + State::Inserted(data.into()) + } else { + State::Replaced(data.into()) + }, + }); + + // Keep initial data on right side of part + if range.end < part_to_split.end { + new_parts.push(Span { + start: range.end, + end: part_to_split.end, + data: State::Initial, + }); + } - new_parts - }; + // Following parts + if let Some(ps) = self.parts.get(index_of_part_to_split + 1..) { + new_parts.extend_from_slice(ps); + } self.parts = new_parts; diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index f36fc173bcc..8aa9d34a4a8 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -987,10 +987,14 @@ impl<'gctx> RustcTargetData<'gctx> { pub fn dep_platform_activated(&self, dep: &Dependency, kind: CompileKind) -> bool { // If this dependency is only available for certain platforms, // make sure we're only enabling it for that platform. + // println!("Is platform activated? {:?}, artifact: {:?} Platform: {:?}", dep.name_in_toml(), dep.artifact(), dep.platform()); + // println!("Is platform specified? {:?}. artifact: {:?} kind: {:?} Platform: {:?}", dep.name_in_toml(), dep.artifact(), kind, dep.platform()); let Some(platform) = dep.platform() else { return true; }; let name = self.short_name(&kind); + println!("self.cfg(kind) {:#?}", self.cfg(kind)); + println!("Platform specified. {:?} - artifact: {:?} - kind: {:?} - dep.kind(): {:?} - Activated: {}", dep.name_in_toml(), dep.artifact(), kind, dep.kind(), platform.matches(name, self.cfg(kind))); platform.matches(name, self.cfg(kind)) } diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index 2ec2aa1a328..f356b4a70aa 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -242,6 +242,11 @@ impl Dependency { self.inner.name } + // // This probably won't work because the version requirement is prob different from the resolved version + // pub fn package_id(&self) -> PackageId { + // PackageId::new(self.package_name(), self.version_req(), self.source_id()) + // } + pub fn source_id(&self) -> SourceId { self.inner.source_id } diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index ac1bcdc5cb7..fea17cbe316 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -408,6 +408,7 @@ impl<'gctx> PackageSet<'gctx> { // let's not flood crates.io with connections multi.set_max_host_connections(2)?; + // println!("LazyCell called on this from PackageSet: {:?}", package_ids); Ok(PackageSet { packages: package_ids @@ -425,7 +426,9 @@ impl<'gctx> PackageSet<'gctx> { pub fn package_ids(&self) -> impl Iterator + '_ { self.packages.keys().cloned() } - + pub fn packages_debug(&self) -> impl Iterator> { + self.packages.values().map(|p| p.borrow()) + } pub fn packages(&self) -> impl Iterator { self.packages.values().filter_map(|p| p.borrow()) } @@ -498,6 +501,7 @@ impl<'gctx> PackageSet<'gctx> { target_data: &RustcTargetData<'gctx>, force_all_targets: ForceAllTargets, ) -> CargoResult<()> { + println!("In download_accessible: requested_kinds {:?}", requested_kinds); fn collect_used_deps( used: &mut BTreeSet, resolve: &Resolve, @@ -548,6 +552,7 @@ impl<'gctx> PackageSet<'gctx> { force_all_targets, )?; } + println!("to_download btree {:?}", to_download); self.get_many(to_download.into_iter())?; Ok(()) } @@ -616,21 +621,53 @@ impl<'gctx> PackageSet<'gctx> { target_data: &'a RustcTargetData<'_>, force_all_targets: ForceAllTargets, ) -> impl Iterator)> + 'a { + println!("Filtering deps of {pkg_id:?}. Requested kinds: {:?}", requested_kinds); resolve .deps(pkg_id) .filter(move |&(_id, deps)| { deps.iter().any(|dep| { + println!("DEP: {:?}", dep.name_in_toml()); if dep.kind() == DepKind::Development && has_dev_units == HasDevUnits::No { return false; } + println!("\tWAS NOT A DEV DEP"); if force_all_targets == ForceAllTargets::No { + // let chain = match dep.artifact() + // .and_then(|artifact| artifact.target()) + // .and_then(|target| target.to_resolved_compile_target(requested_kind)) { + // Some(target) => [&CompileKind::Target(target), &CompileKind::Host], + // None => &CompileKind::Host + // }; + // let kind = match (node_kind, dep.kind()) { + // (CompileKind::Host, _) => CompileKind::Host, + // (_, DepKind::Build) => CompileKind::Host, + // (_, DepKind::Normal) => node_kind, + // (_, DepKind::Development) => node_kind, + // }; + // let activated = if dep.artifact() + // .and_then(|artifact| artifact.target()) + // .and_then(|target| target.to_resolved_compile_target(requested_kind)) + println!("REQUESTED KINDS {:?}", requested_kinds); let activated = requested_kinds .iter() .chain(Some(&CompileKind::Host)) - .any(|kind| target_data.dep_platform_activated(dep, *kind)); + .chain(other) + .any(|kind| { + println!("REQUESTED KIND {:?}", kind); + let req_kind = dep.artifact() + .and_then(|artifact| artifact.target()) + .and_then(|target| target.to_resolved_compile_target(*kind)) + .and_then(|ctarget| Some(CompileKind::Target(ctarget))) + .unwrap_or(*kind); + + println!("Artifact resolved compile target: {:?}", req_kind); + target_data.dep_platform_activated(dep, req_kind) + }); if !activated { + println!("\tWAS NOT ACTIVATED"); return false; } + println!("\tWAS ACTIVATED"); } true }) diff --git a/src/cargo/ops/cargo_add/mod.rs b/src/cargo/ops/cargo_add/mod.rs index ac49f58e1d3..9e8e5d1b870 100644 --- a/src/cargo/ops/cargo_add/mod.rs +++ b/src/cargo/ops/cargo_add/mod.rs @@ -37,7 +37,6 @@ use crate::util::toml_mut::dependency::MaybeWorkspace; use crate::util::toml_mut::dependency::PathSource; use crate::util::toml_mut::dependency::Source; use crate::util::toml_mut::dependency::WorkspaceSource; -use crate::util::toml_mut::is_sorted; use crate::util::toml_mut::manifest::DepTable; use crate::util::toml_mut::manifest::LocalManifest; use crate::CargoResult; @@ -111,10 +110,14 @@ pub fn add(workspace: &Workspace<'_>, options: &AddOptions<'_>) -> CargoResult<( .map(TomlItem::as_table) .map_or(true, |table_option| { table_option.map_or(true, |table| { - is_sorted(table.get_values().iter_mut().map(|(key, _)| { - // get_values key paths always have at least one key. - key.remove(0) - })) + table + .get_values() + .iter_mut() + .map(|(key, _)| { + // get_values key paths always have at least one key. + key.remove(0) + }) + .is_sorted() }) }); for dep in deps { diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index a3d08bb4db0..9de0f58dc70 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -1,7 +1,6 @@ use crate::core::{Edition, Shell, Workspace}; use crate::util::errors::CargoResult; use crate::util::important_paths::find_root_manifest_for_wd; -use crate::util::toml_mut::is_sorted; use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo}; use crate::util::{restricted_names, GlobalContext}; use anyhow::{anyhow, Context as _}; @@ -995,7 +994,7 @@ fn update_manifest_with_new_member( } } - let was_sorted = is_sorted(members.iter().map(Value::as_str)); + let was_sorted = members.iter().map(Value::as_str).is_sorted(); members.push(display_path); if was_sorted { members.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str())); diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs index 246636d1f60..e5793ea8f2d 100644 --- a/src/cargo/ops/cargo_output_metadata.rs +++ b/src/cargo/ops/cargo_output_metadata.rs @@ -246,6 +246,7 @@ fn build_resolve_graph_r( let lib_target = targets.iter().find(|t| t.is_lib()); for dep in deps.iter() { + // this filtering is VERY IMPORTANT if let Some(target) = lib_target { // When we do have a library target, include them in deps if... let included = match dep.artifact() { diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index 223833ac8c3..551345aaf29 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -223,6 +223,7 @@ pub fn resolve_ws_with_opts<'gctx>( }; let pkg_set = get_resolved_packages(&resolved_with_overrides, registry)?; + // println!("pkg_set after get_resolved_packages: {:#?}", pkg_set.packages_debug().collect::>()); let member_ids = ws .members_with_features(specs, cli_features)? @@ -237,6 +238,7 @@ pub fn resolve_ws_with_opts<'gctx>( target_data, force_all_targets, )?; + // println!("pkg_set after download_accessible: {:#?}", pkg_set.packages_debug().collect::>()); let feature_opts = FeatureOpts::new(ws, has_dev_units, force_all_targets)?; let resolved_features = FeatureResolver::resolve( @@ -259,6 +261,7 @@ pub fn resolve_ws_with_opts<'gctx>( target_data, force_all_targets, )?; + // println!("pkg_set inside resolver: {:#?}", pkg_set.packages_debug().collect::>()); Ok(WorkspaceResolve { pkg_set, diff --git a/src/cargo/ops/tree/graph.rs b/src/cargo/ops/tree/graph.rs index 25939df8e18..a8416997a09 100644 --- a/src/cargo/ops/tree/graph.rs +++ b/src/cargo/ops/tree/graph.rs @@ -337,6 +337,7 @@ fn add_pkg( return *idx; } let from_index = graph.add_node(node); + println!("\nPackage: {}, node_kind: {:?} requested_kind: {:?}", package_id.name(), node_kind, requested_kind); // Compute the dep name map which is later used for foo/bar feature lookups. let mut dep_name_map: HashMap> = HashMap::new(); let mut deps: Vec<_> = resolve.deps(package_id).collect(); @@ -348,6 +349,7 @@ fn add_pkg( // This filter is *similar* to the one found in `unit_dependencies::compute_deps`. // Try to keep them in sync! .filter(|dep| { + // TODO change RIGHT HERE kind let kind = match (node_kind, dep.kind()) { (CompileKind::Host, _) => CompileKind::Host, (_, DepKind::Build) => CompileKind::Host, @@ -355,7 +357,10 @@ fn add_pkg( (_, DepKind::Development) => node_kind, }; // Filter out inactivated targets. + // TODO this should filter out artifact_deps too + println!("~{:?} kind: {:?} dep.kind(): {:?} Platform: {:?}", dep.package_name(), kind, dep.kind(), dep.platform()); if !show_all_targets && !target_data.dep_platform_activated(dep, kind) { + println!("Target is not activated, {:?}", kind); return false; } // Filter out dev-dependencies if requested. @@ -380,14 +385,20 @@ fn add_pkg( true }) .collect(); + // println!("deps with target filtered out: {:#?}", deps); // This dependency is eliminated from the dependency tree under // the current target and feature set. + // Note to self dep_id is package_id + // AHA! this is supposed to be empty because artifact dep is supposed to have been filtered out if deps.is_empty() { + println!("deps is empty on dep_id {:?} of {:?}", dep_id, package_id); continue; } deps.sort_unstable_by_key(|dep| dep.name_in_toml()); + // println!("Deps is not empty {:?}\n", deps); + // println!("PACKAGE MAP {:#?}", graph.package_map); let dep_pkg = graph.package_map[&dep_id]; for dep in deps { diff --git a/src/cargo/ops/tree/mod.rs b/src/cargo/ops/tree/mod.rs index 0940f0ebfad..1e535d9a679 100644 --- a/src/cargo/ops/tree/mod.rs +++ b/src/cargo/ops/tree/mod.rs @@ -132,6 +132,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() ForceAllTargets::No }; let dry_run = false; + println!("Requested kinds: {:?}", requested_kinds); let ws_resolve = ops::resolve_ws_with_opts( ws, &mut target_data, @@ -143,11 +144,33 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() dry_run, )?; + // println!("{:#?}", ws_resolve.pkg_set.packages().map(|pkg| pkg.package_id()).collect::>()); + // let thing = ws_resolve.pkg_set.packages().flat_map(|pkg| pkg.) + println!("Requested kinds after resolving: {:?}", requested_kinds); + let package_map: HashMap = ws_resolve .pkg_set .packages() - .map(|pkg| (pkg.package_id(), pkg)) + .map(|pkg| (pkg.package_id(), pkg)) // TODO here??? .collect(); + // println!("PACKAGE SET {:#?}", ws_resolve.pkg_set.packages_debug().collect::>()); + // the package_map is 3 things: foo, bar, and "None", meaning the baz cell has not been initialized + // println!("Resolver pkg_set {:#?}", ws_resolve.pkg_set.packages_debug().collect::>()); + + // let package_map2: HashMap = ws_resolve + // .pkg_set + // .packages() + // .flat_map(|pkg| ( + // [(pkg.package_id(), pkg)].iter().chain( + // pkg.dependencies().iter().map(|dep| ((dep.package_name(), dep.version_req(), dep.source_id()), dep)) + // ) + // ) + // ) // TODO here??? + // .collect(); + + // pkg.dependencies().into_iter().map(|dep| ((dep.package_name(), dep.version_req(), dep.source_id()), dep)) + // somehow artifact dep deps aren't showing up in this package_map + // either change this mapping above or stop conflating package and dependency let mut graph = graph::build( ws, diff --git a/src/cargo/util/toml_mut/dependency.rs b/src/cargo/util/toml_mut/dependency.rs index 5e0e437e8f6..48ebe7ad5d9 100644 --- a/src/cargo/util/toml_mut/dependency.rs +++ b/src/cargo/util/toml_mut/dependency.rs @@ -14,7 +14,6 @@ use crate::core::SourceId; use crate::core::Summary; use crate::core::{Features, GitReference}; use crate::util::toml::lookup_path_base; -use crate::util::toml_mut::is_sorted; use crate::CargoResult; use crate::GlobalContext; @@ -639,7 +638,7 @@ impl Dependency { .collect::>>() }) .unwrap_or_default(); - let is_already_sorted = is_sorted(features.iter()); + let is_already_sorted = features.iter().is_sorted(); features.extend(new_features.iter().map(|s| s.as_str())); let features = if is_already_sorted { features.into_iter().sorted().collect::() diff --git a/src/cargo/util/toml_mut/mod.rs b/src/cargo/util/toml_mut/mod.rs index 1da707ea192..2cfa7556896 100644 --- a/src/cargo/util/toml_mut/mod.rs +++ b/src/cargo/util/toml_mut/mod.rs @@ -12,19 +12,3 @@ pub mod dependency; pub mod manifest; pub mod upgrade; - -// Based on Iterator::is_sorted from nightly std; remove in favor of that when stabilized. -pub fn is_sorted(mut it: impl Iterator) -> bool { - let Some(mut last) = it.next() else { - return true; - }; - - for curr in it { - if curr < last { - return false; - } - last = curr; - } - - true -} diff --git a/src/doc/src/guide/continuous-integration.md b/src/doc/src/guide/continuous-integration.md index d9f14de9b41..0d69f908743 100644 --- a/src/doc/src/guide/continuous-integration.md +++ b/src/doc/src/guide/continuous-integration.md @@ -165,6 +165,8 @@ jobs: name: Latest Dependencies runs-on: ubuntu-latest continue-on-error: true + env: + CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: allow steps: - uses: actions/checkout@v4 - run: rustup update stable && rustup default stable @@ -172,6 +174,9 @@ jobs: - run: cargo build --verbose - run: cargo test --verbose ``` +Notes: +- [`CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS`](../reference/config.md#resolverincompatible-rust-versions) is set to ensure the [resolver](../reference/resolver.md) doesn't limit selected dependencies because of your project's [Rust version](../reference/rust-version.md). + For projects with higher risks of per-platform or per-Rust version failures, more combinations may want to be tested. diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index 7360992459b..dc2decce5fb 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -1579,13 +1579,8 @@ foo v0.0.0 ([ROOT]/foo) .run(); } -/// From issue #10593 -/// The case where: -/// * artifact dep is { target = } -/// * dependency of that artifact dependency specifies the same target -/// * the target is not activated. #[cargo_test] -fn dep_of_artifact_dep_same_target_specified() { +fn no_artifact() { if cross_compile::disabled() { return; } @@ -1602,7 +1597,7 @@ fn dep_of_artifact_dep_same_target_specified() { resolver = "2" [dependencies] - bar = {{ path = "bar", artifact = "bin", target = "{target}" }} + bar = {{ path = "bar" }} "#, ), ) @@ -1620,14 +1615,13 @@ fn dep_of_artifact_dep_same_target_specified() { "#, ), ) - .file("bar/src/main.rs", "fn main() {}") + .file("bar/src/lib.rs", "") .file( "baz/Cargo.toml", r#" [package] name = "baz" version = "0.1.0" - "#, ) .file("baz/src/lib.rs", "") @@ -1637,8 +1631,7 @@ fn dep_of_artifact_dep_same_target_specified() { .masquerade_as_nightly_cargo(&["bindeps"]) .with_stderr_data(str![[r#" [LOCKING] 2 packages to latest compatible versions -[COMPILING] baz v0.1.0 ([ROOT]/foo/baz) -[COMPILING] bar v0.1.0 ([ROOT]/foo/bar) +[CHECKING] bar v0.1.0 ([ROOT]/foo/bar) [CHECKING] foo v0.1.0 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s @@ -1649,13 +1642,94 @@ fn dep_of_artifact_dep_same_target_specified() { // TODO This command currently fails due to a bug in cargo but it should be fixed so that it succeeds in the future. p.cargo("tree -Z bindeps") .masquerade_as_nightly_cargo(&["bindeps"]) - .with_stderr_data( - r#"... -no entry found for key -... -"#, + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) +"#]]) + .with_status(0) + .run(); +} + +/// From issue #10593 +/// The case where: +/// * artifact dep (bar) is { target = } +/// * dependency (bar) of that artifact dependency specifies the same target +/// * the target is not activated. +/// +/// * entry point is foo +/// * a dependency (baz) of an artifact dependency (bar) is platform specified +/// * artifact dep itself (bar) is { target = } with the same platform as its own dependency +/// * the platform is not activated. +#[cargo_test] +fn dep_of_artifact_dep_same_target_specified() { + if cross_compile::disabled() { + return; + } + let target = cross_compile::alternate(); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + resolver = "2" + + [dependencies] + bar = {{ path = "bar", artifact = "bin", target = "{target}" }} + "#, + ), ) - .with_status(101) + .file("src/lib.rs", "") + .file( + "bar/Cargo.toml", + &format!( + r#" + [package] + name = "bar" + version = "0.1.0" + + [target.{target}.dependencies] + baz = {{ path = "../baz" }} + "#, + ), + ) + .file("bar/src/main.rs", "fn main() {}") + .file( + "baz/Cargo.toml", + r#" + [package] + name = "baz" + version = "0.1.0" + "#, + ) + .file("baz/src/lib.rs", "") + .build(); + +// p.cargo("check -Z bindeps") +// .masquerade_as_nightly_cargo(&["bindeps"]) +// .with_stderr_data(str![[r#" +// [LOCKING] 2 packages to latest compatible versions +// [COMPILING] baz v0.1.0 ([ROOT]/foo/baz) +// [COMPILING] bar v0.1.0 ([ROOT]/foo/bar) +// [CHECKING] foo v0.1.0 ([ROOT]/foo) +// [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +// "#]]) +// .with_status(0) +// .run(); + + // TODO This command currently fails due to a bug in cargo but it should be fixed so that it succeeds in the future. + p.cargo("tree -Z bindeps") + .masquerade_as_nightly_cargo(&["bindeps"]) + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) +└── bar v0.1.0 ([ROOT]/foo/bar) + └── baz v0.1.0 ([ROOT]/foo/baz) + +"#]]) + .with_status(0) .run(); } @@ -2980,6 +3054,17 @@ fn decouple_same_target_transitive_dep_from_artifact_dep() { "#]]) .run(); + + p.cargo("tree -Z bindeps") + .masquerade_as_nightly_cargo(&["bindeps"]) + .with_stdout_data(str![[r#" +foo v0.1.0 ([ROOT]/foo) +└── bar v0.1.0 ([ROOT]/foo/bar) + └── baz v0.1.0 ([ROOT]/foo/baz) + +"#]]) + .with_status(0) + .run(); } #[cargo_test]