@@ -330,6 +330,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
330330 ) ;
331331 }
332332
333+ // handle patterns like `None | None` or two different arms that
334+ // have the same pattern.
335+ //
336+ // NOTE: why this works is a bit subtle: we always want to pick the
337+ // first arm for a pattern, and because this is a stable sort that
338+ // works out.
339+ arm_blocks. sort_by_key( |( _, discr, _, _) | discr. val) ;
340+ arm_blocks. dedup_by_key( |( _, discr, _, _) | discr. val) ;
341+
333342 // if we're matching on an enum, the discriminant order in the `SwitchInt`
334343 // targets should match the order yielded by `AdtDef::discriminants`.
335344 if state_ty. is_enum( ) {
@@ -378,6 +387,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
378387 . chain( otherwise) ;
379388
380389 for ( mut block, arm) in it {
390+ if this. cfg. block_data( block) . terminator. is_some( ) {
391+ continue ; // this can occur with or-patterns
392+ }
393+
381394 let empty_place = this. get_unit_temp( ) ;
382395 unpack!(
383396 block = this. expr_into_dest(
@@ -850,8 +863,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
850863 result. push ( ( VariantIdx :: ZERO , discr, block, arm_id) ) ;
851864 }
852865 Constructor :: Wildcard => {
866+ // the first wildcard wins
867+ if otherwise. is_none ( ) {
868+ let block = current_block. unwrap_or_else ( || self . cfg . start_new_block ( ) ) ;
869+ * otherwise = Some ( ( block, arm_id) )
870+ }
871+ }
872+ Constructor :: Or => {
853873 let block = current_block. unwrap_or_else ( || self . cfg . start_new_block ( ) ) ;
854- * otherwise = Some ( ( block, arm_id) )
874+
875+ for indexed in pat. iter_fields ( ) {
876+ self . loop_match_patterns ( arm_id, & indexed. pat , Some ( block) , result, otherwise) ;
877+ }
855878 }
856879 other => todo ! ( "{:?}" , other) ,
857880 }
0 commit comments