diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index bc4c15b88d9d..630c2119ecc2 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -1,4 +1,4 @@ -use super::job::{Freshness, Job, Work}; +use super::job::{Job, Work}; use super::{fingerprint, Context, LinkType, Unit}; use crate::core::compiler::artifact; use crate::core::compiler::context::Metadata; @@ -488,7 +488,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult { } else { fingerprint::prepare_target(cx, unit, false)? }; - if job.freshness() == Freshness::Dirty { + if job.freshness().is_dirty() { job.before(dirty); } else { job.before(fresh); diff --git a/src/cargo/core/compiler/fingerprint/dirty_reason.rs b/src/cargo/core/compiler/fingerprint/dirty_reason.rs index 025aa8ee1c2b..90ec85217b53 100644 --- a/src/cargo/core/compiler/fingerprint/dirty_reason.rs +++ b/src/cargo/core/compiler/fingerprint/dirty_reason.rs @@ -4,7 +4,7 @@ use crate::core::Shell; use crate::Config; use std::fmt; -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum DirtyReason { RustcChanged, FeaturesChanged { @@ -84,6 +84,7 @@ impl DirtyReason { } } +#[derive(Clone)] #[allow(dead_code)] // fields to be used in the future pub struct DirtyReasonDeps { pub(super) old: Vec, @@ -96,6 +97,7 @@ impl fmt::Debug for DirtyReasonDeps { } } +#[derive(Clone)] pub struct FsStatusOutdated(FsStatus); impl FsStatusOutdated { diff --git a/src/cargo/core/compiler/job.rs b/src/cargo/core/compiler/job.rs index 75fe98b3db71..4d660aab41a9 100644 --- a/src/cargo/core/compiler/job.rs +++ b/src/cargo/core/compiler/job.rs @@ -8,8 +8,6 @@ use crate::util::CargoResult; pub struct Job { work: Work, fresh: Freshness, - - dirty_reason: Option, } /// Each proc should send its description before starting. @@ -48,7 +46,6 @@ impl Job { Job { work: Work::noop(), fresh: Freshness::Fresh, - dirty_reason: None, } } @@ -56,8 +53,7 @@ impl Job { pub fn new_dirty(work: Work, dirty_reason: Option) -> Job { Job { work, - fresh: Freshness::Dirty, - dirty_reason, + fresh: Freshness::Dirty(dirty_reason), } } @@ -70,18 +66,14 @@ impl Job { /// Returns whether this job was fresh/dirty, where "fresh" means we're /// likely to perform just some small bookkeeping where "dirty" means we'll /// probably do something slow like invoke rustc. - pub fn freshness(&self) -> Freshness { - self.fresh + pub fn freshness(&self) -> &Freshness { + &self.fresh } pub fn before(&mut self, next: Work) { let prev = mem::replace(&mut self.work, Work::noop()); self.work = next.then(prev); } - - pub fn dirty_reason(&self) -> Option<&DirtyReason> { - self.dirty_reason.as_ref() - } } impl fmt::Debug for Job { @@ -94,8 +86,31 @@ impl fmt::Debug for Job { /// /// A fresh package does not necessarily need to be rebuilt (unless a dependency /// was also rebuilt), and a dirty package must always be rebuilt. -#[derive(PartialEq, Eq, Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub enum Freshness { + Fresh, + Dirty(Option), +} + +impl Freshness { + pub fn is_dirty(&self) -> bool { + matches!(self, Freshness::Dirty(_)) + } + + pub fn is_fresh(&self) -> bool { + matches!(self, Freshness::Fresh) + } + + pub fn kind(&self) -> FreshnessKind { + match self { + Freshness::Fresh => FreshnessKind::Fresh, + Freshness::Dirty(_) => FreshnessKind::Dirty, + } + } +} + +#[derive(Copy, Clone, Debug)] +pub enum FreshnessKind { Fresh, Dirty, } diff --git a/src/cargo/core/compiler/job_queue.rs b/src/cargo/core/compiler/job_queue.rs index ef8f2198f544..d09b03ea19a7 100644 --- a/src/cargo/core/compiler/job_queue.rs +++ b/src/cargo/core/compiler/job_queue.rs @@ -71,10 +71,10 @@ use super::job::{ }; use super::timings::Timings; use super::{BuildContext, BuildPlan, CompileMode, Context, Unit}; -use crate::core::compiler::fingerprint::DirtyReason; use crate::core::compiler::future_incompat::{ self, FutureBreakageItem, FutureIncompatReportPackage, }; +use crate::core::compiler::job::FreshnessKind; use crate::core::resolver::ResolveBehavior; use crate::core::{PackageId, Shell, TargetKind}; use crate::util::diagnostic_server::{self, DiagnosticPrinter}; @@ -676,7 +676,7 @@ impl<'cfg> DrainState<'cfg> { // NOTE: An error here will drop the job without starting it. // That should be OK, since we want to exit as soon as // possible during an error. - self.note_working_on(cx.bcx.config, &unit, job.freshness(), job.dirty_reason())?; + self.note_working_on(cx.bcx.config, &unit, job.freshness())?; } self.run(&unit, job, cx, scope); } @@ -1115,7 +1115,7 @@ impl<'cfg> DrainState<'cfg> { assert!(self.active.insert(id, unit.clone()).is_none()); let messages = self.messages.clone(); - let fresh = job.freshness(); + let fresh = job.freshness().kind(); // closure below moves job, cannot keep `&Freshness` let rmeta_required = cx.rmeta_required(unit); let doit = move |state: JobState<'_, '_>| { @@ -1167,7 +1167,7 @@ impl<'cfg> DrainState<'cfg> { }; match fresh { - Freshness::Fresh => { + FreshnessKind::Fresh => { self.timings.add_fresh(); // Running a fresh job on the same thread is often much faster than spawning a new // thread to run the job. @@ -1179,7 +1179,7 @@ impl<'cfg> DrainState<'cfg> { _marker: marker::PhantomData, }); } - Freshness::Dirty => { + FreshnessKind::Dirty => { self.timings.add_dirty(); scope.spawn(move || { doit(JobState { @@ -1342,8 +1342,7 @@ impl<'cfg> DrainState<'cfg> { &mut self, config: &Config, unit: &Unit, - fresh: Freshness, - dirty_reason: Option<&DirtyReason>, + fresh: &Freshness, ) -> CargoResult<()> { if (self.compiled.contains(&unit.pkg.package_id()) && !unit.mode.is_doc() @@ -1357,7 +1356,7 @@ impl<'cfg> DrainState<'cfg> { match fresh { // Any dirty stage which runs at least one command gets printed as // being a compiled package. - Dirty => { + Dirty(dirty_reason) => { if unit.mode.is_doc() { self.documented.insert(unit.pkg.package_id()); config.shell().status("Documenting", &unit.pkg)?; diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 2376db463884..e7bd5bf97607 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -167,7 +167,7 @@ fn compile<'cfg>( } else { let force = exec.force_rebuild(unit) || force_rebuild; let mut job = fingerprint::prepare_target(cx, unit, force)?; - job.before(if job.freshness() == Freshness::Dirty { + job.before(if job.freshness().is_dirty() { let work = if unit.mode.is_doc() || unit.mode.is_doc_scrape() { rustdoc(cx, unit)? } else { diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index ea933ce08142..72bcb41c8d59 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use std::{env, fs}; -use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, Freshness, UnitOutput}; +use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, UnitOutput}; use crate::core::{Dependency, Edition, Package, PackageId, Source, SourceId, Workspace}; use crate::ops::CompileFilter; use crate::ops::{common_for_install_and_uninstall::*, FilterRule}; @@ -683,7 +683,7 @@ fn is_installed( let tracker = InstallTracker::load(config, root)?; let (freshness, _duplicates) = tracker.check_upgrade(dst, pkg, force, opts, target, &rustc.verbose_version)?; - Ok(freshness == Freshness::Fresh) + Ok(freshness.is_fresh()) } /// Checks if vers can only be satisfied by exactly one version of a package in a registry, and it's diff --git a/src/cargo/ops/common_for_install_and_uninstall.rs b/src/cargo/ops/common_for_install_and_uninstall.rs index 6b8e8d792aa0..1762f9a241d0 100644 --- a/src/cargo/ops/common_for_install_and_uninstall.rs +++ b/src/cargo/ops/common_for_install_and_uninstall.rs @@ -170,7 +170,7 @@ impl InstallTracker { // Check if any tracked exe's are already installed. let duplicates = self.find_duplicates(dst, &exes); if force || duplicates.is_empty() { - return Ok((Freshness::Dirty, duplicates)); + return Ok((Freshness::Dirty(None), duplicates)); } // Check if all duplicates come from packages of the same name. If // there are duplicates from other packages, then --force will be @@ -200,7 +200,7 @@ impl InstallTracker { let source_id = pkg.package_id().source_id(); if source_id.is_path() { // `cargo install --path ...` is always rebuilt. - return Ok((Freshness::Dirty, duplicates)); + return Ok((Freshness::Dirty(None), duplicates)); } let is_up_to_date = |dupe_pkg_id| { let info = self @@ -224,7 +224,7 @@ impl InstallTracker { if matching_duplicates.iter().all(is_up_to_date) { Ok((Freshness::Fresh, duplicates)) } else { - Ok((Freshness::Dirty, duplicates)) + Ok((Freshness::Dirty(None), duplicates)) } } else { // Format the error message.