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

Allow else and else if blocks to attach to the end of macro expantions #2335

Open
Nokel81 opened this issue Feb 14, 2018 · 13 comments
Open

Allow else and else if blocks to attach to the end of macro expantions #2335

Nokel81 opened this issue Feb 14, 2018 · 13 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@Nokel81
Copy link
Contributor

Nokel81 commented Feb 14, 2018

Currently, even though macro expansion is done during the parse phase of the compiler it does not fully inline the production because if the ending of macro is an if block a following else block is not paired up with it.
I have been told that this is intended, though I believe that it is rather strange behaviour, because if someone was to output the --extended=pretty output of the compiler from said macro expansion it would look like the else block should match up.

Motivation:
If this was allowed then macro writers would have a very nice and clean way to have an optional fallout case that is syntactically nice to look at.

Example:
Lets say you want to write an initialiser for an object that relies on some item but have the option for a default value that is written by the user, with the else block you could write the following:

let item = init_foo!{ parms } else { Foo::new(15) };

Here the initialisation might go ahead normally but if not there is a custom default value.

@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label Feb 14, 2018
@hanna-kruppe
Copy link

hanna-kruppe commented Feb 14, 2018

If this applies to all macros by default, then this leaks an implementation detail of the macro. Changing a macro that expands to an if or if let to expand to something else (e.g., a match, or an if ... else ...) would be a breaking change in that world. That doesn't sound desirable. Macros that do want to offer this option can allow it in current Rust with slightly different syntax by explicitly accepting a trailing else ... in its input (example).

@Nokel81
Copy link
Contributor Author

Nokel81 commented Feb 14, 2018

I understand that it could leak implementation details however, that could be seen by just directly outputting the macro - expanded output from the compiler.

It could be blocked by outputting a blank block at the end.

I don't see how a match statement would be able to take advantage of this

@hanna-kruppe
Copy link

I understand that it could leak implementation details however, that could be seen by just directly outputting the macro - expanded output from the compiler.

You can look at the expanded output but you can't write Rust code that depends on it. Well, theoreitcally you could invoke rustc from a build script, pass the unstable compiler option, and compile the output, but (1) the output of pretty-expanded often can't be compiled as-is for various reasons and (2) by doing this you're pretty clearly far outside any reasonably stability guarantees.

It could be blocked by outputting a blank block at the end.

Yes but this is a burden for all macro authors. They'd have to be aware of it and do it. (And what about macros that are already written?)

I don't see how a match statement would be able to take advantage of this

I mean if a macro expands to if let with no else, then one could presumably stick an else after the macro invocation, and that would break if the macro definition changes to use a match instead of if let.

@Nokel81
Copy link
Contributor Author

Nokel81 commented Feb 14, 2018

I understand. This should be opt-inable I think for those reasons. From my knowledge of compilers macro_rules could always output that extra block unless told not to.

@hanna-kruppe
Copy link

Yeah an opt-in would resolve those concerns. Of course, there are other concerns, e.g., the evergreen "is it worth the added complexity?"

From my knowledge of compilers macro_rules could always output that extra block unless told not to.

Possibly but if there is an opt-in that the compiler knows about, it can just implement it more directly than by emulating the hacks a library author would have to use.

@Nokel81
Copy link
Contributor Author

Nokel81 commented Feb 14, 2018

Of course, though I have not looked into that part of the compiler I would have to imagine that we are currently explicitly not allowing this since from a strictly syntax perspective this probably should have already been the case.

As for the evergreen question: I believe so since one of the nice things about rust is the consistent and pleasant looking syntax and I find that really complex macros do not have this. This change would help with some of that

@Nokel81
Copy link
Contributor Author

Nokel81 commented Apr 4, 2018

I have thought about this some more.

For Macros2.0 we will now be declaring macros like other blocks. Similarly to functions or structs so a derive would make sense as the way to signal to the compiler this feature.

Example:

#derive(plop)
macro unless (expr: cond { expr: do})
...

(Pretty sure that this macro isn't valid but I think it gets my point across)

And if a macro derives plop then it is allowed to attach itself to external syntax and still be valid. Example:

unless!(foo { doBar();})
else unless!(bar { doFoo();})
else { doFooBar(); }

@Centril
Copy link
Contributor

Centril commented Oct 9, 2018

cc rust-lang/rust#39412

@Nokel81
Copy link
Contributor Author

Nokel81 commented Oct 10, 2018

@Centril Because I do not know, what does a cc mean in this context?

@mark-i-m
Copy link
Member

I believe they are just notifying a related thread. Mentioning the GitHub issue leaves a note in the timeline on that issue.

@golddranks
Copy link

@Nokel81 I believe it stems from the email field "CC" ("Carbon Copy") which is used to send the message to related third parties to keep them informed.

@Nokel81
Copy link
Contributor Author

Nokel81 commented Oct 12, 2018

@mark-i-m @golddranks Thank you. I was really asking if I should join in on the conversation on their side but from what you say that is not exactly what was being offered. More to just observe.

@Centril
Copy link
Contributor

Centril commented Oct 12, 2018

@Nokel81 If you care about the future of macros, which from this issue it seems you do, I totally think you should join in on the "other side" (the other issue).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

5 participants