@@ -292,6 +292,12 @@ impl<'ctx> Codegen<'ctx> {
292292 // The handler works similar to a match expression, but matching against the effect
293293 // and doing much more control flow work.
294294 for handler in handlers {
295+ if matches ! (
296+ handler. guard. as_ref( ) . map( |g| & g. value) ,
297+ Some ( Value :: Boolean ( false ) )
298+ ) {
299+ continue ;
300+ }
295301 let next_case_function = self . add_continuation ( "" ) ;
296302 let ( go_to_next_case, next_case_cp) =
297303 self . capture_current_continuation ( next_case_function, "when.next" ) ;
@@ -301,30 +307,34 @@ impl<'ctx> Codegen<'ctx> {
301307 {
302308 break ;
303309 }
304- let Some ( guard_bool) = self . compile_expression ( & handler. guard , "when.guard" ) else {
305- self . become_continuation_point ( next_case_cp) ;
306- self . begin_next_function ( next_case_function) ;
307- continue ;
308- } ;
309- let guard_flag = self . trilogy_boolean_untag ( guard_bool, "" ) ;
310- // NOTE: bool doesn't really need to be destroyed... but do it anyway
311- self . trilogy_value_destroy ( guard_bool) ;
312- let body_block = self . context . append_basic_block ( self . get_function ( ) , "body" ) ;
313- let next_block = self . context . append_basic_block ( self . get_function ( ) , "next" ) ;
314- let body_cp = self . branch_continuation_point ( ) ;
315- self . builder
316- . build_conditional_branch ( guard_flag, body_block, next_block)
317- . unwrap ( ) ;
318- let snapshot = self . snapshot_function_context ( ) ;
319-
320- self . builder . position_at_end ( next_block) ;
321- let go_next = self . use_temporary_clone ( go_to_next_case) . unwrap ( ) ;
322- self . void_call_continuation ( go_next) ;
323-
324- self . builder . position_at_end ( body_block) ;
325- self . destroy_owned_temporary ( go_to_next_case) ;
326- self . restore_function_context ( snapshot) ;
327- self . become_continuation_point ( body_cp) ;
310+ if let Some ( guard) = & handler. guard
311+ && !matches ! ( guard. value, Value :: Boolean ( true ) )
312+ {
313+ let Some ( guard_bool) = self . compile_expression ( guard, "when.guard" ) else {
314+ self . become_continuation_point ( next_case_cp) ;
315+ self . begin_next_function ( next_case_function) ;
316+ continue ;
317+ } ;
318+ let guard_flag = self . trilogy_boolean_untag ( guard_bool, "" ) ;
319+ // NOTE: bool doesn't really need to be destroyed... but do it anyway
320+ self . trilogy_value_destroy ( guard_bool) ;
321+ let body_block = self . context . append_basic_block ( self . get_function ( ) , "body" ) ;
322+ let next_block = self . context . append_basic_block ( self . get_function ( ) , "next" ) ;
323+ let body_cp = self . branch_continuation_point ( ) ;
324+ self . builder
325+ . build_conditional_branch ( guard_flag, body_block, next_block)
326+ . unwrap ( ) ;
327+ let snapshot = self . snapshot_function_context ( ) ;
328+
329+ self . builder . position_at_end ( next_block) ;
330+ let go_next = self . use_temporary_clone ( go_to_next_case) . unwrap ( ) ;
331+ self . void_call_continuation ( go_next) ;
332+
333+ self . builder . position_at_end ( body_block) ;
334+ self . destroy_owned_temporary ( go_to_next_case) ;
335+ self . restore_function_context ( snapshot) ;
336+ self . become_continuation_point ( body_cp) ;
337+ }
328338 self . push_handler_scope ( resume) ;
329339 if let Some ( result) = self . compile_expression ( & handler. body , "handler_result" ) {
330340 // If a handler runs off, it ends. Most handlers should choose to explicitly cancel
@@ -545,7 +555,10 @@ impl<'ctx> Codegen<'ctx> {
545555 for case in & expr. cases {
546556 // An unmatchable case can be skipped; rare this would occur, but easy to handle
547557 // since we're handling true specially anyway
548- if matches ! ( case. guard. value, Value :: Boolean ( false ) ) {
558+ if matches ! (
559+ case. guard. as_ref( ) . map( |g| & g. value) ,
560+ Some ( Value :: Boolean ( false ) )
561+ ) {
549562 continue ;
550563 }
551564
@@ -554,8 +567,10 @@ impl<'ctx> Codegen<'ctx> {
554567 self . capture_current_continuation ( next_case_function, "match.next" ) ;
555568 self . compile_pattern_match ( & case. pattern , discriminant, go_to_next_case) ?;
556569
557- if !matches ! ( case. guard. value, Value :: Boolean ( true ) ) {
558- let Some ( guard_bool) = self . compile_expression ( & case. guard , "match.guard" ) else {
570+ if let Some ( guard) = & case. guard
571+ && !matches ! ( guard. value, Value :: Boolean ( true ) )
572+ {
573+ let Some ( guard_bool) = self . compile_expression ( guard, "match.guard" ) else {
559574 self . become_continuation_point ( next_case_cp) ;
560575 self . begin_next_function ( next_case_function) ;
561576 continue ;
0 commit comments