diff --git a/src/lib.rs b/src/lib.rs index 39177fa..7e6a50a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -164,7 +164,10 @@ 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)* }) => { @@ -239,6 +242,10 @@ macro_rules! __if_chain { #[cfg(test)] mod tests { + #[derive(Debug,Copy,Clone,Eq,PartialEq)] + enum Got { Then(usize), Else(usize) } + use self::Got::*; + #[test] fn simple() { let x: Option, (u32, u32)>> = Some(Err((41, 42))); @@ -311,4 +318,37 @@ mod tests { }; assert_eq!(x, 3); } + + #[test] + fn let_rebinding_values() { + #[allow(unused_variables)] + fn wat(seq: &[usize]) -> Got { + let mut seq = seq.iter(); + let dunno = 0; + if_chain! { + 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(0), wat(&[ 1 ])); + assert_eq!(Then(2), wat(&[ 1, 2 ])); + assert_eq!(Then(2), wat(&[ 1, 2, 3 ])); + } + + #[test] + fn let_rebinding() { + let v = Some(Some(Some('a'))); + if_chain! { + if let Some(v) = v; + if let Some(v) = v; + if let Some(v) = v; + if true; + then { let _: char = v; } + else { let _: Option>> = v; } + }; + } }