aboutsummaryrefslogtreecommitdiff
path: root/src/select.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/select.rs')
-rw-r--r--src/select.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/select.rs b/src/select.rs
index ddb2e6a..23e280a 100644
--- a/src/select.rs
+++ b/src/select.rs
@@ -41,3 +41,70 @@ pub(crate) fn declare_output_enum(input: TokenStream) -> TokenStream {
pub(super) type Mask = #mask;
})
}
+
+pub(crate) fn clean_pattern_macro(input: TokenStream) -> TokenStream {
+ // If this isn't a pattern, we return the token stream as-is. The select!
+ // macro is using it in a location requiring a pattern, so an error will be
+ // emitted there.
+ let mut input: syn::Pat = match syn::parse(input.clone()) {
+ Ok(it) => it,
+ Err(_) => return input,
+ };
+
+ clean_pattern(&mut input);
+ quote::ToTokens::into_token_stream(input).into()
+}
+
+// Removes any occurrences of ref or mut in the provided pattern.
+fn clean_pattern(pat: &mut syn::Pat) {
+ match pat {
+ syn::Pat::Box(_box) => {}
+ syn::Pat::Lit(_literal) => {}
+ syn::Pat::Macro(_macro) => {}
+ syn::Pat::Path(_path) => {}
+ syn::Pat::Range(_range) => {}
+ syn::Pat::Rest(_rest) => {}
+ syn::Pat::Verbatim(_tokens) => {}
+ syn::Pat::Wild(_underscore) => {}
+ syn::Pat::Ident(ident) => {
+ ident.by_ref = None;
+ ident.mutability = None;
+ if let Some((_at, pat)) = &mut ident.subpat {
+ clean_pattern(&mut *pat);
+ }
+ }
+ syn::Pat::Or(or) => {
+ for case in or.cases.iter_mut() {
+ clean_pattern(case);
+ }
+ }
+ syn::Pat::Slice(slice) => {
+ for elem in slice.elems.iter_mut() {
+ clean_pattern(elem);
+ }
+ }
+ syn::Pat::Struct(struct_pat) => {
+ for field in struct_pat.fields.iter_mut() {
+ clean_pattern(&mut field.pat);
+ }
+ }
+ syn::Pat::Tuple(tuple) => {
+ for elem in tuple.elems.iter_mut() {
+ clean_pattern(elem);
+ }
+ }
+ syn::Pat::TupleStruct(tuple) => {
+ for elem in tuple.pat.elems.iter_mut() {
+ clean_pattern(elem);
+ }
+ }
+ syn::Pat::Reference(reference) => {
+ reference.mutability = None;
+ clean_pattern(&mut *reference.pat);
+ }
+ syn::Pat::Type(type_pat) => {
+ clean_pattern(&mut *type_pat.pat);
+ }
+ _ => {}
+ }
+}