Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand Procedural Macro Docs #412

Merged
merged 24 commits into from
Sep 7, 2018
Merged

Conversation

Havvy
Copy link
Contributor

@Havvy Havvy commented Sep 2, 2018

This merges my WIP stuff, @alexcrichton's mostly guide level stuff, and some new material into what I hope will be the final status for the procedural macro page.

I'm not super happy with the attribute resolution section personally, but I feel like we can fix that up later. I want procedural macros to be in the reference before the next stable release, since I feel people are going to have questions about it and the reference should be a good place to find answers.

Opening a new pull request instead of pushing to @alexcrichton's because so much has changed that conversation already there is entirely outdated.

@Havvy Havvy added New Content Missing features or aspects of language not currently documented. RFC Stabilization Docs Documentation required for stabilizing a feature labels Sep 2, 2018

These macros cannot expand to syntax that defines new `macro_rule` style macros.

### Derive mode macros
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of "mode" in "derive mode"?
It's like a random unrelated word just inserted there.
I've seen the wording "derive mode" in a couple of compiler errors maybe, but that's all.

The phrasing "define new modes for the derive attribute" doesn't make sense to me.
Ok, I'm not a native speaker, let's look into a dictionary - "A way or manner" / "A fashion or style" - still doesn't make any sense.
In the first approximation, derive just applies arbitrary macros passed to it (#[derive(A, B, C)] ITEM -> #[A] #[B] #[C] ITEM), how are those macros "modes"?

</rant>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main point, as I see it, is that it lets us talk about the A, B, C inside #[derive(A, B, C)] without needing to always call them macros. If we want to talk about A without caring that its a macro, and we just call them derive macros, then what do we call it? We could call it a "derive", but that does not jive well. "The derive attribute takes derives" is also weird. So we need some name to distinguish them. My original thought was to go with "deriver", but then I saw said compiler error that calls them a derive mode. And mode makes sense to me.

When I think of modes, I think of distinct ways of operating something. My oven has modes for "bake", "boil", some other one I never use, and "clean". Firefox has safe mode and private browsing mode. Businesses operate in stealth mode or growth mode or whatever fancy mode they want. That said, if you want to get it changed to "deriver" or something, file an issue against rust-lang/rust. I defer terminology to what it uses when I can.

Copy link
Contributor

@petrochenkov petrochenkov Sep 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw said compiler error that calls them a derive mode.

Yeah, I've seen those diagnostics too and always thought they were bad, and wanted to get rid of them.
That's why when I'd seen that terminology reused I immediately thought it wasn't a good idea.
(Please, excuse my past tenses if I got them all wrong.)

I suspect the terminology came from the time when only a limited set of built-in derives existed.
"Mode" kinda implies that you have several of them and need to choose one, i.e. something enum-like.

without needing to always call them macros

Why? They are macros.
If #[proc_macro_attribute] defines an "attribute macro", #[proc_macro_derive] defines a "derive macro", then we have a symmetry between language and docs.
"derive attribute takes derive macros as arguments" - sounds ok to me.

when compiling for tests and dynamic otherwise. Attribute macros are dynamic.
All other attributes are inert.

## Attribute resolution
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to avoid specifying any details here for now, the rules are not settled yet.
Macro modularization was stabilized, but there's still a number of incomplete items from rust-lang/rust#50911 (comment) that need to be done until beta, stable or maybe even later if crater allows.
(My suggestion would be to stash this section somewhere until 1.30 stable is released.)

attributes* remove themselves from the thing they are on while *inert attriutes*
stay on.

The `cfg` and `cfg_attr` attributes are dynamic. The `test` attribute is inert
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full list is cfg, cfg_attr, test, bench, derive currently, if I'm not missing anything.

test and bench are being migrated to macros right now though (rust-lang/rust#53410).
(Also, test/bench are always "dynamic", they tweak their target items in test mode as well - add pubs, reexports.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps "active" would be better than "dynamic"?
Dynamic sounds like 1) something happening at runtime and 2) the attributes themselves are changing.
The difference with inert attributes is that "dynamic"/"active" attributes can transform their target items, i.e. change something else rather than themselves.

Perhaps we can even avoid "active built-in attributes" as a class and just call them "built-in attribute macros".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 on "active". I knew there was a better word. There always is when it comes to "dynamic". I just couldn't think of it.

I was going for "inert" as being attributes that remain on the item during macro resolution. bench isn't stable so we don't have to worry about it. derive seems to act as an inert attribute to me. It doesn't get removed from the item when running the derivers/derive modes. It doesn't actually modify the item its own but produce new one. Likewise, the test attribute stays on when compiling tests.

I'm not quite sure I want to call built-in attributes macro attributes as well.

also define derive mode helper attributes.

Custom deriver modes are defined by a [public] [function] with the
`proc_maco_derive` attribute and a signature of `(TokenStream) -> TokenStream`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proc_macro_derive


Function-like procedural macros define new invokable macros.

These macros are defined by a [public] [function] with the `proc_maco`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proc_macro

Copy link
Member

@steveklabnik steveklabnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one tiny whitespace nit

src/linkage.md Outdated
@@ -205,3 +209,7 @@ a statically linked binary on MSVC you would execute:
```ignore,notrust
RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc
```


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✂️

@Havvy
Copy link
Contributor Author

Havvy commented Sep 7, 2018

I would like to see this section in the reference before the deadline. People are going to want to look this up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Content Missing features or aspects of language not currently documented. RFC Stabilization Docs Documentation required for stabilizing a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants