Uh oh!
There was an error while loading. Please reload this page.
Hygiene opt-out for idents in expansion of declarative macros - #47992
Hygiene opt-out for idents in expansion of declarative macros#47992alexreg wants to merge 10 commits into
Conversation
rust-highfive
commented
Feb 4, 2018
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @petrochenkov (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
petrochenkov
commented
Feb 5, 2018
Could you add all the examples from the PR descriptions as tests? |
@petrochenkov Yep, sounds fair. Also, thoughts on my above comment about use of the syntax in legacy |
Oh, and I think the syntax |
alexreg
commented
Feb 6, 2018
A further question:
|
alexreg
commented
Feb 6, 2018
Okay, my present thoughts are that 3 and 4 should indeed fail. To make them work would mean having the macro parser understand items, which would mean binding it more tightly to the normal parser, and really make a mess of things. |
@alexreg I'm confused as to what it would mean for them to work, even if it would involve reworking the parser. If I understand correctly, in examples 3 and 4 // `main` scope// vvvvvvvpubmod foo_mod {// `foo!` scope// vvvpubconstBAR:u32 = 123;}In both cases |
alexreg
commented
Feb 6, 2018
@pierzchalski Well, the alternative semantics would be i.e. We have (The same end result in terms of hygiene as for |
pierzchalski
commented
Feb 6, 2018
@alexreg Ah, I see! Yeah, making scopes semantics-aware sounds like a lot of work. It also means you'd need a way to 'un-lift' any identifiers you expected to use privately: // `main` scope// vvvvvvvpubmod foo_mod {// `main` scope// vvvpubfnbar(){// I want this to be in `foo_mod!` scopebaz();}// Perhaps I want this private to `foo_mod!` but// `pub` because it's used by... other modules generated by `foo_mod!`,// or something else silly.pubfnbaz(){ ...}} |
petrochenkov
commented
Feb 6, 2018
If it can be easily prohibited, then let's prohibit it for a start, otherwise any use of the |
petrochenkov
commented
Feb 6, 2018
Why? |
petrochenkov
commented
Feb 6, 2018
Yes, ideally we should. |
petrochenkov
commented
Feb 6, 2018
What is "3 and 4"? |
pierzchalski
commented
Feb 6, 2018
@petrochenkov The 3rd and 4th code snippets in the starting post (I was also briefly lost on that). |
petrochenkov
commented
Feb 6, 2018
They should fail then, |
petrochenkov
commented
Feb 6, 2018
cc https://internals.rust-lang.org/t/pre-rfc-splitting-liftime-into-two-tokens/6716 |
alexreg
commented
Feb 6, 2018
@pierzchalski Exactly. The difficulties outweigh the small benefits and added complexity I think. |
alexreg
commented
Feb 6, 2018
@petrochenkov Sounds good to me. If we can solve the spaces problem mentioned there, it will definitely simplify a lot of code. For now I may hack around it. |
alexreg
commented
Feb 6, 2018
Sure. I'll have a go at this – I don't think it's too hard. |
alexreg
commented
Feb 6, 2018
I think of it in terms of composability. For a metavar |
Okay, tests added (both run-pass & compile-fail) – everything passing locally. r? @jseyfried CC @nikomatsakis too, in case @jseyfried is too busy still (I've noticed a bit of activity from him though). |
nikomatsakis
commented
Feb 8, 2018
There was a problem hiding this comment.
The context of this span needs to match the context of the identifier or lifetime token for proc-macros to be coherent (a proc-macro identifer token is just an interned string and a span; when we reconstruct the libsyntax::TokenTree the interned string turns into an identifier with the span's context).
You might have chosen to use cx.current_expansion.mark for better diagnostics (even if the ident resolves at call site, it should show up in diagnostics at the call site). To achieve this, the plan is for spans to have separate SyntaxContexts for hygiene and for diagnostics. I'm working on a PR for this now.
There was a problem hiding this comment.
Yeah, I was in a bit of a conundrum over this... I'm glad you're working on separating out hygiene and diagnostic contexts. To be clear, how should the span be correctly constructed under this new model?
I guess we can wait for your PR to land, before merging this, presuming it won't be too much more work? Do post a link here when you open it.
This comment has been minimized.
This comment has been minimized.
alexreg
commented
May 9, 2018
@petrochenkov@jseyfried Just to confirm, we only want this feature gate to apply to the |
We want this to fail for the time being, per <rust-lang#47992 (comment)>.
rust-highfive
commented
May 9, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
rust-highfive
commented
May 9, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
alexreg
commented
May 10, 2018
How are we looking now, @petrochenkov / @jseyfried? :-) |
joshtriplett
commented
May 10, 2018
We discussed this in the language team meeting, and we agree that this needs an actual RFC to specify this for review. This is not the kind of thing we should just do without an RFC. |
alexreg
commented
May 10, 2018
@joshtriplett Okay. What I'll do then is get @petrochenkov & @jseyfried's feedback now, and then start writing up an RFC including what's been done (and learnt) in this PR, plus future plans. Maybe we can leave this open in the meanwhile, then once that's accepted, we can hopefully get this merged with few changes? |
emilyalbini
commented
May 10, 2018
@alexreg I'd prefer for this PR to be closed in the meantime, otherwise triage would have to check this PR every week. Then when you're ready you can open it again. |
alexreg
commented
May 10, 2018
@pietroalbini As long as it can be reopened easily, sure. Hopefully @petrochenkov & @jseyfried will see my above comments anyway, and leave some feedback before I get to writing the RFC. |
| pub struct Escaper(pub SyntaxContext); | ||
| impl Folder for Escaper { | ||
| fn fold_ident(&mut self, mut ident: Ident) -> Ident { |
There was a problem hiding this comment.
Overriding fold_ident is not necessary, overridden new_span applies to identifiers as well.
There was a problem hiding this comment.
Ah, I see. Why is it necessary in the Folder implementation for Marker though?
There was a problem hiding this comment.
It isn't necessary there either, it's just something I forgot to remove in #49154.
petrochenkov
commented
May 13, 2018
I'm not even sure there's a need in a separate feature gate beyond |
petrochenkov
commented
May 13, 2018
Feedback: the implementation looks good to me, but if lang team thinks it needs an RFC, then it needs an RFC. |
emilyalbini
commented
May 13, 2018
Ok, closing this until an RFC is approved. @alexreg when you're ready to work on this again just click the reopen button |
petrochenkov
commented
May 13, 2018
@pietroalbini |
alexreg
commented
May 13, 2018
@pietroalbini It turns out I don't have the rights to reopen my PRs (as I thought), but I'll ping you or someone else when it's time, sure! |
alexreg
commented
May 13, 2018
@petrochenkov There's no easy way to get whether we're in legacy mode from within the |
alexreg
commented
May 13, 2018
@petrochenkov Also, should the errors be emitted when doing the actual parsing of the macro or the expansion? |
petrochenkov
commented
May 13, 2018
Don't know, looks like no.
Ideally, if some error will be reported at any expansion, then it should be reported at macro definition. |
alexreg
commented
May 13, 2018
@petrochenkov Makes sense, thanks. I think we can bail within the |
alexreg
commented
May 13, 2018
@petrochenkov Incidentally, do you want to disallow I'm not sure what the error message should be when an interpolated token follows |
petrochenkov
commented
May 13, 2018
Something like "Hygiene opt-out is not supported for macro parameters" or "... on the left side of the macro". |
alexreg
commented
May 14, 2018
Hmm, what are interpolated tokens? Something to do with proc macros I seem to recall, but I don’t really know. The term might confuse users, no? |
alexreg
commented
May 14, 2018
The problem with this is, we're allowing |
alexreg
commented
May 14, 2018
@petrochenkov Pushed new commits anyway, in case you want to have a look. May make another, depending on your answers to the above two queries, but otherwise I'll focus on the RFC now. |
This PR adds basic support for hygiene opt-out for idents during macro expansion. This has been previously discussed in #40847 and #39412.
The syntax involves prefixing idents with the
#(i.e. pound/hash) character to indicate that the syntax context of the ident should be that of the call site rather than the definition site.The following now compiles and runs as expected:
as does:
but the following does not:
nor does:
Questions:
macro_rulesmacros, of course, but should we explicitly disallow the#syntax in such places? (Currently that is not done.)CC @jseyfried