@@ -61,10 +61,26 @@ pub struct SignificantDropTightening<'tcx> {
6161}
6262
6363impl < ' tcx > SignificantDropTightening < ' tcx > {
64+ /// Unifies the statements of a block with its return expression.
65+ fn all_block_stmts < ' ret , ' rslt , ' stmts > (
66+ block_stmts : & ' stmts [ hir:: Stmt < ' tcx > ] ,
67+ dummy_ret_stmt : Option < & ' ret hir:: Stmt < ' tcx > > ,
68+ ) -> impl Iterator < Item = & ' rslt hir:: Stmt < ' tcx > >
69+ where
70+ ' ret : ' rslt ,
71+ ' stmts : ' rslt ,
72+ {
73+ block_stmts. iter ( ) . chain ( dummy_ret_stmt)
74+ }
75+
6476 /// Searches for at least one statement that could slow down the release of a significant drop.
65- fn at_least_one_stmt_is_expensive ( stmts : & [ hir:: Stmt < ' _ > ] ) -> bool {
77+ fn at_least_one_stmt_is_expensive < ' stmt > ( stmts : impl Iterator < Item = & ' stmt hir:: Stmt < ' tcx > > ) -> bool
78+ where
79+ ' tcx : ' stmt ,
80+ {
6681 for stmt in stmts {
6782 match stmt. kind {
83+ hir:: StmtKind :: Expr ( expr) if let hir:: ExprKind :: Path ( _) = expr. kind => { }
6884 hir:: StmtKind :: Local ( local) if let Some ( expr) = local. init
6985 && let hir:: ExprKind :: Path ( _) = expr. kind => { } ,
7086 _ => return true
@@ -99,7 +115,7 @@ impl<'tcx> SignificantDropTightening<'tcx> {
99115 expr : & ' tcx hir:: Expr < ' _ > ,
100116 idx : usize ,
101117 sdap : & mut SigDropAuxParams ,
102- stmt : & ' tcx hir:: Stmt < ' _ > ,
118+ stmt : & hir:: Stmt < ' _ > ,
103119 cb : impl Fn ( & mut SigDropAuxParams ) ,
104120 ) {
105121 let mut sig_drop_finder = SigDropFinder :: new ( cx, & mut self . seen_types ) ;
@@ -117,7 +133,7 @@ impl<'tcx> SignificantDropTightening<'tcx> {
117133 }
118134 }
119135
120- /// Shows a generic overall message as well as specialized messages depending on the usage.
136+ /// Shows generic overall messages as well as specialized messages depending on the usage.
121137 fn set_suggestions ( cx : & LateContext < ' tcx > , block_span : Span , diag : & mut Diagnostic , sdap : & SigDropAuxParams ) {
122138 match sdap. number_of_stmts {
123139 0 | 1 => { } ,
@@ -172,8 +188,13 @@ impl<'tcx> SignificantDropTightening<'tcx> {
172188
173189impl < ' tcx > LateLintPass < ' tcx > for SignificantDropTightening < ' tcx > {
174190 fn check_block ( & mut self , cx : & LateContext < ' tcx > , block : & ' tcx hir:: Block < ' _ > ) {
191+ let dummy_ret_stmt = block. expr . map ( |expr| hir:: Stmt {
192+ hir_id : hir:: HirId :: INVALID ,
193+ kind : hir:: StmtKind :: Expr ( expr) ,
194+ span : DUMMY_SP ,
195+ } ) ;
175196 let mut sdap = SigDropAuxParams :: default ( ) ;
176- for ( idx, stmt) in block. stmts . iter ( ) . enumerate ( ) {
197+ for ( idx, stmt) in Self :: all_block_stmts ( block. stmts , dummy_ret_stmt . as_ref ( ) ) . enumerate ( ) {
177198 match stmt. kind {
178199 hir:: StmtKind :: Expr ( expr) => self . modify_sdap_if_sig_drop_exists (
179200 cx,
@@ -213,11 +234,9 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
213234 _ => { }
214235 } ;
215236 }
216- let stmts_after_last_use = sdap
217- . last_use_stmt_idx
218- . checked_add ( 1 )
219- . and_then ( |idx| block. stmts . get ( idx..) )
220- . unwrap_or_default ( ) ;
237+
238+ let idx = sdap. last_use_stmt_idx . wrapping_add ( 1 ) ;
239+ let stmts_after_last_use = Self :: all_block_stmts ( block. stmts , dummy_ret_stmt. as_ref ( ) ) . skip ( idx) ;
221240 if sdap. number_of_stmts > 1 && Self :: at_least_one_stmt_is_expensive ( stmts_after_last_use) {
222241 span_lint_and_then (
223242 cx,
0 commit comments