@@ -617,7 +617,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
617
617
// If there are multiple arms, make sure they all agree on
618
618
// what the type of the binding `x` ought to be.
619
619
if var_id != pat. hir_id {
620
- self . check_binding_alt_eq_ty ( pat. span , var_id, local_ty, ti) ;
620
+ self . check_binding_alt_eq_ty ( ba , pat. span , var_id, local_ty, ti) ;
621
621
}
622
622
623
623
if let Some ( p) = sub {
@@ -627,7 +627,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
627
627
local_ty
628
628
}
629
629
630
- fn check_binding_alt_eq_ty ( & self , span : Span , var_id : HirId , ty : Ty < ' tcx > , ti : TopInfo < ' tcx > ) {
630
+ fn check_binding_alt_eq_ty (
631
+ & self ,
632
+ ba : hir:: BindingAnnotation ,
633
+ span : Span ,
634
+ var_id : HirId ,
635
+ ty : Ty < ' tcx > ,
636
+ ti : TopInfo < ' tcx > ,
637
+ ) {
631
638
let var_ty = self . local_ty ( span, var_id) . decl_ty ;
632
639
if let Some ( mut err) = self . demand_eqtype_pat_diag ( span, var_ty, ty, ti) {
633
640
let hir = self . tcx . hir ( ) ;
@@ -645,12 +652,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
645
652
} ) ;
646
653
let pre = if in_match { "in the same arm, " } else { "" } ;
647
654
err. note ( & format ! ( "{}a binding must have the same type in all alternatives" , pre) ) ;
648
- // FIXME: check if `var_ty` and `ty` can be made the same type by adding or removing
649
- // `ref` or `&` to the pattern.
655
+ self . suggest_adding_missing_ref_or_removing_ref (
656
+ & mut err,
657
+ span,
658
+ var_ty,
659
+ self . resolve_vars_with_obligations ( ty) ,
660
+ ba,
661
+ ) ;
650
662
err. emit ( ) ;
651
663
}
652
664
}
653
665
666
+ fn suggest_adding_missing_ref_or_removing_ref (
667
+ & self ,
668
+ err : & mut Diagnostic ,
669
+ span : Span ,
670
+ expected : Ty < ' tcx > ,
671
+ actual : Ty < ' tcx > ,
672
+ ba : hir:: BindingAnnotation ,
673
+ ) {
674
+ match ( expected. kind ( ) , actual. kind ( ) , ba) {
675
+ ( ty:: Ref ( _, inner_ty, _) , _, hir:: BindingAnnotation :: Unannotated )
676
+ if self . can_eq ( self . param_env , * inner_ty, actual) . is_ok ( ) =>
677
+ {
678
+ err. span_suggestion_verbose (
679
+ span. shrink_to_lo ( ) ,
680
+ "consider adding `ref`" ,
681
+ "ref " ,
682
+ Applicability :: MaybeIncorrect ,
683
+ ) ;
684
+ }
685
+ ( _, ty:: Ref ( _, inner_ty, _) , hir:: BindingAnnotation :: Ref )
686
+ if self . can_eq ( self . param_env , expected, * inner_ty) . is_ok ( ) =>
687
+ {
688
+ err. span_suggestion_verbose (
689
+ span. with_hi ( span. lo ( ) + BytePos ( 4 ) ) ,
690
+ "consider removing `ref`" ,
691
+ "" ,
692
+ Applicability :: MaybeIncorrect ,
693
+ ) ;
694
+ }
695
+ _ => ( ) ,
696
+ }
697
+ }
698
+
654
699
// Precondition: pat is a Ref(_) pattern
655
700
fn borrow_pat_suggestion ( & self , err : & mut Diagnostic , pat : & Pat < ' _ > ) {
656
701
let tcx = self . tcx ;
0 commit comments