Skip to content

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Aug 22, 2019

Every use of apply_mark in a built-in or procedural macro is supposed to look like this

location.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id))

where SyntaxContext::root() means that the built-in/procedural macro is defined directly, rather than expanded from some other macro.

However, few people understood what apply_mark does, so we had a lot of copy-pasted uses of it looking e.g. like

span = span.apply_mark(ecx.current_expansion.id);

, which doesn't really make sense for procedural macros, but at the same time is not too harmful, if the macros use the traditional macro_rules hygiene.

So, to fight this, we stop using apply_mark directly in built-in macro implementations, and follow the example of regular proc macros instead and use analogues of Span::def_site() and Span::call_site(), which are much more intuitive and less error-prone.

  • ecx.with_def_site_ctxt(span) takes the span's location and combines it with a def-site context.
  • ecx.with_call_site_ctxt(span) takes the span's location and combines it with a call-site context.

Even if called multiple times (which sometimes happens due to some historical messiness of the built-in macro code) these functions will produce the same result, unlike apply_mark which will grow the mark chain further in this case.


After apply_marks in built-in macros are eliminated, the remaining apply_marks are very few in number, so we can start passing the previously implicit Transparency argument to them explicitly, thus eliminating the need in default_transparency fields in hygiene structures and #[rustc_macro_transparency] annotations on built-in macros.

So, the task of making built-in macros opaque can now be formulated as "eliminate with_legacy_ctxt in favor of with_def_site_ctxt" rather than "replace #[rustc_macro_transparency = "semitransparent"] with #[rustc_macro_transparency = "opaque"]".

r? @matthewjasper

Replace them with equivalents of `Span::{def_site,call_site}` from proc macro API.
The new API is much less error prone and doesn't rely on macros having default transparency.
… contexts

Using `ExpnId`s default transparency here instead of the mark's real transparency was actually incorrect.
All transparancies are passed explicitly now.
Also remove `#[rustc_macro_transparency]` annotations from built-in macros, they are no longer used.
`#[rustc_macro_transparency]` only makes sense for declarative macros now.
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 22, 2019
@@ -575,9 +550,15 @@ impl Span {
/// The returned span belongs to the created expansion and has the new properties,
/// but its location is inherited from the current span.
pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does Transparency::Transparent makes more sense here? This expansion isn't for a macro so it can't be used for hygienic resolution anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some of the things using fresh_expansion currently use gensyms too, so it may be better to organize opaque expansions for them.
Transparency::SemiTransparent is used here just to keep the pre-existing behavior for now.

@matthewjasper
Copy link
Contributor

@bors r+

@bors
Copy link
Collaborator

bors commented Aug 24, 2019

📌 Commit 6548a5f has been approved by matthewjasper

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 24, 2019
@bors
Copy link
Collaborator

bors commented Aug 24, 2019

⌛ Testing commit 6548a5f with merge 5ade61a...

bors added a commit that referenced this pull request Aug 24, 2019
Audit uses of `apply_mark` in built-in macros + Remove default macro transparencies

Every use of `apply_mark` in a built-in or procedural macro is supposed to look like this
```rust
location.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id))
```
where `SyntaxContext::root()` means that the built-in/procedural macro is defined directly, rather than expanded from some other macro.

However, few people understood what `apply_mark` does, so we had a lot of copy-pasted uses of it looking e.g. like
```rust
span = span.apply_mark(ecx.current_expansion.id);
```
, which doesn't really make sense for procedural macros, but at the same time is not too harmful, if the macros use the traditional `macro_rules` hygiene.

So, to fight this, we stop using `apply_mark` directly in built-in macro implementations, and follow the example of regular proc macros instead and use analogues of `Span::def_site()` and `Span::call_site()`, which are much more intuitive and less error-prone.
- `ecx.with_def_site_ctxt(span)` takes the `span`'s location and combines it with a def-site context.
- `ecx.with_call_site_ctxt(span)` takes the `span`'s location and combines it with a call-site context.

Even if called multiple times (which sometimes happens due to some historical messiness of the built-in macro code) these functions will produce the same result, unlike `apply_mark` which will grow  the mark chain further in this case.

---

After `apply_mark`s in built-in macros are eliminated, the remaining `apply_mark`s are very few in number, so we can start passing the previously implicit `Transparency` argument to them explicitly, thus eliminating the need in `default_transparency` fields in hygiene structures and `#[rustc_macro_transparency]` annotations on built-in macros.

So, the task of making built-in macros opaque can now be formulated as "eliminate `with_legacy_ctxt` in favor of `with_def_site_ctxt`" rather than "replace `#[rustc_macro_transparency = "semitransparent"]` with `#[rustc_macro_transparency = "opaque"]`".

r? @matthewjasper
@bors
Copy link
Collaborator

bors commented Aug 24, 2019

☀️ Test successful - checks-azure
Approved by: matthewjasper
Pushing 5ade61a to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 24, 2019
@bors bors merged commit 6548a5f into rust-lang:master Aug 24, 2019
@petrochenkov petrochenkov deleted the noapply2 branch February 22, 2025 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants