Proc macro pass on all content until closing delimeter

I'm trying to write a proc macro which contains some sections wrapped in matching delimiters.

After the opening delimiter there is some content that is transformed by the macro. After that, there is some content which the macro should not transform at all, simply passing it on unadulterated, until we reach the matching closing delimiter, at which point the macro should start transforming the input once more:

(                 // Opening delimeter
  "foo" bar "baz" // Content the macro should transform
  f(a) + g(b, c)  // Content that should be passed on as is
)                 // Closing delimiter 

I'm using parsel to write this, so the contents of the parentheses in the above example might be expressed something like this

#[derive(PartialEq, Eq, Debug, Parse, ToTokens)]
struct Example {
    pre: LitStr,
    bar: Maybe<kw::bar, LitStr>,
    pass_on: Any<???>,

but I'm struggling figure out what should replace the ???.

I get the impression that I'm not seeing the wood for the trees.

Is there a simple way to do this?

Maybe ??? could be replaced with TokenTree?

That was my first guess too. It leads to errors about lack of implementation of Parse and ToTokens, which are beyond my reach because of the orphan rule. My attempts to hack around it with a newtype pattern, run into all sorts of other problems.

Huh, looks to me like Parse and ToTokens is implemented for TokenTree. Maybe you are importing TokenTree from proc_macro/proc_macro2 and not from parsel/proc_macro2 (parsel's TokenTree is a re-export of proc_macro2::TokenTree, see below)?

1 Like

Parsel reexports all basic types and traits from proc_macro2 and syn, so it must be proc_macro getting somewhere in the mix.


You are absolutely right, TokenTree from parsel is a reexport of the one from proc_macro2.

Explicitly specifying parsel::TokenTree was the key to the solution.

Unfortunately it doesn't implement Eq, and given that I copied the derive(... Eq) from the example in the parsel docs, I must have assumed that it was crucial to the whole lot working, because I do recall coming across this problem when poking around earlier and I think it did throw me off the path. Removing the derives for PartialEq, Eq for this and any enclosing type fixes the problem.

Thank you both for your help.

No. All of parsel's derive macros are self-contained. The AST nodes are never being read, compared for equality (or inequality), hashed, or inspected in any other way by Parsel in the Parse and FromStr derives (and they are only used in plain old match expressions by the ToTokens and Display macros). There is no requirement to manually couple other derives with any of the derive macros exported by Parsel.

The documentation adds the usual derives because it's good practice to do so, as outlined in the Rust API guidelines; I was striving for high-quality code in the examples.

Not blaming you for anything. I'm entirely guilty of having made a false inference in the heat of the moment.

Many thanks for the excellent crate!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.