@@ -369,17 +369,22 @@ struct FindSignificantDropper<'a, 'tcx> {
369
369
}
370
370
371
371
impl < ' tcx > FindSignificantDropper < ' _ , ' tcx > {
372
+ /// Check the scrutinee of an `if let` to see if it promotes any temporary values
373
+ /// that would change drop order in edition 2024. Specifically, it checks the value
374
+ /// of the scrutinee itself, and also recurses into the expression to find any ref
375
+ /// exprs (or autoref) which would promote temporaries that would be scoped to the
376
+ /// end of this `if`.
372
377
fn check_if_let_scrutinee ( & mut self , init : & ' tcx hir:: Expr < ' tcx > ) -> ControlFlow < Span > {
373
378
self . check_promoted_temp_with_drop ( init) ?;
374
379
self . visit_expr ( init)
375
380
}
376
381
377
- // Check that an expression is not a promoted temporary with a significant
378
- // drop impl.
379
- //
380
- // An expression is a promoted temporary if it has an addr taken (i.e. `&expr`)
381
- // or is the scrutinee of the `if let`, *and* the expression is not a place
382
- // expr, and it has a significant drop.
382
+ /// Check that an expression is not a promoted temporary with a significant
383
+ /// drop impl.
384
+ ///
385
+ /// An expression is a promoted temporary if it has an addr taken (i.e. `&expr` or autoref )
386
+ /// or is the scrutinee of the `if let`, *and* the expression is not a place
387
+ /// expr, and it has a significant drop.
383
388
fn check_promoted_temp_with_drop ( & self , expr : & ' tcx hir:: Expr < ' tcx > ) -> ControlFlow < Span > {
384
389
if !expr. is_place_expr ( |base| {
385
390
self . cx
@@ -405,7 +410,8 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> {
405
410
406
411
fn visit_block ( & mut self , b : & ' tcx hir:: Block < ' tcx > ) -> Self :: Result {
407
412
// Blocks introduce temporary terminating scope for all of its
408
- // statements, so just visit the tail expr.
413
+ // statements, so just visit the tail expr, skipping over any
414
+ // statements. This prevents false positives like `{ let x = &Drop; }`.
409
415
if let Some ( expr) = b. expr { self . visit_expr ( expr) } else { ControlFlow :: Continue ( ( ) ) }
410
416
}
411
417
@@ -415,6 +421,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> {
415
421
// where `fn as_ref(&self) -> Option<...>`.
416
422
for adj in self . cx . typeck_results ( ) . expr_adjustments ( expr) {
417
423
match adj. kind {
424
+ // Skip when we hit the first deref expr.
418
425
Adjust :: Deref ( _) => break ,
419
426
Adjust :: Borrow ( _) => {
420
427
self . check_promoted_temp_with_drop ( expr) ?;
@@ -424,7 +431,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> {
424
431
}
425
432
426
433
match expr. kind {
427
- // Check for cases like `if let None = Some(&Drop) {} else {}`.
434
+ // Account for cases like `if let None = Some(&Drop) {} else {}`.
428
435
hir:: ExprKind :: AddrOf ( _, _, expr) => {
429
436
self . check_promoted_temp_with_drop ( expr) ?;
430
437
intravisit:: walk_expr ( self , expr)
@@ -438,6 +445,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> {
438
445
hir:: ExprKind :: Match ( scrut, _, _) => self . visit_expr ( scrut) ,
439
446
// Self explanatory.
440
447
hir:: ExprKind :: DropTemps ( _) => ControlFlow :: Continue ( ( ) ) ,
448
+ // Otherwise, walk into the expr's parts.
441
449
_ => intravisit:: walk_expr ( self , expr) ,
442
450
}
443
451
}
0 commit comments