Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAmbiguity between custom derive attributes and proc macro attributes #52226
Comments
alexcrichton
added
A-macros-2.0
A-macros-1.2
labels
Jul 10, 2018
alexcrichton
referenced this issue
Jul 10, 2018
Closed
Tracking issue for "macro naming and modularisation" (RFC #1561) #35896
This comment has been minimized.
This comment has been minimized.
|
Some immediate mitigations that look like they should be in place are:
@alercah and @petrochenkov, can y'all comment to whether this fixes the issue at hand or not? This is the same as I mentioned here but @alercah I wanted to clarify that the importing case is hopefully handled by the second bullet. In general I also think the most pressing part here is future-proofing ourselves. We don't necessarily need a fully fleshed out and fully rationalized system from day 1, we mostly just need to buy us as much runway as we can. |
petrochenkov
self-assigned this
Jul 10, 2018
This comment has been minimized.
This comment has been minimized.
|
Now that I've done the hard work, I'm pretty sure conflicts will be resolved if you add:
But I worry that this isn't enough future-proofing, because the implicit import behaviour will be stabilized if we go ahead as-is. As I understand it, right now, if you import |
This comment has been minimized.
This comment has been minimized.
|
Ah, wait, I think that since that's only for imports, |
This comment has been minimized.
This comment has been minimized.
|
@alercah I'm gonna respond to your other comment over here to try to keep discussion centralized, copied below in case anyone needs it! So the main point of the inert attributes is to provide a way for If we imagined a world where On the other side, derive macros can't (currently) edit the token stream of the struct they are deriving for, so they cannot remove their residue. Therefore, we can't have these inert attributes always be an error. Based on testing, the current resolution system is this, modulo some bugs:
This is a bit of a mess. If we imagine ourselves trying to reconcile this against future plans like scoped attribute names, we run into issues because inert attribute processing in step 3 is unable to accommodate paths: the derive macro has no way of knowing if Regular attribute macros run into the same problem, if you try to coordinate between two of them (again, suppose you want to mark fields). Currently, attribute macros can fake inert attributes by removing them from fields as they are encountered, but they would run into the same issue of trying to identify other attributes by way of scoping. Additionally, the lack of explicit declarations for inert attributes is problematic. At the risk of relitigating #35900 and #37614, I'm going to consider what I would do if I was designing from scratch:
The first one actually seems like a fairly conservative extension to the The third is a bigger change, and would break existing users of The fourth is just a slight semantic reordering to let the In general, it strikes me as weird that
(Or, alternatively, we decide it should be part of 2018 but will be late, so we require 2018 code to use It's true yeah that the macros 1.1 custom derive inert attributes aren't necessarily going to mesh perfectly with the module system, but the fact of the matter is that macros 1.1 is stable in Rust and we don't currently plan to change/deprecate any portions of its design. While it's true that weird cases can come up they should also be weighed against how common they're expected to be to provide a signal as to how urgent it'd be to resolve them. In that sense we don't really have an opportunity to design the system from scratch, and it's basically already stable that I think it's possible to implement the extra restriction you mentioned but it affects stable code so we'd need to be very careful about making such a change. Additionally it doesn't actually impact macros 1.2 stabilization (it only affects stable code already) so it may mean we don't necessarily need to tackle this for the 2018 edition! |
This comment has been minimized.
This comment has been minimized.
|
Yes, sorry, I have a habit of writing "here's what I would do designing from scratch" as a way to sort through my thoughts, rather than actually proposing a ground-up rewrite. I think that the proposed changes to macros 1.1 are pretty straightforward, enough to maybe sneak along an epoch boundary to unify everything, but not urgent. I realized I didn't really think through how this all interacts with declarative macros, and I'm now worried that will also cause futureproofing issues. If we're going to consider putting those into the macro namespace at some point, then we have to prepare for that rather than having pseudo-namespaced identifiers. Part of the arguments I read today about the stabilization of |
This comment has been minimized.
This comment has been minimized.
|
You can, however, shadow built-in derives, even with non-derive macros. |
This comment has been minimized.
This comment has been minimized.
|
Ah, but you can't shadow them with other derives. That one's an error. |
alexcrichton
referenced this issue
Jul 16, 2018
Merged
resolve: Modularize crate-local `#[macro_export] macro_rules` #52234
Mark-Simulacrum
modified the milestone:
Rust 2018 Preview 2
Jul 17, 2018
alexcrichton
added this to the Rust 2018 Preview 2 milestone
Jul 17, 2018
dtolnay
referenced this issue
Jul 19, 2018
Closed
macro imports don't work when there are _two_ imported attributes #52525
Mark-Simulacrum
modified the milestones:
Rust 2018 Preview 2,
Rust 2018 RC
Jul 31, 2018
aturon
modified the milestones:
Rust 2018 RC,
Edition RC 2
Sep 5, 2018
This comment has been minimized.
This comment has been minimized.
|
Bumping to RC2 milestone |
This comment has been minimized.
This comment has been minimized.
|
@petrochenkov hey I was curious to check in on this issue, I believe the current state is that whitelisted attributes are not macro-expanded, even if there's a macro in scope, right? |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton macro serde() {}
#[derive(Serialize)]
#[serde] // ERROR macro `serde` may not be used in attributes
struct S;
fn main() {}This causes regressions like #53583 and #53898. My intention so far is to bump priority of derive helpers so they shadow other macros instead (#53583 (comment)). |
This comment has been minimized.
This comment has been minimized.
|
Ok cool, sounds good to me! |
petrochenkov
referenced this issue
Sep 9, 2018
Merged
resolve: Future proof derive helper attributes #54086
bors
added a commit
that referenced
this issue
Sep 13, 2018
This comment has been minimized.
This comment has been minimized.
|
Status update: future proofed in #54086. The model is largely the same as previously, the helper attribute (e.g. Future proofing: If derive helper attribute is ambiguous with any other macro name in scope (taking sub-namespacing into account), then ambiguity error is reported. Compatibility: to avoid regressions, helper attributes are succesfully resolved even if they are written before the derive
, this is not good - the attribute is not in scope yet at that point if we want to pursue straightforward left-to-right expansion model. Future plans:
I think we can close this generic issue now and perhaps create new more focused issues for "future plans" (if those even need tracking). |
alexcrichton commentedJul 10, 2018
Discovered by @alercah here
it's not clear what to do with this crate right now:
along with:
cc @petrochenkov