Comments (11)
FYI, this is one of the main things I dislike in Rust's syntax because of the typing overhead and the fact that pretty much any tokens are valid in #[here]
. Using @Foo(param=foo)
(or #[Foo(param=foo)]
if you like typing braces) and supporting exactly this style of calling a macro would reduce complexity quite a bit.
from rune.
FYI, this is one of the main things I dislike in Rust's syntax because of the typing overhead and the fact that pretty much any tokens are valid in
#[here]
. Using@Foo(param=foo)
(or#[Foo(param=foo)]
if you like typing braces) and supporting exactly this style of calling a macro would reduce complexity quite a bit.
I appreciate the point of view. But this is another instance when I want to maintain feature parity with Rust to make it possible to more easily transfer ideas. A note is that attributes are pretty much macro calls with different call syntax (and are associated with the AST they are tacked on to). You can see this in syn
, with the Macro
(macro call) and Attribute
. They both take a Path
and a raw TokenStream
.
syn
also provides a convenience function to parse its content as meta items. Something like this can be done to unobtrusively enforce more opinion. Or something like darling
can be ported to Rune.
from rune.
Might look into this in the next few days, what should be the input of a function handling a macro? everything after the path? or should it only be the "input" as it is in rust: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros i.e. if you call #[attribute(some_input)] the macro implementation would only get some_input
and not (some_input)
.
from rune.
Doing it in the same way as Rust sounds good to me.
from rune.
this would mean, that a macro could not detect whether they got #[path(...)]
, #[path[...]]
, #[path={...}
or #[path = ...]
. Though I guess that should be fine, as it would be strange to have a different behavior depending on the exact syntax used to invoke (similar to how normal macros also don't differentiate`.
from rune.
I think so, all though I must admit I'm not sure what happens with the #[path = ..]
variant 😅. I'm guessing ..
is what's being fed in? The =
is mentioned in the reference as part of meta syntax. Or is it not supported for proc-macro's?
from rune.
IIRC it is not supported for the actual macro, only for it's helper macros.
I guess this information could also just be added to the AttributeMacroContext
.
I.e. outer vs inner, what kind of delimiter was used etc., though I could also see an argument be made that this is just preference of the macro user, and the macro dev shouldn't try to enforce anything.
AFAICT we need to have a bunch of seperate types for the attribute macros anyway, as they e.g. in the AttributeMacroContext
would need to have input_span
and item_span
instead of only stream_span
.
As we have builtin ast which is different from rust's proc-macros, we could also have the attribute macro input be something like syn's https://docs.rs/syn/latest/syn/enum.Meta.html instead of a plain token_stream.
from rune.
As we have builtin ast which is different from rust's proc-macros, we could also have the attribute macro input be something like syn's https://docs.rs/syn/latest/syn/enum.Meta.html instead of a plain token_stream.
I'd be a bit careful with that. Even in Rust a meta item is only defined to the extent that it is used as a convention for most built-in macros. I frequently include things which is not valid meta
type syntax in macros (types, patterns, bounds, ...). If a macro wants the meta syntax, they can opt to parse it out and there's really no difference in diagnostics.
If I'm being honest, I'd probably prefer specialized AST constructs derived in many cases instead of using generic containers such as syn::Meta
(which you'd need to decompose / parse further anyway). Many attribute parsing needs can then be done by derives, like:
// Parses `= "<string>"` in an a `#[path]` attribute.
#[derive(Parse, ToTokens, Spanned)]
pub struct PathValue(T![=], LitStr);
The benefit here is that instead of having to match out syn::Meta::NameValue
and match out its expression to a literal string or raise an error, that happens during the first round of parsing instead.
from rune.
I'd be a bit careful with that. Even in Rust a meta item is only defined to the extent that it is used as a convention for most built-in macros. I frequently include things which is not valid
meta
type syntax in macros (types, patterns, bounds, ...). If a macro wants the meta syntax, they can opt to parse it out and there's really no difference in diagnostics.
Actually in syn2, the MetaList variant contains unparsed tokenstreams, so it would only enforce that the top level macro matches meta which (at least in rust) is enforced by the syntax itself, but I agree that having the derived Parse is quite nice, and you would lose that when preparsed in some way.
Another place where this question arises is with the item, as an attribute macro can be applied only to valid items (and attributes themselves also to modules, statements and fields/params) the item could also be forwarded in it's parsed form, though the same argument could be applied here, that one could want to call ItemFn::parse directly instead of matching on the Item.
from rune.
One future question is, should macros be able to have helper attributes, like rust derive macros have? I.e. attributes that will be ignored when not in scope instead of raising an error.
In rust, only derive macros can have them, attribute macros need to clean them up themselves.
from rune.
Derive macros should definitely declare and have their helper attributes cleaned up by the compiler. The reason there would be that other than removing those attributes the original item remains untouched. Anything added is added as separate items after it. It can safely be punted on, since I don't think there's any particular infrastructure overlap in the compiler between the two, but I might be wrong! Unless you want to implement derives as well.
For attribute macros, do what Rust does basically 😄 (unless there's a really good reason). Which I think amounts to "follow a top to bottom expansion order, unless nested macros are present". But no helper attributes.
from rune.
Related Issues (20)
- Feature request: Warn about unused Result HOT 1
- rune_modules 0.13.3: Incorrect dependencies between features
- More descriptive errors (file and line, what it was trying to do) HOT 4
- Formatting screwup on inline block comment HOT 1
- Strange formatting on comment at end of block
- Flaky auto-formatting in vscode / Rune LSP crashes
- Broken auto-formatting for consecutive single line comments HOT 2
- Panic in rune-internal tracing logging while formatting anyhow `Result` wrapped in rune `Value` HOT 5
- Silly auto-formatting for chained method calls / builder pattern HOT 1
- Output capture on process in rune-modules is non-functional HOT 2
- Can not use vm_result on function taking `&mut self`
- Runes `std::collections::HashMap` is not accessible from rust extension types
- Missing docs for `#[rune::function(keep)]` HOT 2
- `#[rune::function]` fails when adding a 6th argument HOT 5
- Feature request: More accurate types in generated rune API documentation HOT 4
- New 0.13.x release? HOT 1
- Before releasing 0.14
- Rune LSP cargo broken with multi-binary crates HOT 2
- Formatting likes to add more and more blank lines (not idempotent) HOT 1
- request: Multiple match patterns
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rune.