@@ -27,14 +27,38 @@ use rustc_span::Span;
27
27
/// employing the ExprUseVisitor.
28
28
pub trait Delegate < ' tcx > {
29
29
// The value found at `place` is either copied or moved, depending
30
- // on mode.
31
- fn consume ( & mut self , place_with_id : & PlaceWithHirId < ' tcx > , mode : ConsumeMode ) ;
30
+ // on mode. Where `diag_expr_id` is the id used for diagnostics for `place`.
31
+ //
32
+ // The reson for a separate expr_id for diagonostics is to support cases
33
+ // like `let pat = upvar`, in such scenarios reporting the pattern (lhs)
34
+ // looks confusing. Instead we prefer to report the discriminant (rhs)
35
+ fn consume (
36
+ & mut self ,
37
+ place_with_id : & PlaceWithHirId < ' tcx > ,
38
+ diag_expr_id : hir:: HirId ,
39
+ mode : ConsumeMode ,
40
+ ) ;
32
41
33
42
// The value found at `place` is being borrowed with kind `bk`.
34
- fn borrow ( & mut self , place_with_id : & PlaceWithHirId < ' tcx > , bk : ty:: BorrowKind ) ;
35
-
36
- // The path at `place_with_id` is being assigned to.
37
- fn mutate ( & mut self , assignee_place : & PlaceWithHirId < ' tcx > ) ;
43
+ // `diag_expr_id` is the id used for diagnostics for `place`.
44
+ //
45
+ // The reson for a separate expr_id for diagonostics is to support cases
46
+ // like `let pat = upvar`, in such scenarios reporting the pattern (lhs)
47
+ // looks confusing. Instead we prefer to report the discriminant (rhs)
48
+ fn borrow (
49
+ & mut self ,
50
+ place_with_id : & PlaceWithHirId < ' tcx > ,
51
+ diag_expr_id : hir:: HirId ,
52
+ bk : ty:: BorrowKind ,
53
+ ) ;
54
+
55
+ // The path at `assignee_place` is being assigned to.
56
+ // `diag_expr_id` is the id used for diagnostics for `place`.
57
+ //
58
+ // The reson for a separate expr_id for diagonostics is to support cases
59
+ // like `let pat = upvar`, in such scenarios reporting the pattern (lhs)
60
+ // looks confusing. Instead we prefer to report the discriminant (rhs)
61
+ fn mutate ( & mut self , assignee_place : & PlaceWithHirId < ' tcx > , diag_expr_id : hir:: HirId ) ;
38
62
}
39
63
40
64
#[ derive( Copy , Clone , PartialEq , Debug ) ]
@@ -116,11 +140,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
116
140
self . mc . tcx ( )
117
141
}
118
142
119
- fn delegate_consume ( & mut self , place_with_id : & PlaceWithHirId < ' tcx > ) {
143
+ fn delegate_consume ( & mut self , place_with_id : & PlaceWithHirId < ' tcx > , diag_expr_id : hir :: HirId ) {
120
144
debug ! ( "delegate_consume(place_with_id={:?})" , place_with_id) ;
121
145
122
146
let mode = copy_or_move ( & self . mc , place_with_id) ;
123
- self . delegate . consume ( place_with_id, mode) ;
147
+ self . delegate . consume ( place_with_id, diag_expr_id , mode) ;
124
148
}
125
149
126
150
fn consume_exprs ( & mut self , exprs : & [ hir:: Expr < ' _ > ] ) {
@@ -133,21 +157,21 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
133
157
debug ! ( "consume_expr(expr={:?})" , expr) ;
134
158
135
159
let place_with_id = return_if_err ! ( self . mc. cat_expr( expr) ) ;
136
- self . delegate_consume ( & place_with_id) ;
160
+ self . delegate_consume ( & place_with_id, place_with_id . hir_id ) ;
137
161
self . walk_expr ( expr) ;
138
162
}
139
163
140
164
fn mutate_expr ( & mut self , expr : & hir:: Expr < ' _ > ) {
141
165
let place_with_id = return_if_err ! ( self . mc. cat_expr( expr) ) ;
142
- self . delegate . mutate ( & place_with_id) ;
166
+ self . delegate . mutate ( & place_with_id, place_with_id . hir_id ) ;
143
167
self . walk_expr ( expr) ;
144
168
}
145
169
146
170
fn borrow_expr ( & mut self , expr : & hir:: Expr < ' _ > , bk : ty:: BorrowKind ) {
147
171
debug ! ( "borrow_expr(expr={:?}, bk={:?})" , expr, bk) ;
148
172
149
173
let place_with_id = return_if_err ! ( self . mc. cat_expr( expr) ) ;
150
- self . delegate . borrow ( & place_with_id, bk) ;
174
+ self . delegate . borrow ( & place_with_id, place_with_id . hir_id , bk) ;
151
175
152
176
self . walk_expr ( expr)
153
177
}
@@ -404,7 +428,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
404
428
with_field. ty ( self . tcx ( ) , substs) ,
405
429
ProjectionKind :: Field ( f_index as u32 , VariantIdx :: new ( 0 ) ) ,
406
430
) ;
407
- self . delegate_consume ( & field_place) ;
431
+ self . delegate_consume ( & field_place, field_place . hir_id ) ;
408
432
}
409
433
}
410
434
}
@@ -436,7 +460,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
436
460
adjustment:: Adjust :: NeverToAny | adjustment:: Adjust :: Pointer ( _) => {
437
461
// Creating a closure/fn-pointer or unsizing consumes
438
462
// the input and stores it into the resulting rvalue.
439
- self . delegate_consume ( & place_with_id) ;
463
+ self . delegate_consume ( & place_with_id, place_with_id . hir_id ) ;
440
464
}
441
465
442
466
adjustment:: Adjust :: Deref ( None ) => { }
@@ -448,7 +472,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
448
472
// this is an autoref of `x`.
449
473
adjustment:: Adjust :: Deref ( Some ( ref deref) ) => {
450
474
let bk = ty:: BorrowKind :: from_mutbl ( deref. mutbl ) ;
451
- self . delegate . borrow ( & place_with_id, bk) ;
475
+ self . delegate . borrow ( & place_with_id, place_with_id . hir_id , bk) ;
452
476
}
453
477
454
478
adjustment:: Adjust :: Borrow ( ref autoref) => {
@@ -476,13 +500,17 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
476
500
477
501
match * autoref {
478
502
adjustment:: AutoBorrow :: Ref ( _, m) => {
479
- self . delegate . borrow ( base_place, ty:: BorrowKind :: from_mutbl ( m. into ( ) ) ) ;
503
+ self . delegate . borrow (
504
+ base_place,
505
+ base_place. hir_id ,
506
+ ty:: BorrowKind :: from_mutbl ( m. into ( ) ) ,
507
+ ) ;
480
508
}
481
509
482
510
adjustment:: AutoBorrow :: RawPtr ( m) => {
483
511
debug ! ( "walk_autoref: expr.hir_id={} base_place={:?}" , expr. hir_id, base_place) ;
484
512
485
- self . delegate . borrow ( base_place, ty:: BorrowKind :: from_mutbl ( m) ) ;
513
+ self . delegate . borrow ( base_place, base_place . hir_id , ty:: BorrowKind :: from_mutbl ( m) ) ;
486
514
}
487
515
}
488
516
}
@@ -525,19 +553,22 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
525
553
// binding being produced.
526
554
let def = Res :: Local ( canonical_id) ;
527
555
if let Ok ( ref binding_place) = mc. cat_res( pat. hir_id, pat. span, pat_ty, def) {
528
- delegate. mutate( binding_place) ;
556
+ delegate. mutate( binding_place, binding_place . hir_id ) ;
529
557
}
530
558
531
559
// It is also a borrow or copy/move of the value being matched.
560
+ // In a cases of pattern like `let pat = upvar`, don't use the span
561
+ // of the pattern, as this just looks confusing, instead use the span
562
+ // of the discriminant.
532
563
match bm {
533
564
ty:: BindByReference ( m) => {
534
565
let bk = ty:: BorrowKind :: from_mutbl( m) ;
535
- delegate. borrow( place, bk) ;
566
+ delegate. borrow( place, discr_place . hir_id , bk) ;
536
567
}
537
568
ty:: BindByValue ( ..) => {
538
- let mode = copy_or_move( mc, place) ;
569
+ let mode = copy_or_move( mc, & place) ;
539
570
debug!( "walk_pat binding consuming pat" ) ;
540
- delegate. consume( place, mode) ;
571
+ delegate. consume( place, discr_place . hir_id , mode) ;
541
572
}
542
573
}
543
574
}
@@ -564,10 +595,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
564
595
match upvar_capture {
565
596
ty:: UpvarCapture :: ByValue ( _) => {
566
597
let mode = copy_or_move ( & self . mc , & captured_place) ;
567
- self . delegate . consume ( & captured_place, mode) ;
598
+ self . delegate . consume ( & captured_place, captured_place . hir_id , mode) ;
568
599
}
569
600
ty:: UpvarCapture :: ByRef ( upvar_borrow) => {
570
- self . delegate . borrow ( & captured_place, upvar_borrow. kind ) ;
601
+ self . delegate . borrow (
602
+ & captured_place,
603
+ captured_place. hir_id ,
604
+ upvar_borrow. kind ,
605
+ ) ;
571
606
}
572
607
}
573
608
}
0 commit comments