@@ -178,15 +178,20 @@ macro_rules! push_rules {
178178 ) => {
179179 // Found the conclusion.
180180 {
181- // give the user a type error if the name they gave
182- // in the conclusion is not the same as the name of the
183- // function
184- #[ allow( dead_code) ]
185- struct WrongJudgmentNameInConclusion ;
186- const _: WrongJudgmentNameInConclusion = {
187- let $judgment_name = WrongJudgmentNameInConclusion ;
181+ $crate:: respan!(
188182 $conclusion_name
189- } ;
183+ (
184+ // give the user a type error if the name they gave
185+ // in the conclusion is not the same as the name of the
186+ // function
187+ #[ allow( dead_code) ]
188+ struct WrongJudgmentNameInConclusion ;
189+ const _: WrongJudgmentNameInConclusion = {
190+ let $judgment_name = WrongJudgmentNameInConclusion ;
191+ $conclusion_name
192+ } ;
193+ )
194+ ) ;
190195
191196 if let Some ( __JudgmentStruct( $( $input_names) ,* ) ) = Some ( $input_value) {
192197 $crate:: push_rules!( @match
@@ -283,33 +288,104 @@ macro_rules! push_rules {
283288 // expression `v` is carried in from the conclusion and forms the final
284289 // output of this rule, once all the conditions are evaluated.
285290
286- ( @body $args: tt; $inputs: tt; $step_index: expr; ( if $c: expr) $( $m: tt) * ) => {
287- 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) {
288294 $crate:: push_rules!( @body $args; $inputs; $step_index + 1 ; $( $m) * ) ;
289295 } else {
290- $crate:: push_rules!( @record_failure $inputs; $step_index, $c; $crate:: judgment:: RuleFailureCause :: IfFalse {
291- 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) ,
292299 } ) ;
293300 }
294301 } ;
295302
296- ( @body $args: tt; $inputs: tt; $step_index: expr; ( assert $c: expr) $( $m: tt) * ) => {
297- assert!( $c) ;
298- $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) * )
299307 } ;
300308
301- ( @body $args: tt; $inputs: tt; $step_index: expr; ( if let $p: pat = $e: expr) $( $m: tt) * ) => {
302- let value = & $e;
303- 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+ } {
304371 $crate:: push_rules!( @body $args; $inputs; $step_index + 1 ; $( $m) * ) ;
305372 } else {
306- $crate:: push_rules!( @record_failure $inputs; $step_index, $e; $crate:: judgment:: RuleFailureCause :: IfLetDidNotMatch {
307- pattern: stringify!( $p) . to_string( ) ,
308- 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+ ] ,
309380 } ) ;
310381 }
311382 } ;
312383
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+
313389 ( @body $args: tt; $inputs: tt; $step_index: expr; ( $i: expr => $p: pat) $( $m: tt) * ) => {
314390 // Explicitly calling `into_iter` silences some annoying lints
315391 // in the case where `$i` is an `Option` or a `Result`
0 commit comments