You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Edition 2015: ? is a macro separator, not a kleene op, but using it as a separator triggers a migration lint.
Edition 2018: ? is not a valid separator. ?is a valid Kleene op.
EDIT: To clarify: Under this proposal, $(a)?+ matches + and a+ unambiguously.
Why we chose this behavior:
It's the cleanest choice both in terms of end-user experience and implementation. See the alternatives.
Alternatives: The main problem to address is ambiguity. Currently, ? is a valid separator, so there are a lot of ambiguous possibilities like $(a)?+. Is the ? a separator for 1 or more iterations OR is it a zero-or-one kleene op followed by a + token? The solutions fall into 2 categories: make breaking changes or add fallbacks.
Fallbacks
The original implementation (currently on nightly behind feature gate macro_at_most_once_rep):
The ? kleene op is allowed to take a separator which can never be used (we don't allow trailing separators and ? allows at most one repetition).
When parsing a macro, we disambiguate by looking after the separator: if ? is followed by +, *, or ?, we treat the ? as a separator and the second token as a kleene op.
On the tracking issue, we decided that it is confusing for ? to take a separator, so the rules would be that ? followed by + or * is a separator, but ? followed by ? or any other token would be a ? kleene op followed by the other token.
This is a viable implementation, but it seems like a lot of special cases and the code gets messy. This led us more towards the breaking changes options.
There are probably lots of variations of fallbacks we could do, but they all have weird corner cases.
This means that $(a)?+ matches + and a+ unambiguously. However, it is a breaking change. This was deemed not worthy of a breaking change in the 2015 edition.
Make a breaking change in the 2018 edition and lint in the 2015 edition. No change to behavior in 2015. This is the current proposal implemented in 2018 edition ? Kleene operator #51587 and is the subject of this FCP.
The primary downside here is that it's not clear what happens if you import a macro from 2015 into 2018 that uses ? as a separator. Currently, you would just get a compile error.
The implementation is significantly cleaner and more maintainable and the behavior is more consistent for end-users.
cc @nikomatsakis
cc @petrochenkov Reviewed the second attempt
cc @durka@alexreg @clarcharr @Centril@kennytm@ExpHP Who participated extensively in the original design discussions (EDIT: apologies if I missed anyone; there were a lot of people who came in at various points)
cc @oli-obk Who brought up clippy breakage
cc @sgrif@pietroalbini Who wanted to see an FCP
This is a request for FCP on PR #51587, according to #51587 (comment).
Tracking issue: #48075 (
?macro repetition)Current behavior:
?is a macro separator, not a Kleene op.Proposed new behavior (implemented in #51587):
?is a macro separator, not a kleene op, but using it as a separator triggers a migration lint.?is not a valid separator.?is a valid Kleene op.EDIT: To clarify: Under this proposal,
$(a)?+matches+anda+unambiguously.Why we chose this behavior:
Alternatives: The main problem to address is ambiguity. Currently,
?is a valid separator, so there are a lot of ambiguous possibilities like$(a)?+. Is the?a separator for 1 or more iterations OR is it a zero-or-one kleene op followed by a+token? The solutions fall into 2 categories: make breaking changes or add fallbacks.Fallbacks
macro_at_most_once_rep):?kleene op is allowed to take a separator which can never be used (we don't allow trailing separators and?allows at most one repetition).?is followed by+,*, or?, we treat the?as a separator and the second token as a kleene op.?to take a separator, so the rules would be that?followed by+or*is a separator, but?followed by?or any other token would be a?kleene op followed by the other token.Breaking changes
?repetition disambiguation. #49719, accidentally merged without FCP, and rolled back).?as a separator in 2015 edition.?kleene op from taking a separator.$(a)?+matches+anda+unambiguously. However, it is a breaking change. This was deemed not worthy of a breaking change in the 2015 edition.?Kleene operator #51587 and is the subject of this FCP.?as a separator. Currently, you would just get a compile error.?repetition disambiguation. #49719 (comment)). However, we did found out later that there was apparently some breakage elsewhere (Update?repetition disambiguation. #49719 (comment)).cc @nikomatsakis
cc @petrochenkov Reviewed the second attempt
cc @durka @alexreg @clarcharr @Centril @kennytm @ExpHP Who participated extensively in the original design discussions (EDIT: apologies if I missed anyone; there were a lot of people who came in at various points)
cc @oli-obk Who brought up clippy breakage
cc @sgrif @pietroalbini Who wanted to see an FCP
Whew... that's a lot of people :)