Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.11 KB | None | 0 0
  1. macro_rules! reassign {
  2. // Init: manually feed incrementing indices
  3. (
  4. ( $($tt:tt)* ) = $expr:expr
  5. ) => (
  6. // let temp = $expr;
  7. reassign! {
  8. @write_with_type_annotation [ $($tt)* ] ()
  9. let temp = $expr;
  10. }
  11. reassign! {
  12. @indices [0 1 2 3 4 5 6 7 8 9 10 11 12]
  13. ( $($tt)* ) = temp
  14. }
  15. );
  16.  
  17. // Handling left-hand-side step-by-step
  18. // New binding case
  19. (@indices
  20. [ $cur_index:tt $($rest_indices:tt)* ]
  21. (
  22. let $var:pat
  23. $(
  24. , $($rest:tt)*
  25. )?
  26. ) = $expr:ident
  27. ) => (
  28. let $var = $expr.$cur_index;
  29. reassign! {
  30. @indices [ $($rest_indices)* ]
  31. (
  32. $( $($rest)* )?
  33. ) = $expr
  34. }
  35. );
  36.  
  37. // Nested tuple case
  38. (@indices
  39. [ $cur_index:tt $($rest_indices:tt)* ]
  40. (
  41. ( $($tt:tt)* )
  42. $(
  43. , $($rest:tt)*
  44. )?
  45. ) = $expr:ident
  46. ) => (
  47. reassign!( ($($tt)*) = $expr.$cur_index );
  48. reassign! {
  49. @indices [ $($rest_indices)* ]
  50. (
  51. $( $($rest)* )?
  52. ) = $expr
  53. }
  54. );
  55.  
  56. // place expression case (`*(&mut ...)` or varname)
  57. (@indices
  58. [ $cur_index:tt $($rest_indices:tt)* ]
  59. (
  60. $var:expr
  61. $(
  62. , $($rest:tt)*
  63. )?
  64. ) = $expr:ident
  65. ) => (
  66. $var = $expr.$cur_index;
  67. reassign! {
  68. @indices [ $($rest_indices)* ]
  69. (
  70. $( $($rest)* )?
  71. ) = $expr
  72. }
  73. );
  74.  
  75. // Termination
  76. (@indices
  77. $indices:tt
  78. () = $expr:ident
  79. ) => ();
  80.  
  81. // Bad termination: exhausted indices
  82. (@indices
  83. []
  84. $vars:tt = $expr:ident
  85. ) => (
  86. compile_error! {
  87. "`reassign!` only supports up to 12-tuples"
  88. }
  89. );
  90.  
  91. // Writing a type annotation to prevent the right hand side
  92. // from having extra (unused) elements:
  93. // New binding case
  94. (@write_with_type_annotation
  95. [ let $pat:pat $(, $($tt:tt)* )? ] // input
  96. (
  97. $($tys:tt)*
  98. )
  99. let $ident:ident = $expr:expr;
  100. ) => (reassign!(@write_with_type_annotation
  101. [ $( $($tt)* )? ]
  102. (
  103. $($tys)* _,
  104. )
  105. let $ident = $expr;
  106. ));
  107.  
  108. // place expression case
  109. (@write_with_type_annotation
  110. [ $place:expr $(, $($tt:tt)* )? ] // input
  111. (
  112. $($tys:tt)*
  113. )
  114. let $ident:ident = $expr:expr;
  115. ) => (reassign!(@write_with_type_annotation
  116. [ $( $($tt)* )? ]
  117. (
  118. $($tys)* _,
  119. )
  120. let $ident = $expr;
  121. ));
  122.  
  123. // End
  124. (@write_with_type_annotation
  125. [] // input
  126. ($($tuple_ty:tt)*)
  127. let $ident:ident = $expr:expr;
  128. ) => (
  129. let $ident: ($($tuple_ty)*) = $expr;
  130. );
  131. }
  132.  
  133. fn main ()
  134. {
  135. let mut a = [0, 0];
  136. reassign! {
  137. (
  138. (a[0],), a[1], let z,
  139. ) = (
  140. (42,), 27, 0,
  141. )
  142. }
  143. dbg!(a.iter().sum::<i32>());
  144. dbg!(z);
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement