@@ -9,9 +9,9 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
9
9
use rustc_hir:: { HirId , Pat , PatKind } ;
10
10
use rustc_infer:: infer;
11
11
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
12
- use rustc_infer:: traits:: Pattern ;
12
+ use rustc_infer:: traits:: { ObligationCause , Pattern } ;
13
13
use rustc_span:: hygiene:: DesugaringKind ;
14
- use rustc_span:: Span ;
14
+ use rustc_span:: source_map :: { Span , Spanned } ;
15
15
use syntax:: ast;
16
16
use syntax:: util:: lev_distance:: find_best_match_for_name;
17
17
@@ -66,16 +66,19 @@ struct TopInfo<'tcx> {
66
66
}
67
67
68
68
impl < ' tcx > FnCtxt < ' _ , ' tcx > {
69
+ fn pattern_cause ( & self , ti : TopInfo < ' tcx > , cause_span : Span ) -> ObligationCause < ' tcx > {
70
+ let code = Pattern { span : ti. span , root_ty : ti. expected , origin_expr : ti. origin_expr } ;
71
+ self . cause ( cause_span, code)
72
+ }
73
+
69
74
fn demand_eqtype_pat_diag (
70
75
& self ,
71
76
cause_span : Span ,
72
77
expected : Ty < ' tcx > ,
73
78
actual : Ty < ' tcx > ,
74
79
ti : TopInfo < ' tcx > ,
75
80
) -> Option < DiagnosticBuilder < ' tcx > > {
76
- let code = Pattern { span : ti. span , root_ty : ti. expected , origin_expr : ti. origin_expr } ;
77
- let cause = self . cause ( cause_span, code) ;
78
- self . demand_eqtype_with_origin ( & cause, expected, actual)
81
+ self . demand_eqtype_with_origin ( & self . pattern_cause ( ti, cause_span) , expected, actual)
79
82
}
80
83
81
84
fn demand_eqtype_pat (
@@ -152,7 +155,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
152
155
self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos, expected, def_bm, ti)
153
156
}
154
157
PatKind :: Path ( ref qpath) => {
155
- self . check_pat_path ( pat, path_res. unwrap ( ) , qpath, expected)
158
+ self . check_pat_path ( pat, path_res. unwrap ( ) , qpath, expected, ti )
156
159
}
157
160
PatKind :: Struct ( ref qpath, fields, etc) => {
158
161
self . check_pat_struct ( pat, qpath, fields, etc, expected, def_bm, ti)
@@ -361,16 +364,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
361
364
// Byte string patterns behave the same way as array patterns
362
365
// They can denote both statically and dynamically-sized byte arrays.
363
366
let mut pat_ty = ty;
364
- if let hir:: ExprKind :: Lit ( ref lt) = lt. kind {
365
- if let ast:: LitKind :: ByteStr ( _) = lt. node {
366
- let expected_ty = self . structurally_resolved_type ( span, expected) ;
367
- if let ty:: Ref ( _, r_ty, _) = expected_ty. kind {
368
- if let ty:: Slice ( _) = r_ty. kind {
369
- let tcx = self . tcx ;
370
- pat_ty =
371
- tcx. mk_imm_ref ( tcx. lifetimes . re_static , tcx. mk_slice ( tcx. types . u8 ) ) ;
372
- }
373
- }
367
+ if let hir:: ExprKind :: Lit ( Spanned { node : ast:: LitKind :: ByteStr ( _) , .. } ) = lt. kind {
368
+ let expected = self . structurally_resolved_type ( span, expected) ;
369
+ if let ty:: Ref ( _, ty:: TyS { kind : ty:: Slice ( _) , .. } , _) = expected. kind {
370
+ let tcx = self . tcx ;
371
+ pat_ty = tcx. mk_imm_ref ( tcx. lifetimes . re_static , tcx. mk_slice ( tcx. types . u8 ) ) ;
374
372
}
375
373
}
376
374
@@ -384,7 +382,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
384
382
// &'static str <: expected
385
383
//
386
384
// then that's equivalent to there existing a LUB.
387
- if let Some ( mut err) = self . demand_suptype_diag ( span, expected, pat_ty) {
385
+ let cause = self . pattern_cause ( ti, span) ;
386
+ if let Some ( mut err) = self . demand_suptype_with_origin ( & cause, expected, pat_ty) {
388
387
err. emit_unless (
389
388
ti. span
390
389
. filter ( |& s| {
@@ -543,8 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
543
542
// If there are multiple arms, make sure they all agree on
544
543
// what the type of the binding `x` ought to be.
545
544
if var_id != pat. hir_id {
546
- let vt = self . local_ty ( pat. span , var_id) . decl_ty ;
547
- self . demand_eqtype_pat ( pat. span , vt, local_ty, ti) ;
545
+ self . check_binding_alt_eq_ty ( pat. span , var_id, local_ty, ti) ;
548
546
}
549
547
550
548
if let Some ( p) = sub {
@@ -554,6 +552,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
554
552
local_ty
555
553
}
556
554
555
+ fn check_binding_alt_eq_ty ( & self , span : Span , var_id : HirId , ty : Ty < ' tcx > , ti : TopInfo < ' tcx > ) {
556
+ let var_ty = self . local_ty ( span, var_id) . decl_ty ;
557
+ if let Some ( mut err) = self . demand_eqtype_pat_diag ( span, var_ty, ty, ti) {
558
+ let hir = self . tcx . hir ( ) ;
559
+ let var_ty = self . resolve_vars_with_obligations ( var_ty) ;
560
+ let msg = format ! ( "first introduced with type `{}` here" , var_ty) ;
561
+ err. span_label ( hir. span ( var_id) , msg) ;
562
+ let in_arm = hir. parent_iter ( var_id) . any ( |( _, n) | matches ! ( n, hir:: Node :: Arm ( ..) ) ) ;
563
+ let pre = if in_arm { "in the same arm, " } else { "" } ;
564
+ err. note ( & format ! ( "{}a binding must have the same type in all alternatives" , pre) ) ;
565
+ err. emit ( ) ;
566
+ }
567
+ }
568
+
557
569
fn borrow_pat_suggestion (
558
570
& self ,
559
571
err : & mut DiagnosticBuilder < ' _ > ,
@@ -659,6 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
659
671
path_resolution : ( Res , Option < Ty < ' tcx > > , & ' b [ hir:: PathSegment < ' b > ] ) ,
660
672
qpath : & hir:: QPath < ' _ > ,
661
673
expected : Ty < ' tcx > ,
674
+ ti : TopInfo < ' tcx > ,
662
675
) -> Ty < ' tcx > {
663
676
let tcx = self . tcx ;
664
677
@@ -684,7 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
684
697
685
698
// Type-check the path.
686
699
let pat_ty = self . instantiate_value_path ( segments, opt_ty, res, pat. span , pat. hir_id ) . 0 ;
687
- self . demand_suptype ( pat. span , expected, pat_ty) ;
700
+ if let Some ( mut err) =
701
+ self . demand_suptype_with_origin ( & self . pattern_cause ( ti, pat. span ) , expected, pat_ty)
702
+ {
703
+ err. emit ( ) ;
704
+ }
688
705
pat_ty
689
706
}
690
707
@@ -901,7 +918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
901
918
} ) ;
902
919
let element_tys = tcx. mk_substs ( element_tys_iter) ;
903
920
let pat_ty = tcx. mk_ty ( ty:: Tuple ( element_tys) ) ;
904
- if let Some ( mut err) = self . demand_eqtype_diag ( span, expected, pat_ty) {
921
+ if let Some ( mut err) = self . demand_eqtype_pat_diag ( span, expected, pat_ty, ti ) {
905
922
err. emit ( ) ;
906
923
// Walk subpatterns with an expected type of `err` in this case to silence
907
924
// further errors being emitted when using the bindings. #50333
@@ -1205,7 +1222,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1205
1222
} ) ;
1206
1223
let rptr_ty = self . new_ref_ty ( pat. span , mutbl, inner_ty) ;
1207
1224
debug ! ( "check_pat_ref: demanding {:?} = {:?}" , expected, rptr_ty) ;
1208
- let err = self . demand_eqtype_diag ( pat. span , expected, rptr_ty) ;
1225
+ let err = self . demand_eqtype_pat_diag ( pat. span , expected, rptr_ty, ti ) ;
1209
1226
1210
1227
// Look for a case like `fn foo(&foo: u32)` and suggest
1211
1228
// `fn foo(foo: &u32)`
0 commit comments