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