Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(settings): mark drop guard as !Send #695

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to insta and cargo-insta are documented here.

## Unreleased

- `insta::internals::SettingsBindDropGuard` (returned from
`Settings::bind_to_scope`) no longer implements `Send`. This was an error and
any tests relying on this behavior where not working properly.
Fixes #694 in #695 by @jalil-salame

## 1.41.1

- Re-release of 1.41.1 to generate release artifacts correctly.
Expand Down
25 changes: 23 additions & 2 deletions insta/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ impl Settings {
CURRENT_SETTINGS.with(|x| {
let mut x = x.borrow_mut();
let old = mem::replace(&mut x.inner, self.inner.clone());
SettingsBindDropGuard(Some(old))
SettingsBindDropGuard(Some(old), std::marker::PhantomData)
})
}

Expand All @@ -580,8 +580,29 @@ impl Settings {
}

/// Returned from [`Settings::bind_to_scope`]
///
/// This type is not shareable between threads:
///
/// ```compile_fail E0277
/// let mut settings = insta::Settings::clone_current();
/// settings.set_snapshot_suffix("test drop guard");
/// let guard = settings.bind_to_scope();
///
/// std::thread::spawn(move || { let guard = guard; }); // doesn't compile
/// ```
///
/// This is to ensure tests under async runtimes like `tokio` don't show unexpected results
#[must_use = "The guard is immediately dropped so binding has no effect. Use `let _guard = ...` to bind it."]
pub struct SettingsBindDropGuard(Option<Arc<ActualSettings>>);
pub struct SettingsBindDropGuard(
Option<Arc<ActualSettings>>,
/// A ZST that is not [`Send`] but is [`Sync`]
///
/// This is necessary due to the lack of stable [negative impls](https://github.com/rust-lang/rust/issues/68318).
///
/// Required as [`SettingsBindDropGuard`] modifies a thread local variable which would end up
/// with unexpected results if sent to a different thread.
std::marker::PhantomData<std::sync::MutexGuard<'static, ()>>,
);

impl Drop for SettingsBindDropGuard {
fn drop(&mut self) {
Expand Down