Indeed. In this instance, you may be interested in the .{fold,visit}_expr_struct{,_mut}() variants of the diverse AST-traversal traits, since that's the Expr "kind" that matches a literal struct construction.
From there, you can (after sub-recursing!), look at the .path field, and see if the .last() of its (path .segments) has an .ident that is equal to MyStruct.
But be aware that basing the analysis on syntax only and not semantics is a bit brittle (what if somebody has their::own::MyStruct which has nothing to do with your macro? Inversely, what if somebody did use MyStruct as Renamed;, and then used Renamed { ...}?)
Thanks again @Yandros for the additional insights that answers some follow-on questions, and will help.
I take your point.
Yes, if my proposal was accepted MyStruct would become something of a reserved word in the library. As I reflect on it I don't suppose there is anything lost by adding a segment to the path, and matching on, buyin::MyStruct. Is this what you meant by also using semantics?
Correct. I don't think I can guard against this - unless the AST holds this information?
In which case I'd have to add a feature to the roadmap, about making this more robust.
This "feature" does require you "buy-in" and commit to respecting a naming convention. It is an opt-in feature, so hopefully won't be too controversial for the community.
Overall, I'm not sure how else I could set things up so that library users could 'plugin' their own desired behavior - MyStruct { f1, f2, f3 } is effectively serving as compile-time plugin API (along with some functions) with which they can Cargo [patch] in their implementation.
Hmm, that was wrong.
The compile-time plugin API is, I think, some proc-macro-attributes. The lib user then provides their implementation of some callback-style functions (based on a template crate - a 80/20 rule starting point). Their proc-macro implementation is [patch]ed in via their application crate Cargo.toml, or some .cargo/config.toml
One such function is invoked on matching buyin::MyStruct{f1,f2,f3} - because they have a proc-macro template to start from, they could remove this functionality entirely. Which is a feature - I don't want to tie their hands, nor step on their feet - as you've pointed out above.
All they need to do is respect the proc-macro-attribute syntax used in the template, and some naming conventions and they are free to do as they wish - the audience is developers.
At least, that is the hope, and I'm open to suggestions or pointers to crates that have done this a better way.