@@ -2,12 +2,14 @@ use rustc_lint::{LateLintPass, LateContext};
2
2
use rustc_ast:: ast:: Attribute ;
3
3
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
4
4
use rustc_errors:: Applicability ;
5
- use rustc_hir:: intravisit:: FnKind ;
5
+ use rustc_hir:: intravisit:: { FnKind , walk_expr , NestedVisitorMap , Visitor } ;
6
6
use rustc_span:: source_map:: Span ;
7
7
use rustc_middle:: lint:: in_external_macro;
8
+ use rustc_middle:: hir:: map:: Map ;
9
+ use rustc_middle:: ty:: subst:: GenericArgKind ;
8
10
use rustc_hir:: { Block , Body , Expr , ExprKind , FnDecl , HirId , MatchSource , StmtKind } ;
9
11
10
- use crate :: utils:: { snippet_opt, span_lint_and_sugg, span_lint_and_then} ;
12
+ use crate :: utils:: { fn_def_id , snippet_opt, span_lint_and_sugg, span_lint_and_then} ;
11
13
12
14
declare_clippy_lint ! {
13
15
/// **What it does:** Checks for return statements at the end of a block.
@@ -164,3 +166,42 @@ fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, inner_span: Option<Spa
164
166
} ,
165
167
}
166
168
}
169
+
170
+ fn last_statement_borrows < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) -> bool {
171
+ let mut visitor = BorrowVisitor { cx, borrows : false } ;
172
+ walk_expr ( & mut visitor, expr) ;
173
+ visitor. borrows
174
+ }
175
+
176
+ struct BorrowVisitor < ' a , ' tcx > {
177
+ cx : & ' a LateContext < ' tcx > ,
178
+ borrows : bool ,
179
+ }
180
+
181
+ impl < ' tcx > Visitor < ' tcx > for BorrowVisitor < ' _ , ' tcx > {
182
+ type Map = Map < ' tcx > ;
183
+
184
+ fn visit_expr ( & mut self , expr : & ' tcx Expr < ' _ > ) {
185
+ if self . borrows {
186
+ return ;
187
+ }
188
+
189
+ if let Some ( def_id) = fn_def_id ( self . cx , expr) {
190
+ self . borrows = self
191
+ . cx
192
+ . tcx
193
+ . fn_sig ( def_id)
194
+ . output ( )
195
+ . skip_binder ( )
196
+ . walk ( )
197
+ . any ( |arg| matches ! ( arg. unpack( ) , GenericArgKind :: Lifetime ( _) ) ) ;
198
+ }
199
+
200
+ walk_expr ( self , expr) ;
201
+ }
202
+
203
+ fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
204
+ NestedVisitorMap :: None
205
+ }
206
+ }
207
+
0 commit comments