diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index d116c1e91..9bc4d8202 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -800,11 +800,9 @@ impl<'gctx> Registry for PackageRegistry<'gctx> { #[tracing::instrument(skip_all)] fn block_until_ready(&mut self) -> CargoResult<()> { - if cfg!(debug_assertions) { - // Force borrow to catch invalid borrows, regardless of which source is used and how it - // happens to behave this time - self.gctx.shell().verbosity(); - } + // Ensure `shell` is not already in use, + // regardless of which source is used and how it happens to behave this time + self.gctx.debug_assert_shell_not_borrowed(); for (source_id, source) in self.sources.sources_mut() { source .block_until_ready() diff --git a/src/cargo/util/context/mod.rs b/src/cargo/util/context/mod.rs index 62b04113f..1a03e4b58 100644 --- a/src/cargo/util/context/mod.rs +++ b/src/cargo/util/context/mod.rs @@ -412,6 +412,17 @@ impl GlobalContext { self.shell.borrow_mut() } + /// Assert [`Self::shell`] is not in use + /// + /// Testing might not identify bugs with two accesses to `shell` at once + /// due to conditional logic, + /// so place this outside of the conditions to catch these bugs in more situations. + pub fn debug_assert_shell_not_borrowed(&self) { + if cfg!(debug_assertions) { + self.shell().verbosity(); + } + } + /// Gets the path to the `rustdoc` executable. pub fn rustdoc(&self) -> CargoResult<&Path> { self.rustdoc diff --git a/src/cargo/util/flock.rs b/src/cargo/util/flock.rs index 9c929de99..e82465e89 100644 --- a/src/cargo/util/flock.rs +++ b/src/cargo/util/flock.rs @@ -389,10 +389,9 @@ fn acquire( lock_try: &dyn Fn() -> Result<(), TryLockError>, lock_block: &dyn Fn() -> io::Result<()>, ) -> CargoResult<()> { - if cfg!(debug_assertions) { - // Force borrow to catch invalid borrows outside of contention situations - gctx.shell().verbosity(); - } + // Ensure `shell` is not already in use, + // regardless of whether we hit contention or not + gctx.debug_assert_shell_not_borrowed(); if try_acquire(path, lock_try)? { return Ok(()); }