Description
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):
- 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.
- The
- 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.
- The original implementation (currently on nightly behind feature gate
-
Breaking changes
- Make a breaking change in the 2015 edition (implemented in Update
?
repetition disambiguation. #49719, accidentally merged without FCP, and rolled back).- Disallow
?
as a separator in 2015 edition. - Disallow
?
kleene op from taking a separator. - This means that
$(a)?+
matches+
anda+
unambiguously. However, it is a breaking change. This was deemed not worthy of a breaking change in the 2015 edition.
- Disallow
- 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. - I believe the breakage is likely to be extremely rare. A crater run showed no breakage (Update
?
repetition disambiguation. #49719 (comment)). However, we did found out later that there was apparently some breakage elsewhere (Update?
repetition disambiguation. #49719 (comment)). - The implementation is significantly cleaner and more maintainable and the behavior is more consistent for end-users.
- The primary downside here is that it's not clear what happens if you import a macro from 2015 into 2018 that uses
- Make a breaking change in the 2015 edition (implemented in Update
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 :)