Skip to content

Commit

Permalink
variable rebinding: Use Some() etc. to move scope of else
Browse files Browse the repository at this point in the history
If you rebind variables in the various ifs, the else should have none
of them in scope.

As a bonus this means that the expansion contains only one copy of the
else clause.

There is a behavioural change in some code, but arguably a bugfix.

Signed-off-by: Ian Jackson <[email protected]>
  • Loading branch information
ijackson committed Mar 22, 2021
1 parent 282b063 commit 47fac88
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,14 @@ macro_rules! if_chain {
macro_rules! __if_chain {
// Expand with both a successful case and a fallback
(@init ($($tt:tt)*) then { $($then:tt)* } else { $($other:tt)* }) => {
__if_chain! { @expand { $($other)* } $($tt)* then { $($then)* } }
match __if_chain! { @expand { None } $($tt)* then { Some({ $($then)* })} } {
Some(__if_chain_y) => __if_chain_y,
None => { $($other)* },
}
};
// Expand with no fallback
(@init ($($tt:tt)*) then { $($then:tt)* }) => {
__if_chain! { @expand {} $($tt)* then { $($then)* } }
__if_chain! { @expand { () } $($tt)* then { $($then)* } }
};
// Munch everything until either of the arms above can be matched.
// Munched tokens are placed into `$($tt)*`
Expand Down Expand Up @@ -317,20 +320,21 @@ mod tests {
}

#[test]

This comment has been minimized.

Copy link
@ijackson

ijackson Mar 22, 2021

Author Owner

Observe behavioral changes in this test case:

fn weirdness() {
fn let_rebinding_values() {
#[allow(unused_variables)]
fn wat(seq: &[usize]) -> Got {
let mut seq = seq.iter().copied();
let dunno = 0;
if_chain! {
if let Some(dunno) = seq.next();
if let Some(dunno) = seq.next(); // unused binding
if let Some(dunno) = seq.next();
then { Then(dunno) }
else { Else(dunno) }
}
}

assert_eq!(Else(0), wat(&[ ]));
assert_eq!(Else(1), wat(&[ 1 ]));
assert_eq!(Else(0), wat(&[ 1 ]));
assert_eq!(Then(2), wat(&[ 1, 2 ]));
assert_eq!(Then(2), wat(&[ 1, 2, 3 ]));
}
Expand Down

0 comments on commit 47fac88

Please sign in to comment.