@@ -288,33 +288,104 @@ macro_rules! push_rules {
288288 // expression `v` is carried in from the conclusion and forms the final
289289 // output of this rule, once all the conditions are evaluated.
290290
291- ( @body $args: tt; $inputs: tt; $step_index: expr; ( if $c: expr) $( $m: tt) * ) => {
292- if $c {
291+ ( @body $args: tt; $inputs: tt; $step_index: expr; ( if let $p: pat = $e: expr) $( $m: tt) * ) => {
292+ let value = & $e;
293+ if let $p = Clone :: clone( value) {
293294 $crate:: push_rules!( @body $args; $inputs; $step_index + 1 ; $( $m) * ) ;
294295 } else {
295- $crate:: push_rules!( @record_failure $inputs; $step_index, $c; $crate:: judgment:: RuleFailureCause :: IfFalse {
296- expr: stringify!( $c) . to_string( ) ,
296+ $crate:: push_rules!( @record_failure $inputs; $step_index, $e; $crate:: judgment:: RuleFailureCause :: IfLetDidNotMatch {
297+ pattern: stringify!( $p) . to_string( ) ,
298+ value: format!( "{:?}" , value) ,
297299 } ) ;
298300 }
299301 } ;
300302
301- ( @body $args: tt; $inputs: tt; $step_index: expr; ( assert $c: expr) $( $m: tt) * ) => {
302- assert!( $c) ;
303- $crate:: push_rules!( @body $args; $inputs; $step_index + 1 ; $( $m) * ) ;
303+ // For `(if ...)`, we have special treatment to try and extract the arguments so we can give better information
304+ // about why the expression evaluated to false.
305+ ( @body $args: tt; $inputs: tt; $step_index: expr; ( if $( $c: tt) * ) $( $m: tt) * ) => {
306+ $crate:: push_rules!( @body_if $args; $inputs; $step_index; $( $c) * ; $( $c) * ; $( $m) * )
304307 } ;
305308
306- ( @body $args: tt; $inputs: tt; $step_index: expr; ( if let $p: pat = $e: expr) $( $m: tt) * ) => {
307- let value = & $e;
308- if let $p = Clone :: clone( value) {
309+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $arg0: ident . $method: ident ( ) ; $origcond: expr; $( $m: tt) * ) => {
310+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0) ; arg0. $method( ) ; $origcond; $( $m) * )
311+ } ;
312+
313+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; ! $arg0: ident . $method: ident ( ) ; $origcond: expr; $( $m: tt) * ) => {
314+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0) ; !arg0. $method( ) ; $origcond; $( $m) * )
315+ } ;
316+
317+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $arg0: ident . $method: ident ( $arg1: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
318+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1) ; arg0. $method( arg1) ; $origcond; $( $m) * )
319+ } ;
320+
321+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; ! $arg0: ident . $method: ident ( $arg1: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
322+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1) ; !arg0. $method( arg1) ; $origcond; $( $m) * )
323+ } ;
324+
325+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $arg0: ident . $method: ident ( $arg1: expr, $arg2: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
326+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1, arg2 = $arg2) ; arg0. $method( arg1, arg2) ; $origcond; $( $m) * )
327+ } ;
328+
329+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; ! $arg0: ident . $method: ident ( $arg1: expr, $arg2: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
330+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1, arg2 = $arg2) ; !arg0. $method( arg1, arg2) ; $origcond; $( $m) * )
331+ } ;
332+
333+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $func: ident ( $arg0: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
334+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0) ; $func( arg0) ; $origcond; $( $m) * )
335+ } ;
336+
337+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; ! $func: ident ( $arg0: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
338+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0) ; !$func( arg0) ; $origcond; $( $m) * )
339+ } ;
340+
341+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $func: ident ( $arg0: expr, $arg1: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
342+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1) ; $func( arg0, arg1) ; $origcond; $( $m) * )
343+ } ;
344+
345+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; ! $func: ident ( $arg0: expr, $arg1: expr $( , ) ? ) ; $origcond: expr; $( $m: tt) * ) => {
346+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1) ; ! $func( arg0, arg1) ; $origcond; $( $m) * )
347+ } ;
348+
349+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $arg0: ident == $arg1: ident; $origcond: expr; $( $m: tt) * ) => {
350+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1) ; arg0 == arg1; $origcond; $( $m) * )
351+ } ;
352+
353+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $arg0: ident != $arg1: ident; $origcond: expr; $( $m: tt) * ) => {
354+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( arg0 = $arg0, arg1 = $arg1) ; arg0 != arg1; $origcond; $( $m) * )
355+ } ;
356+
357+ ( @body_if $args: tt; $inputs: tt; $step_index: expr; $e: expr; $origcond: expr; $( $m: tt) * ) => {
358+ $crate:: push_rules!( @structured_if $args; $inputs; $step_index; ( ) ; $e; $origcond; $( $m) * )
359+ } ;
360+
361+ ( @structured_if $args: tt; $inputs: tt; $step_index: expr; ( $( $argn: ident = $arge: expr) ,* ) ; $cond: expr; $origcond: expr; $( $m: tt) * ) => {
362+ $(
363+ let $argn = & $arge;
364+ ) *
365+ if {
366+ $(
367+ let $argn = Clone :: clone( $argn) ;
368+ ) *
369+ $cond
370+ } {
309371 $crate:: push_rules!( @body $args; $inputs; $step_index + 1 ; $( $m) * ) ;
310372 } else {
311- $crate:: push_rules!( @record_failure $inputs; $step_index, $e; $crate:: judgment:: RuleFailureCause :: IfLetDidNotMatch {
312- pattern: stringify!( $p) . to_string( ) ,
313- value: format!( "{:?}" , value) ,
373+ $crate:: push_rules!( @record_failure $inputs; $step_index, $origcond; $crate:: judgment:: RuleFailureCause :: IfFalse {
374+ expr: stringify!( $origcond) . to_string( ) ,
375+ args: vec![
376+ $(
377+ ( stringify!( $arge) . to_string( ) , format!( "{:?}" , $argn) ) ,
378+ ) *
379+ ] ,
314380 } ) ;
315381 }
316382 } ;
317383
384+ ( @body $args: tt; $inputs: tt; $step_index: expr; ( assert $c: expr) $( $m: tt) * ) => {
385+ assert!( $c) ;
386+ $crate:: push_rules!( @body $args; $inputs; $step_index + 1 ; $( $m) * ) ;
387+ } ;
388+
318389 ( @body $args: tt; $inputs: tt; $step_index: expr; ( $i: expr => $p: pat) $( $m: tt) * ) => {
319390 // Explicitly calling `into_iter` silences some annoying lints
320391 // in the case where `$i` is an `Option` or a `Result`
0 commit comments