@@ -29,12 +29,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
29
29
pat : & ' gcx hir:: Pat ,
30
30
mut expected : Ty < ' tcx > ,
31
31
mut def_bm : ty:: BindingMode ,
32
- is_arg : bool )
33
- {
32
+ match_discrim_span : Option < Span > ,
33
+ ) {
34
34
let tcx = self . tcx ;
35
35
36
- debug ! ( "check_pat_walk(pat={:?},expected={:?},def_bm={:?},is_arg={})" ,
37
- pat, expected, def_bm, is_arg) ;
36
+ debug ! ( "check_pat_walk(pat={:?},expected={:?},def_bm={:?})" , pat, expected, def_bm) ;
38
37
39
38
let is_non_ref_pat = match pat. node {
40
39
PatKind :: Struct ( ..) |
@@ -210,8 +209,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
210
209
let common_type = self . resolve_type_vars_if_possible ( & lhs_ty) ;
211
210
212
211
// subtyping doesn't matter here, as the value is some kind of scalar
213
- self . demand_eqtype ( pat. span , expected, lhs_ty) ;
214
- self . demand_eqtype ( pat. span , expected, rhs_ty) ;
212
+ self . demand_eqtype_pat ( pat. span , expected, lhs_ty, match_discrim_span ) ;
213
+ self . demand_eqtype_pat ( pat. span , expected, rhs_ty, match_discrim_span ) ;
215
214
common_type
216
215
}
217
216
PatKind :: Binding ( ba, var_id, _, ref sub) => {
@@ -240,37 +239,45 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
240
239
// `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
241
240
// required. However, we use equality, which is stronger. See (*) for
242
241
// an explanation.
243
- self . demand_eqtype ( pat. span , region_ty, local_ty) ;
242
+ self . demand_eqtype_pat ( pat. span , region_ty, local_ty, match_discrim_span ) ;
244
243
}
245
244
// otherwise the type of x is the expected type T
246
245
ty:: BindByValue ( _) => {
247
246
// As above, `T <: typeof(x)` is required but we
248
247
// use equality, see (*) below.
249
- self . demand_eqtype ( pat. span , expected, local_ty) ;
248
+ self . demand_eqtype_pat ( pat. span , expected, local_ty, match_discrim_span ) ;
250
249
}
251
250
}
252
251
253
252
// if there are multiple arms, make sure they all agree on
254
253
// what the type of the binding `x` ought to be
255
254
if var_id != pat. id {
256
255
let vt = self . local_ty ( pat. span , var_id) . decl_ty ;
257
- self . demand_eqtype ( pat. span , vt, local_ty) ;
256
+ self . demand_eqtype_pat ( pat. span , vt, local_ty, match_discrim_span ) ;
258
257
}
259
258
260
259
if let Some ( ref p) = * sub {
261
- self . check_pat_walk ( & p, expected, def_bm, true ) ;
260
+ self . check_pat_walk ( & p, expected, def_bm, match_discrim_span ) ;
262
261
}
263
262
264
263
local_ty
265
264
}
266
265
PatKind :: TupleStruct ( ref qpath, ref subpats, ddpos) => {
267
- self . check_pat_tuple_struct ( pat, qpath, & subpats, ddpos, expected, def_bm)
266
+ self . check_pat_tuple_struct (
267
+ pat,
268
+ qpath,
269
+ & subpats,
270
+ ddpos,
271
+ expected,
272
+ def_bm,
273
+ match_discrim_span,
274
+ )
268
275
}
269
276
PatKind :: Path ( ref qpath) => {
270
277
self . check_pat_path ( pat, qpath, expected)
271
278
}
272
279
PatKind :: Struct ( ref qpath, ref fields, etc) => {
273
- self . check_pat_struct ( pat, qpath, fields, etc, expected, def_bm)
280
+ self . check_pat_struct ( pat, qpath, fields, etc, expected, def_bm, match_discrim_span )
274
281
}
275
282
PatKind :: Tuple ( ref elements, ddpos) => {
276
283
let mut expected_len = elements. len ( ) ;
@@ -295,12 +302,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
295
302
// further errors being emitted when using the bindings. #50333
296
303
let element_tys_iter = ( 0 ..max_len) . map ( |_| tcx. types . err ) ;
297
304
for ( _, elem) in elements. iter ( ) . enumerate_and_adjust ( max_len, ddpos) {
298
- self . check_pat_walk ( elem, & tcx. types . err , def_bm, true ) ;
305
+ self . check_pat_walk ( elem, & tcx. types . err , def_bm, match_discrim_span ) ;
299
306
}
300
307
tcx. mk_tup ( element_tys_iter)
301
308
} else {
302
309
for ( i, elem) in elements. iter ( ) . enumerate_and_adjust ( max_len, ddpos) {
303
- self . check_pat_walk ( elem, & element_tys[ i] , def_bm, true ) ;
310
+ self . check_pat_walk ( elem, & element_tys[ i] , def_bm, match_discrim_span ) ;
304
311
}
305
312
pat_ty
306
313
}
@@ -313,11 +320,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
313
320
// Here, `demand::subtype` is good enough, but I don't
314
321
// think any errors can be introduced by using
315
322
// `demand::eqtype`.
316
- self . demand_eqtype ( pat. span , expected, uniq_ty) ;
317
- self . check_pat_walk ( & inner, inner_ty, def_bm, true ) ;
323
+ self . demand_eqtype_pat ( pat. span , expected, uniq_ty, match_discrim_span ) ;
324
+ self . check_pat_walk ( & inner, inner_ty, def_bm, match_discrim_span ) ;
318
325
uniq_ty
319
326
} else {
320
- self . check_pat_walk ( & inner, tcx. types . err , def_bm, true ) ;
327
+ self . check_pat_walk ( & inner, tcx. types . err , def_bm, match_discrim_span ) ;
321
328
tcx. types . err
322
329
}
323
330
}
@@ -349,15 +356,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
349
356
// Look for a case like `fn foo(&foo: u32)` and suggest
350
357
// `fn foo(foo: &u32)`
351
358
if let Some ( mut err) = err {
352
- if is_arg {
353
- if let PatKind :: Binding ( ..) = inner. node {
354
- if let Ok ( snippet) = tcx. sess . source_map ( )
355
- . span_to_snippet ( pat. span )
356
- {
357
- err. help ( & format ! ( "did you mean `{}: &{}`?" ,
358
- & snippet[ 1 ..] ,
359
- expected) ) ;
360
- }
359
+ if let PatKind :: Binding ( ..) = inner. node {
360
+ if let Ok ( snippet) = tcx. sess . source_map ( )
361
+ . span_to_snippet ( pat. span )
362
+ {
363
+ err. help ( & format ! ( "did you mean `{}: &{}`?" ,
364
+ & snippet[ 1 ..] ,
365
+ expected) ) ;
361
366
}
362
367
}
363
368
err. emit ( ) ;
@@ -366,10 +371,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
366
371
}
367
372
} ;
368
373
369
- self . check_pat_walk ( & inner, inner_ty, def_bm, true ) ;
374
+ self . check_pat_walk ( & inner, inner_ty, def_bm, match_discrim_span ) ;
370
375
rptr_ty
371
376
} else {
372
- self . check_pat_walk ( & inner, tcx. types . err , def_bm, true ) ;
377
+ self . check_pat_walk ( & inner, tcx. types . err , def_bm, match_discrim_span ) ;
373
378
tcx. types . err
374
379
}
375
380
}
@@ -427,13 +432,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
427
432
} ;
428
433
429
434
for elt in before {
430
- self . check_pat_walk ( & elt, inner_ty, def_bm, true ) ;
435
+ self . check_pat_walk ( & elt, inner_ty, def_bm, match_discrim_span ) ;
431
436
}
432
437
if let Some ( ref slice) = * slice {
433
- self . check_pat_walk ( & slice, slice_ty, def_bm, true ) ;
438
+ self . check_pat_walk ( & slice, slice_ty, def_bm, match_discrim_span ) ;
434
439
}
435
440
for elt in after {
436
- self . check_pat_walk ( & elt, inner_ty, def_bm, true ) ;
441
+ self . check_pat_walk ( & elt, inner_ty, def_bm, match_discrim_span ) ;
437
442
}
438
443
expected_ty
439
444
}
@@ -524,12 +529,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
524
529
true
525
530
}
526
531
527
- pub fn check_match ( & self ,
528
- expr : & ' gcx hir:: Expr ,
529
- discrim : & ' gcx hir:: Expr ,
530
- arms : & ' gcx [ hir:: Arm ] ,
531
- expected : Expectation < ' tcx > ,
532
- match_src : hir:: MatchSource ) -> Ty < ' tcx > {
532
+ pub fn check_match (
533
+ & self ,
534
+ expr : & ' gcx hir:: Expr ,
535
+ discrim : & ' gcx hir:: Expr ,
536
+ arms : & ' gcx [ hir:: Arm ] ,
537
+ expected : Expectation < ' tcx > ,
538
+ match_src : hir:: MatchSource ,
539
+ ) -> Ty < ' tcx > {
533
540
let tcx = self . tcx ;
534
541
535
542
// Not entirely obvious: if matches may create ref bindings, we want to
@@ -624,8 +631,12 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
624
631
let mut all_pats_diverge = Diverges :: WarnedAlways ;
625
632
for p in & arm. pats {
626
633
self . diverges . set ( Diverges :: Maybe ) ;
627
- self . check_pat_walk ( & p, discrim_ty,
628
- ty:: BindingMode :: BindByValue ( hir:: Mutability :: MutImmutable ) , true ) ;
634
+ self . check_pat_walk (
635
+ & p,
636
+ discrim_ty,
637
+ ty:: BindingMode :: BindByValue ( hir:: Mutability :: MutImmutable ) ,
638
+ Some ( discrim. span ) ,
639
+ ) ;
629
640
all_pats_diverge &= self . diverges . get ( ) ;
630
641
}
631
642
@@ -703,26 +714,29 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
703
714
coercion. complete ( self )
704
715
}
705
716
706
- fn check_pat_struct ( & self ,
707
- pat : & ' gcx hir:: Pat ,
708
- qpath : & hir:: QPath ,
709
- fields : & ' gcx [ Spanned < hir:: FieldPat > ] ,
710
- etc : bool ,
711
- expected : Ty < ' tcx > ,
712
- def_bm : ty:: BindingMode ) -> Ty < ' tcx >
717
+ fn check_pat_struct (
718
+ & self ,
719
+ pat : & ' gcx hir:: Pat ,
720
+ qpath : & hir:: QPath ,
721
+ fields : & ' gcx [ Spanned < hir:: FieldPat > ] ,
722
+ etc : bool ,
723
+ expected : Ty < ' tcx > ,
724
+ def_bm : ty:: BindingMode ,
725
+ match_discrim_span : Option < Span > ,
726
+ ) -> Ty < ' tcx >
713
727
{
714
728
// Resolve the path and check the definition for errors.
715
729
let ( variant, pat_ty) = if let Some ( variant_ty) = self . check_struct_path ( qpath, pat. id ) {
716
730
variant_ty
717
731
} else {
718
732
for field in fields {
719
- self . check_pat_walk ( & field. node . pat , self . tcx . types . err , def_bm, true ) ;
733
+ self . check_pat_walk ( & field. node . pat , self . tcx . types . err , def_bm, match_discrim_span ) ;
720
734
}
721
735
return self . tcx . types . err ;
722
736
} ;
723
737
724
738
// Type-check the path.
725
- self . demand_eqtype ( pat. span , expected, pat_ty) ;
739
+ self . demand_eqtype_pat ( pat. span , expected, pat_ty, match_discrim_span ) ;
726
740
727
741
// Type-check subpatterns.
728
742
if self . check_struct_pat_fields ( pat_ty, pat. id , pat. span , variant, fields, etc, def_bm) {
@@ -732,11 +746,12 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
732
746
}
733
747
}
734
748
735
- fn check_pat_path ( & self ,
736
- pat : & hir:: Pat ,
737
- qpath : & hir:: QPath ,
738
- expected : Ty < ' tcx > ) -> Ty < ' tcx >
739
- {
749
+ fn check_pat_path (
750
+ & self ,
751
+ pat : & hir:: Pat ,
752
+ qpath : & hir:: QPath ,
753
+ expected : Ty < ' tcx > ,
754
+ ) -> Ty < ' tcx > {
740
755
let tcx = self . tcx ;
741
756
742
757
// Resolve the path and check the definition for errors.
@@ -767,18 +782,20 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
767
782
pat_ty
768
783
}
769
784
770
- fn check_pat_tuple_struct ( & self ,
771
- pat : & hir:: Pat ,
772
- qpath : & hir:: QPath ,
773
- subpats : & ' gcx [ P < hir:: Pat > ] ,
774
- ddpos : Option < usize > ,
775
- expected : Ty < ' tcx > ,
776
- def_bm : ty:: BindingMode ) -> Ty < ' tcx >
777
- {
785
+ fn check_pat_tuple_struct (
786
+ & self ,
787
+ pat : & hir:: Pat ,
788
+ qpath : & hir:: QPath ,
789
+ subpats : & ' gcx [ P < hir:: Pat > ] ,
790
+ ddpos : Option < usize > ,
791
+ expected : Ty < ' tcx > ,
792
+ def_bm : ty:: BindingMode ,
793
+ match_arm_pat_span : Option < Span > ,
794
+ ) -> Ty < ' tcx > {
778
795
let tcx = self . tcx ;
779
796
let on_error = || {
780
797
for pat in subpats {
781
- self . check_pat_walk ( & pat, tcx. types . err , def_bm, true ) ;
798
+ self . check_pat_walk ( & pat, tcx. types . err , def_bm, match_arm_pat_span ) ;
782
799
}
783
800
} ;
784
801
let report_unexpected_def = |def : Def | {
@@ -826,7 +843,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
826
843
let pat_ty = pat_ty. fn_sig ( tcx) . output ( ) ;
827
844
let pat_ty = pat_ty. no_bound_vars ( ) . expect ( "expected fn type" ) ;
828
845
829
- self . demand_eqtype ( pat. span , expected, pat_ty) ;
846
+ self . demand_eqtype_pat ( pat. span , expected, pat_ty, match_arm_pat_span ) ;
830
847
831
848
// Type-check subpatterns.
832
849
if subpats. len ( ) == variant. fields . len ( ) ||
@@ -837,7 +854,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
837
854
} ;
838
855
for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( variant. fields . len ( ) , ddpos) {
839
856
let field_ty = self . field_ty ( subpat. span , & variant. fields [ i] , substs) ;
840
- self . check_pat_walk ( & subpat, field_ty, def_bm, true ) ;
857
+ self . check_pat_walk ( & subpat, field_ty, def_bm, match_arm_pat_span ) ;
841
858
842
859
self . tcx . check_stability ( variant. fields [ i] . did , Some ( pat. id ) , subpat. span ) ;
843
860
}
@@ -917,7 +934,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
917
934
}
918
935
} ;
919
936
920
- self . check_pat_walk ( & field. pat , field_ty, def_bm, true ) ;
937
+ self . check_pat_walk ( & field. pat , field_ty, def_bm, None ) ;
921
938
}
922
939
let mut unmentioned_fields = variant. fields
923
940
. iter ( )
0 commit comments