Skip to content

Commit 1d42749

Browse files
committed
Fix expanding to short versions of constructs
To do so, this commit replaces `$other:block` with `{ $($other:tt)* }` and `{ $($other:tt)+ }`. This is because block matchers behave poorly with literal empty blocks `{}`: after it is matched with the block matcher it can't match literal `{}` anymore. Also adds separate match arms for: * `let` with a single pattern; * `if let` with a single pattern; * `if let` with a single pattern and a fallback.
1 parent 66cbe94 commit 1d42749

File tree

1 file changed

+51
-17
lines changed

1 file changed

+51
-17
lines changed

src/lib.rs

+51-17
Original file line numberDiff line numberDiff line change
@@ -162,44 +162,78 @@ macro_rules! if_chain {
162162
#[doc(hidden)]
163163
#[macro_export(local_inner_macros)]
164164
macro_rules! __if_chain {
165-
(@init ($($tt:tt)*) then $then:block else $other:block) => {
166-
__if_chain! { @expand $other $($tt)* then $then }
165+
// Expand with both a successful case and a fallback
166+
(@init ($($tt:tt)*) then { $($then:tt)* } else { $($other:tt)* }) => {
167+
__if_chain! { @expand { $($other)* } $($tt)* then { $($then)* } }
167168
};
168-
(@init ($($tt:tt)*) then $then:block) => {
169-
__if_chain! { @expand {} $($tt)* then $then }
169+
// Expand with no fallback
170+
(@init ($($tt:tt)*) then { $($then:tt)* }) => {
171+
__if_chain! { @expand {} $($tt)* then { $($then)* } }
170172
};
173+
// Munch everything until either of the arms above can be matched.
174+
// Munched tokens are placed into `$($tt)*`
171175
(@init ($($tt:tt)*) $head:tt $($tail:tt)*) => {
172176
__if_chain! { @init ($($tt)* $head) $($tail)* }
173177
};
174-
(@expand $other:block let $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
178+
179+
// `let` with a single pattern
180+
(@expand { $($other:tt)* } let $pat:pat = $expr:expr; $($tt:tt)+) => {
181+
{
182+
let $pat = $expr;
183+
__if_chain! { @expand { $($other)* } $($tt)+ }
184+
}
185+
};
186+
// `let` with a single identifier and a type hint
187+
(@expand { $($other:tt)* } let $ident:ident: $ty:ty = $expr:expr; $($tt:tt)+) => {
188+
{
189+
let $ident: $ty = $expr;
190+
__if_chain! { @expand { $($other)* } $($tt)+ }
191+
}
192+
};
193+
// `let` with multiple patterns
194+
(@expand { $($other:tt)* } let $pat1:pat | $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
175195
match $expr {
176-
$($pat)|+ => __if_chain! { @expand $other $($tt)+ }
196+
$pat1 | $($pat)|+ => __if_chain! { @expand { $($other)* } $($tt)+ }
177197
}
178198
};
179-
(@expand $other:block let $ident:ident: $ty:ty = $expr:expr; $($tt:tt)+) => {
180-
let $ident: $ty = $expr;
181-
__if_chain! { @expand $other $($tt)+ }
199+
// `if let` with a single pattern
200+
(@expand {} if let $pat:pat = $expr:expr; $($tt:tt)+) => {
201+
if let $pat = $expr {
202+
__if_chain! { @expand {} $($tt)+ }
203+
}
204+
};
205+
// `if let` with a single pattern and a fallback
206+
(@expand { $($other:tt)+ } if let $pat:pat = $expr:expr; $($tt:tt)+) => {
207+
if let $pat = $expr {
208+
__if_chain! { @expand { $($other)+ } $($tt)+ }
209+
} else {
210+
$($other)+
211+
}
182212
};
183-
(@expand $other:block if let $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
213+
// `if let` with multiple matterns and a fallback (if present)
214+
(@expand { $($other:tt)* } if let $pat1:pat | $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
184215
match $expr {
185-
$($pat)|+ => __if_chain! { @expand $other $($tt)+ },
186-
_ => $other
216+
$pat1 | $($pat)|+ => { __if_chain! { @expand { $($other)* } $($tt)+ } },
217+
_ => { $($other)* }
187218
}
188219
};
220+
// `if` with a successful case
189221
(@expand {} if $expr:expr; $($tt:tt)+) => {
190222
if $expr {
191223
__if_chain! { @expand {} $($tt)+ }
192224
}
193225
};
194-
(@expand $other:block if $expr:expr; $($tt:tt)+) => {
226+
// `if` with both a successful case and a fallback
227+
(@expand { $($other:tt)+ } if $expr:expr; $($tt:tt)+) => {
195228
if $expr {
196-
__if_chain! { @expand $other $($tt)+ }
229+
__if_chain! { @expand { $($other)+ } $($tt)+ }
197230
} else {
198-
$other
231+
$($other)+
199232
}
200233
};
201-
(@expand $other:block then $then:block) => {
202-
$then
234+
// Final macro call
235+
(@expand { $($other:tt)* } then { $($then:tt)* }) => {
236+
$($then)*
203237
};
204238
}
205239

0 commit comments

Comments
 (0)