@@ -4,7 +4,7 @@ use clippy_utils::get_attr;
44use clippy_utils:: source:: { indent_of, snippet} ;
55use rustc_errors:: { Applicability , Diagnostic } ;
66use rustc_hir:: intravisit:: { walk_expr, Visitor } ;
7- use rustc_hir:: { Expr , ExprKind } ;
7+ use rustc_hir:: { Expr , ExprKind , MatchSource } ;
88use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
99use rustc_middle:: ty:: subst:: GenericArgKind ;
1010use rustc_middle:: ty:: { Ty , TypeAndMut } ;
@@ -154,9 +154,17 @@ fn has_significant_drop_in_scrutinee<'tcx, 'a>(
154154 cx : & ' a LateContext < ' tcx > ,
155155 expr : & ' tcx Expr < ' tcx > ,
156156) -> Option < Vec < FoundSigDrop > > {
157- let mut helper = SigDropHelper :: new ( cx) ;
158157 match expr. kind {
159- ExprKind :: Match ( match_expr, _, _) => helper. find_sig_drop ( match_expr) ,
158+ ExprKind :: Match ( match_expr, _, source) => {
159+ match source {
160+ MatchSource :: Normal | MatchSource :: ForLoopDesugar => {
161+ let mut helper = SigDropHelper :: new ( cx) ;
162+ helper. find_sig_drop ( match_expr)
163+ } ,
164+ // MatchSource of TryDesugar or AwaitDesugar is out of scope for this lint
165+ MatchSource :: TryDesugar | MatchSource :: AwaitDesugar => None ,
166+ }
167+ } ,
160168 _ => None ,
161169 }
162170}
@@ -213,6 +221,19 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
213221 self . sig_drop_spans . take ( )
214222 }
215223
224+ fn replace_current_sig_drop (
225+ & mut self ,
226+ found_span : Span ,
227+ is_unit_return_val : bool ,
228+ lint_suggestion : LintSuggestion ,
229+ ) {
230+ self . current_sig_drop . replace ( FoundSigDrop {
231+ found_span,
232+ is_unit_return_val,
233+ lint_suggestion,
234+ } ) ;
235+ }
236+
216237 /// This will try to set the current suggestion (so it can be moved into the suggestions vec
217238 /// later). If `allow_move_and_clone` is false, the suggestion *won't* be set -- this gives us
218239 /// an opportunity to look for another type in the chain that will be trivially copyable.
@@ -229,25 +250,15 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
229250 // but let's avoid any chance of an ICE
230251 if let Some ( TypeAndMut { ty, .. } ) = ty. builtin_deref ( true ) {
231252 if ty. is_trivially_pure_clone_copy ( ) {
232- self . current_sig_drop . replace ( FoundSigDrop {
233- found_span : expr. span ,
234- is_unit_return_val : false ,
235- lint_suggestion : LintSuggestion :: MoveAndDerefToCopy ,
236- } ) ;
253+ self . replace_current_sig_drop ( expr. span , false , LintSuggestion :: MoveAndDerefToCopy ) ;
237254 } else if allow_move_and_clone {
238- self . current_sig_drop . replace ( FoundSigDrop {
239- found_span : expr. span ,
240- is_unit_return_val : false ,
241- lint_suggestion : LintSuggestion :: MoveAndClone ,
242- } ) ;
255+ self . replace_current_sig_drop ( expr. span , false , LintSuggestion :: MoveAndClone ) ;
243256 }
244257 }
245258 } else if ty. is_trivially_pure_clone_copy ( ) {
246- self . current_sig_drop . replace ( FoundSigDrop {
247- found_span : expr. span ,
248- is_unit_return_val : false ,
249- lint_suggestion : LintSuggestion :: MoveOnly ,
250- } ) ;
259+ self . replace_current_sig_drop ( expr. span , false , LintSuggestion :: MoveOnly ) ;
260+ } else if allow_move_and_clone {
261+ self . replace_current_sig_drop ( expr. span , false , LintSuggestion :: MoveAndClone ) ;
251262 }
252263 }
253264
@@ -279,11 +290,7 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
279290 // If either side had a significant drop, suggest moving the entire scrutinee to avoid
280291 // unnecessary copies and to simplify cases where both sides have significant drops.
281292 if self . has_significant_drop {
282- self . current_sig_drop . replace ( FoundSigDrop {
283- found_span : span,
284- is_unit_return_val,
285- lint_suggestion : LintSuggestion :: MoveOnly ,
286- } ) ;
293+ self . replace_current_sig_drop ( span, is_unit_return_val, LintSuggestion :: MoveOnly ) ;
287294 }
288295
289296 self . special_handling_for_binary_op = false ;
@@ -363,34 +370,34 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
363370 }
364371 }
365372 ExprKind :: Box ( ..) |
366- ExprKind :: Array ( ..) |
367- ExprKind :: Call ( ..) |
368- ExprKind :: Unary ( ..) |
369- ExprKind :: If ( ..) |
370- ExprKind :: Match ( ..) |
371- ExprKind :: Field ( ..) |
372- ExprKind :: Index ( ..) |
373- ExprKind :: Ret ( ..) |
374- ExprKind :: Repeat ( ..) |
375- ExprKind :: Yield ( ..) |
376- ExprKind :: MethodCall ( ..) => walk_expr ( self , ex) ,
373+ ExprKind :: Array ( ..) |
374+ ExprKind :: Call ( ..) |
375+ ExprKind :: Unary ( ..) |
376+ ExprKind :: If ( ..) |
377+ ExprKind :: Match ( ..) |
378+ ExprKind :: Field ( ..) |
379+ ExprKind :: Index ( ..) |
380+ ExprKind :: Ret ( ..) |
381+ ExprKind :: Repeat ( ..) |
382+ ExprKind :: Yield ( ..) |
383+ ExprKind :: MethodCall ( ..) => walk_expr ( self , ex) ,
377384 ExprKind :: AddrOf ( _, _, _) |
378- ExprKind :: Block ( _, _) |
379- ExprKind :: Break ( _, _) |
380- ExprKind :: Cast ( _, _) |
381- // Don't want to check the closure itself, only invocation, which is covered by MethodCall
382- ExprKind :: Closure ( _, _, _, _, _) |
383- ExprKind :: ConstBlock ( _) |
384- ExprKind :: Continue ( _) |
385- ExprKind :: DropTemps ( _) |
386- ExprKind :: Err |
387- ExprKind :: InlineAsm ( _) |
388- ExprKind :: Let ( _) |
389- ExprKind :: Lit ( _) |
390- ExprKind :: Loop ( _, _, _, _) |
391- ExprKind :: Path ( _) |
392- ExprKind :: Struct ( _, _, _) |
393- ExprKind :: Type ( _, _) => {
385+ ExprKind :: Block ( _, _) |
386+ ExprKind :: Break ( _, _) |
387+ ExprKind :: Cast ( _, _) |
388+ // Don't want to check the closure itself, only invocation, which is covered by MethodCall
389+ ExprKind :: Closure ( _, _, _, _, _) |
390+ ExprKind :: ConstBlock ( _) |
391+ ExprKind :: Continue ( _) |
392+ ExprKind :: DropTemps ( _) |
393+ ExprKind :: Err |
394+ ExprKind :: InlineAsm ( _) |
395+ ExprKind :: Let ( _) |
396+ ExprKind :: Lit ( _) |
397+ ExprKind :: Loop ( _, _, _, _) |
398+ ExprKind :: Path ( _) |
399+ ExprKind :: Struct ( _, _, _) |
400+ ExprKind :: Type ( _, _) => {
394401 return ;
395402 }
396403 }
0 commit comments