Skip to content

Commit

Permalink
Strip mut from test patterns, release 0.4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
djkoloski committed Feb 22, 2025
1 parent b9a3594 commit 02e7be5
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 14 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ members = [
resolver = "2"

[workspace.package]
version = "0.4.1"
version = "0.4.2"
authors = ["David Koloski <[email protected]>"]
edition = "2021"
edition = "2024"
license = "MIT"
readme = "README.md"
repository = "https://github.com/djkoloski/munge"
keywords = ["macro", "no_std"]
categories = ["no-std", "no-std::no-alloc", "rust-patterns"]

[workspace.dependencies]
munge_macro = { version = "=0.4.1", default-features = false, path = "munge_macro" }
munge_macro = { version = "=0.4.2", default-features = false, path = "munge_macro" }
proc-macro2 = { version = "1", default-features = false }
quote = { version = "1", default-features = false }
rustversion = { version = "1", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion munge/src/__macro.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::{hint::unreachable_unchecked, marker::PhantomData};

use crate::{internal, Borrow, Destructure, Restructure};
use crate::{Borrow, Destructure, Restructure, internal};

pub fn make_destructurer<T: Destructure>(
value: T,
Expand Down
2 changes: 1 addition & 1 deletion munge/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::{
cell::{Cell, UnsafeCell},
mem::{transmute, ManuallyDrop, MaybeUninit},
mem::{ManuallyDrop, MaybeUninit, transmute},
ptr::read,
};

Expand Down
4 changes: 2 additions & 2 deletions munge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,8 @@ mod tests {
// SAFETY: `mu` is completely initialized.
let init = unsafe { mu.assume_init() };
assert_eq!(init.0, 1);
assert_eq!(init.1 .0, 2);
assert_eq!(init.1 .1, 'a');
assert_eq!(init.1.0, 2);
assert_eq!(init.1.1, 'a');
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion munge_macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ proc-macro = true
[dependencies]
proc-macro2.workspace = true
quote.workspace = true
syn = { workspace = true, features = ["full", "parsing", "printing", "proc-macro"] }
syn = { workspace = true, features = ["clone-impls", "full", "parsing", "printing", "proc-macro"] }
88 changes: 82 additions & 6 deletions munge_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned};
use syn::{
parse, parse_macro_input,
Error, Expr, FieldPat, Index, Pat, PatIdent, PatRest, PatSlice, PatStruct,
PatTuple, PatTupleStruct, Path, parse, parse_macro_input,
punctuated::Punctuated,
spanned::Spanned,
token::{Eq, FatArrow, Let, Semi},
Error, Expr, Index, Pat, PatRest, PatTuple, PatTupleStruct, Path,
};

/// Destructures a value by projecting pointers.
Expand Down Expand Up @@ -209,11 +209,84 @@ fn parse_pat(
return Err(Error::new_spanned(
pat,
"expected a destructuring pattern",
))
));
}
})
}

fn strip_mut(pat: &Pat) -> Result<Pat, Error> {
Ok(match pat {
Pat::Ident(pat_ident) => Pat::Ident(PatIdent {
attrs: pat_ident.attrs.clone(),
by_ref: None,
mutability: None,
ident: pat_ident.ident.clone(),
subpat: if let Some((at, pat)) = pat_ident.subpat.as_ref() {
Some((*at, Box::new(strip_mut(pat)?)))
} else {
None
},
}),
Pat::Tuple(pat_tuple) => {
let mut elems = Punctuated::new();
for elem in pat_tuple.elems.iter() {
elems.push(strip_mut(elem)?);
}
Pat::Tuple(PatTuple {
attrs: pat_tuple.attrs.clone(),
paren_token: pat_tuple.paren_token,
elems,
})
}
Pat::TupleStruct(pat_tuple_struct) => {
let mut elems = Punctuated::new();
for elem in pat_tuple_struct.elems.iter() {
elems.push(strip_mut(elem)?);
}
Pat::TupleStruct(PatTupleStruct {
attrs: pat_tuple_struct.attrs.clone(),
qself: pat_tuple_struct.qself.clone(),
path: pat_tuple_struct.path.clone(),
paren_token: pat_tuple_struct.paren_token,
elems,
})
}
Pat::Slice(pat_slice) => {
let mut elems = Punctuated::new();
for elem in pat_slice.elems.iter() {
elems.push(strip_mut(elem)?);
}
Pat::Slice(PatSlice {
attrs: pat_slice.attrs.clone(),
bracket_token: pat_slice.bracket_token,
elems,
})
}
Pat::Struct(pat_struct) => {
let mut fields = Punctuated::new();
for field in pat_struct.fields.iter() {
fields.push(FieldPat {
attrs: field.attrs.clone(),
member: field.member.clone(),
colon_token: field.colon_token,
pat: Box::new(strip_mut(&field.pat)?),
});
}
Pat::Struct(PatStruct {
attrs: pat_struct.attrs.clone(),
qself: pat_struct.qself.clone(),
path: pat_struct.path.clone(),
brace_token: pat_struct.brace_token,
fields,
rest: pat_struct.rest.clone(),
})
}
Pat::Rest(pat_rest) => Pat::Rest(pat_rest.clone()),
Pat::Wild(pat_wild) => Pat::Wild(pat_wild.clone()),
_ => todo!(),
})
}

fn destructure(input: Input) -> Result<TokenStream, Error> {
let crate_path = &input.crate_path;

Expand All @@ -222,6 +295,8 @@ fn destructure(input: Input) -> Result<TokenStream, Error> {
let pat = &destructure.pat;
let expr = &destructure.expr;

let test_pat = strip_mut(pat)?;

let (bindings, exprs) = parse_pat(crate_path, pat)?;

result.extend(quote! {
Expand All @@ -244,9 +319,10 @@ fn destructure(input: Input) -> Result<TokenStream, Error> {
// SAFETY: This can never be called.
unsafe {
::core::hint::unreachable_unchecked();
let #pat = #crate_path::__macro::test_destructurer(
&mut destructurer,
);
let #test_pat =
#crate_path::__macro::test_destructurer(
&mut destructurer,
);
}
}

Expand Down

0 comments on commit 02e7be5

Please sign in to comment.