1
1
//! Print diagnostics to explain why values are borrowed.
2
2
3
3
use rustc_errors:: { Applicability , Diagnostic } ;
4
+ use rustc_hir as hir;
5
+ use rustc_hir:: intravisit:: Visitor ;
4
6
use rustc_index:: vec:: IndexVec ;
5
7
use rustc_infer:: infer:: NllRegionVariableOrigin ;
6
8
use rustc_middle:: mir:: {
@@ -11,6 +13,7 @@ use rustc_middle::ty::adjustment::PointerCast;
11
13
use rustc_middle:: ty:: { self , RegionVid , TyCtxt } ;
12
14
use rustc_span:: symbol:: { kw, Symbol } ;
13
15
use rustc_span:: { sym, DesugaringKind , Span } ;
16
+ use rustc_trait_selection:: traits:: error_reporting:: FindExprBySpan ;
14
17
15
18
use crate :: region_infer:: { BlameConstraint , ExtraConstraintInfo } ;
16
19
use crate :: {
@@ -63,6 +66,36 @@ impl<'tcx> BorrowExplanation<'tcx> {
63
66
borrow_span : Option < Span > ,
64
67
multiple_borrow_span : Option < ( Span , Span ) > ,
65
68
) {
69
+ if let Some ( span) = borrow_span {
70
+ let def_id = body. source . def_id ( ) ;
71
+ if let Some ( node) = tcx. hir ( ) . get_if_local ( def_id)
72
+ && let Some ( body_id) = node. body_id ( )
73
+ {
74
+ let body = tcx. hir ( ) . body ( body_id) ;
75
+ let mut expr_finder = FindExprBySpan :: new ( span) ;
76
+ expr_finder. visit_expr ( body. value ) ;
77
+ if let Some ( mut expr) = expr_finder. result {
78
+ while let hir:: ExprKind :: AddrOf ( _, _, inner)
79
+ | hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , inner)
80
+ | hir:: ExprKind :: Field ( inner, _)
81
+ | hir:: ExprKind :: MethodCall ( _, inner, _, _)
82
+ | hir:: ExprKind :: Index ( inner, _) = & expr. kind
83
+ {
84
+ expr = inner;
85
+ }
86
+ if let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None , p) ) = expr. kind
87
+ && let [ hir:: PathSegment { ident, args : None , .. } ] = p. segments
88
+ && let hir:: def:: Res :: Local ( hir_id) = p. res
89
+ && let Some ( hir:: Node :: Pat ( pat) ) = tcx. hir ( ) . find ( hir_id)
90
+ {
91
+ err. span_label (
92
+ pat. span ,
93
+ & format ! ( "binding `{ident}` declared here" ) ,
94
+ ) ;
95
+ }
96
+ }
97
+ }
98
+ }
66
99
match * self {
67
100
BorrowExplanation :: UsedLater ( later_use_kind, var_or_use_span, path_span) => {
68
101
let message = match later_use_kind {
0 commit comments