@@ -82,7 +82,15 @@ macro_rules! cfg_if {
8282 $( $yes , ) ?
8383 not( any( $( $no ) ,* ) )
8484 ) ) ]
85- $crate:: cfg_if! { @__identity $( $tokens ) * }
85+ // Subtle: You might think we could put `$( $tokens )*` here. But if
86+ // that contains multiple items then the `#[cfg(all(..))]` above would
87+ // only apply to the first one. By wrapping `$( $tokens )*` in this
88+ // macro call, we temporarily group the items into a single thing (the
89+ // macro call) that will be included/excluded by the `#[cfg(all(..))]`
90+ // as appropriate. If the `#[cfg(all(..))]` succeeds, the macro call
91+ // will be included, and then evaluated, producing `$( $tokens )*`. See
92+ // also the "issue #90" test below.
93+ $crate:: cfg_if! { @__temp_group $( $tokens ) * }
8694
8795 // Recurse to emit all other items in `$rest`, and when we do so add all
8896 // our `$yes` matchers to the list of `$no` matchers as future emissions
@@ -93,9 +101,8 @@ macro_rules! cfg_if {
93101 }
94102 } ;
95103
96- // Internal macro to make __apply work out right for different match types,
97- // because of how macros match/expand stuff.
98- ( @__identity $( $tokens: tt ) * ) => {
104+ // See the "Subtle" comment above.
105+ ( @__temp_group $( $tokens: tt ) * ) => {
99106 $( $tokens ) *
100107 } ;
101108}
@@ -144,6 +151,21 @@ mod tests {
144151 }
145152 }
146153
154+ // In issue #90 there was a bug that caused only the first item within a
155+ // block to be annotated with the produced `#[cfg(...)]`. In this example,
156+ // it meant that the first `type _B` wasn't being omitted as it should have
157+ // been, which meant we had two `type _B`s, which caused an error. See also
158+ // the "Subtle" comment above.
159+ cfg_if ! (
160+ if #[ cfg( target_os = "no-such-operating-system-good-sir!" ) ] {
161+ type _A = usize ;
162+ type _B = usize ;
163+ } else {
164+ type _A = i32 ;
165+ type _B = i32 ;
166+ }
167+ ) ;
168+
147169 #[ test]
148170 fn it_works ( ) {
149171 assert ! ( works1( ) . is_some( ) ) ;
0 commit comments