@@ -614,13 +614,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
614
614
err. span_label ( span, "expected due to this" ) ;
615
615
}
616
616
ObligationCauseCode :: MatchExpressionArm ( box MatchExpressionArmCause {
617
- semi_span,
617
+ arm_block_id,
618
+ arm_span,
619
+ arm_ty,
620
+ prior_arm_block_id,
621
+ prior_arm_span,
622
+ prior_arm_ty,
618
623
source,
619
624
ref prior_arms,
620
- last_ty,
621
625
scrut_hir_id,
622
626
opt_suggest_box_span,
623
- arm_span,
624
627
scrut_span,
625
628
..
626
629
} ) => match source {
@@ -651,10 +654,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
651
654
}
652
655
}
653
656
_ => {
654
- // `last_ty ` can be `!`, `expected` will have better info when present.
657
+ // `prior_arm_ty ` can be `!`, `expected` will have better info when present.
655
658
let t = self . resolve_vars_if_possible ( match exp_found {
656
659
Some ( ty:: error:: ExpectedFound { expected, .. } ) => expected,
657
- _ => last_ty ,
660
+ _ => prior_arm_ty ,
658
661
} ) ;
659
662
let source_map = self . tcx . sess . source_map ( ) ;
660
663
let mut any_multiline_arm = source_map. is_multiline ( arm_span) ;
@@ -679,37 +682,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
679
682
} ;
680
683
let msg = "`match` arms have incompatible types" ;
681
684
err. span_label ( outer_error_span, msg) ;
682
- if let Some ( ( sp, boxed) ) = semi_span {
683
- if let ( StatementAsExpression :: NeedsBoxing , [ .., prior_arm] ) =
684
- ( boxed, & prior_arms[ ..] )
685
- {
686
- err. multipart_suggestion (
687
- "consider removing this semicolon and boxing the expressions" ,
688
- vec ! [
689
- ( prior_arm. shrink_to_lo( ) , "Box::new(" . to_string( ) ) ,
690
- ( prior_arm. shrink_to_hi( ) , ")" . to_string( ) ) ,
691
- ( arm_span. shrink_to_lo( ) , "Box::new(" . to_string( ) ) ,
692
- ( arm_span. shrink_to_hi( ) , ")" . to_string( ) ) ,
693
- ( sp, String :: new( ) ) ,
694
- ] ,
695
- Applicability :: HasPlaceholders ,
696
- ) ;
697
- } else if matches ! ( boxed, StatementAsExpression :: NeedsBoxing ) {
698
- err. span_suggestion_short (
699
- sp,
700
- "consider removing this semicolon and boxing the expressions" ,
701
- "" ,
702
- Applicability :: MachineApplicable ,
703
- ) ;
704
- } else {
705
- err. span_suggestion_short (
706
- sp,
707
- "consider removing this semicolon" ,
708
- "" ,
709
- Applicability :: MachineApplicable ,
710
- ) ;
711
- }
712
- }
685
+ self . suggest_remove_semi_or_return_binding (
686
+ err,
687
+ prior_arm_block_id,
688
+ prior_arm_ty,
689
+ prior_arm_span,
690
+ arm_block_id,
691
+ arm_ty,
692
+ arm_span,
693
+ ) ;
713
694
if let Some ( ret_sp) = opt_suggest_box_span {
714
695
// Get return type span and point to it.
715
696
self . suggest_boxing_for_return_impl_trait (
@@ -734,48 +715,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
734
715
if let Some ( sp) = outer_span {
735
716
err. span_label ( sp, "`if` and `else` have incompatible types" ) ;
736
717
}
737
- let semicolon = if let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( then_id)
738
- && let Some ( remove_semicolon) = self . could_remove_semicolon ( blk, else_ty)
739
- {
740
- Some ( remove_semicolon)
741
- } else if let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( else_id)
742
- && let Some ( remove_semicolon) = self . could_remove_semicolon ( blk, then_ty)
743
- {
744
- Some ( remove_semicolon)
745
- } else {
746
- None
747
- } ;
748
- if let Some ( ( sp, boxed) ) = semicolon {
749
- if matches ! ( boxed, StatementAsExpression :: NeedsBoxing ) {
750
- err. multipart_suggestion (
751
- "consider removing this semicolon and boxing the expression" ,
752
- vec ! [
753
- ( then_span. shrink_to_lo( ) , "Box::new(" . to_string( ) ) ,
754
- ( then_span. shrink_to_hi( ) , ")" . to_string( ) ) ,
755
- ( else_span. shrink_to_lo( ) , "Box::new(" . to_string( ) ) ,
756
- ( else_span. shrink_to_hi( ) , ")" . to_string( ) ) ,
757
- ( sp, String :: new( ) ) ,
758
- ] ,
759
- Applicability :: MachineApplicable ,
760
- ) ;
761
- } else {
762
- err. span_suggestion_short (
763
- sp,
764
- "consider removing this semicolon" ,
765
- "" ,
766
- Applicability :: MachineApplicable ,
767
- ) ;
768
- }
769
- } else {
770
- let suggested = if let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( then_id) {
771
- self . consider_returning_binding ( blk, else_ty, err)
772
- } else {
773
- false
774
- } ;
775
- if !suggested && let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( else_id) {
776
- self . consider_returning_binding ( blk, then_ty, err) ;
777
- }
778
- }
718
+ self . suggest_remove_semi_or_return_binding (
719
+ err,
720
+ Some ( then_id) ,
721
+ then_ty,
722
+ then_span,
723
+ Some ( else_id) ,
724
+ else_ty,
725
+ else_span,
726
+ ) ;
779
727
if let Some ( ret_sp) = opt_suggest_box_span {
780
728
self . suggest_boxing_for_return_impl_trait (
781
729
err,
@@ -800,6 +748,69 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
800
748
}
801
749
}
802
750
751
+ fn suggest_remove_semi_or_return_binding (
752
+ & self ,
753
+ err : & mut Diagnostic ,
754
+ first_id : Option < hir:: HirId > ,
755
+ first_ty : Ty < ' tcx > ,
756
+ first_span : Span ,
757
+ second_id : Option < hir:: HirId > ,
758
+ second_ty : Ty < ' tcx > ,
759
+ second_span : Span ,
760
+ ) {
761
+ let semicolon =
762
+ if let Some ( first_id) = first_id
763
+ && let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( first_id)
764
+ && let Some ( remove_semicolon) = self . could_remove_semicolon ( blk, second_ty)
765
+ {
766
+ Some ( remove_semicolon)
767
+ } else if let Some ( second_id) = second_id
768
+ && let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( second_id)
769
+ && let Some ( remove_semicolon) = self . could_remove_semicolon ( blk, first_ty)
770
+ {
771
+ Some ( remove_semicolon)
772
+ } else {
773
+ None
774
+ } ;
775
+ if let Some ( ( sp, boxed) ) = semicolon {
776
+ if matches ! ( boxed, StatementAsExpression :: NeedsBoxing ) {
777
+ err. multipart_suggestion (
778
+ "consider removing this semicolon and boxing the expressions" ,
779
+ vec ! [
780
+ ( first_span. shrink_to_lo( ) , "Box::new(" . to_string( ) ) ,
781
+ ( first_span. shrink_to_hi( ) , ")" . to_string( ) ) ,
782
+ ( second_span. shrink_to_lo( ) , "Box::new(" . to_string( ) ) ,
783
+ ( second_span. shrink_to_hi( ) , ")" . to_string( ) ) ,
784
+ ( sp, String :: new( ) ) ,
785
+ ] ,
786
+ Applicability :: MachineApplicable ,
787
+ ) ;
788
+ } else {
789
+ err. span_suggestion_short (
790
+ sp,
791
+ "consider removing this semicolon" ,
792
+ "" ,
793
+ Applicability :: MachineApplicable ,
794
+ ) ;
795
+ }
796
+ } else {
797
+ let suggested =
798
+ if let Some ( first_id) = first_id
799
+ && let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( first_id)
800
+ {
801
+ self . consider_returning_binding ( blk, second_ty, err)
802
+ } else {
803
+ false
804
+ } ;
805
+ if !suggested
806
+ && let Some ( second_id) = second_id
807
+ && let hir:: Node :: Block ( blk) = self . tcx . hir ( ) . get ( second_id)
808
+ {
809
+ self . consider_returning_binding ( blk, first_ty, err) ;
810
+ }
811
+ }
812
+ }
813
+
803
814
fn suggest_boxing_for_return_impl_trait (
804
815
& self ,
805
816
err : & mut Diagnostic ,
0 commit comments