Skip to content

Commit bfe1703

Browse files
authored
fix: mut ownership doesn't work (#60)
1 parent 1025d20 commit bfe1703

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

test-context-macros/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub fn test_context(attr: TokenStream, item: TokenStream) -> TokenStream {
4040

4141
let context_arg = context_args.into_iter().next().unwrap();
4242

43-
if !args.skip_teardown && context_arg.mode == ContextArgMode::Owned {
43+
if !args.skip_teardown && context_arg.mode.is_owned() {
4444
panic!(
4545
"It is not possible to take ownership of the context if the teardown has to be ran."
4646
);
@@ -97,6 +97,7 @@ fn refactor_input_body(
9797

9898
let context_binding = match context_arg.mode {
9999
ContextArgMode::Owned => quote! { let #context_arg_name = __context; },
100+
ContextArgMode::OwnedMut => quote! { let mut #context_arg_name = __context; },
100101
ContextArgMode::Reference => quote! { let #context_arg_name = &__context; },
101102
ContextArgMode::MutableReference => quote! { let #context_arg_name = &mut __context; },
102103
};

test-context-macros/src/test_args.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,25 @@ pub struct ContextArg {
1313
pub enum ContextArgMode {
1414
/// The argument was passed as an owned value (`ContextType`). Only valid with `skip_teardown`.
1515
Owned,
16+
/// The argument was passed as an owned value (mut `ContextType`). Only valid with `skip_teardown`.
17+
OwnedMut,
1618
/// The argument was passed as an immutable reference (`&ContextType`).
1719
Reference,
1820
/// The argument was passed as a mutable reference (`&mut ContextType`).
1921
MutableReference,
2022
}
2123

24+
impl ContextArgMode {
25+
pub fn is_owned(&self) -> bool {
26+
match self {
27+
ContextArgMode::Owned => true,
28+
ContextArgMode::OwnedMut => true,
29+
ContextArgMode::Reference => false,
30+
ContextArgMode::MutableReference => false,
31+
}
32+
}
33+
}
34+
2235
#[derive(Clone)]
2336
pub enum TestArg {
2437
Any(FnArg),
@@ -47,9 +60,18 @@ impl TestArg {
4760
mode,
4861
})
4962
} else if types_equal(arg_type, expected_context_type) {
63+
// To determine mutability for an owned type, we check the identifier pattern.
64+
let mode = if pat_ident.mutability.is_some() {
65+
// This catches signatures like: `mut my_ctx: ContextType`
66+
ContextArgMode::OwnedMut
67+
} else {
68+
// This catches signatures like: `my_ctx: ContextType`
69+
ContextArgMode::Owned
70+
};
71+
5072
TestArg::Context(ContextArg {
5173
name: pat_ident.ident.clone(),
52-
mode: ContextArgMode::Owned,
74+
mode,
5375
})
5476
} else {
5577
TestArg::Any(arg)

test-context/tests/test.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ async fn test_async_skip_teardown_with_immutable_ref(_ctx: &TeardownPanicContext
182182
#[tokio::test]
183183
async fn test_async_skip_teardown_with_full_ownership(_ctx: TeardownPanicContext) {}
184184

185+
#[test_context(TeardownPanicContext, skip_teardown)]
186+
#[tokio::test]
187+
async fn test_async_skip_teardown_with_full_mut_ownership(mut ctx: TeardownPanicContext) {
188+
let _test = &mut ctx;
189+
}
190+
185191
#[test_context(TeardownPanicContext, skip_teardown)]
186192
#[test]
187193
fn test_sync_skip_teardown(_ctx: &mut TeardownPanicContext) {}
@@ -194,6 +200,12 @@ fn test_sync_skip_teardown_with_immutable_ref(_ctx: &TeardownPanicContext) {}
194200
#[test]
195201
fn test_sync_skip_teardown_with_full_ownership(_ctx: TeardownPanicContext) {}
196202

203+
#[test_context(TeardownPanicContext, skip_teardown)]
204+
#[test]
205+
fn test_sync_skip_teardown_with_full_mut_ownership(mut ctx: TeardownPanicContext) {
206+
let _test = &mut ctx;
207+
}
208+
197209
struct GenericContext<T> {
198210
contents: T,
199211
}

0 commit comments

Comments
 (0)