@@ -3,7 +3,7 @@ use std::collections::hash_map;
3
3
use std:: rc:: Rc ;
4
4
5
5
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
6
- use rustc_data_structures:: unord:: UnordSet ;
6
+ use rustc_data_structures:: unord:: { UnordMap , UnordSet } ;
7
7
use rustc_errors:: Subdiagnostic ;
8
8
use rustc_hir:: CRATE_HIR_ID ;
9
9
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
@@ -20,7 +20,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
20
20
use rustc_mir_dataflow:: move_paths:: { LookupResult , MoveData , MovePathIndex } ;
21
21
use rustc_mir_dataflow:: { Analysis , MaybeReachable , ResultsCursor } ;
22
22
use rustc_session:: lint;
23
- use rustc_span:: { Span , Symbol } ;
23
+ use rustc_span:: { DUMMY_SP , Span , Symbol } ;
24
24
use rustc_type_ir:: data_structures:: IndexMap ;
25
25
use smallvec:: { SmallVec , smallvec} ;
26
26
use tracing:: { debug, instrument} ;
@@ -170,7 +170,9 @@ fn true_significant_drop_ty<'tcx>(
170
170
debug ! ( ?name_str) ;
171
171
match name_str[ ..] {
172
172
// These are the types from Rust core ecosystem
173
- [ "sym" | "proc_macro2" , ..] | [ "core" | "std" , "task" , "RawWaker" ] => Some ( smallvec ! [ ] ) ,
173
+ [ "sym" | "proc_macro2" , ..]
174
+ | [ "core" | "std" , "task" , "LocalWaker" | "Waker" ]
175
+ | [ "core" | "std" , "task" , "wake" , "LocalWaker" | "Waker" ] => Some ( smallvec ! [ ] ) ,
174
176
// These are important types from Rust ecosystem
175
177
[ "tracing" , "instrument" , "Instrumented" ] | [ "bytes" , "Bytes" ] => Some ( smallvec ! [ ] ) ,
176
178
[ "hashbrown" , "raw" , "RawTable" | "RawIntoIter" ] => {
@@ -328,9 +330,19 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
328
330
// because they tend to be scheduled in the same drop ladder block.
329
331
let mut bid_per_block = IndexMap :: default ( ) ;
330
332
let mut bid_places = UnordSet :: new ( ) ;
333
+ let param_env = tcx. param_env ( def_id) . with_reveal_all_normalized ( tcx) ;
334
+ let mut ty_dropped_components = UnordMap :: default ( ) ;
331
335
for ( block, data) in body. basic_blocks . iter_enumerated ( ) {
332
336
for ( statement_index, stmt) in data. statements . iter ( ) . enumerate ( ) {
333
337
if let StatementKind :: BackwardIncompatibleDropHint { place, reason : _ } = & stmt. kind {
338
+ let ty = place. ty ( body, tcx) . ty ;
339
+ if ty_dropped_components
340
+ . entry ( ty)
341
+ . or_insert_with ( || extract_component_with_significant_dtor ( tcx, param_env, ty) )
342
+ . is_empty ( )
343
+ {
344
+ continue ;
345
+ }
334
346
bid_per_block
335
347
. entry ( block)
336
348
. or_insert ( vec ! [ ] )
@@ -345,7 +357,6 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
345
357
346
358
dump_mir ( tcx, false , "lint_tail_expr_drop_order" , & 0 as _ , body, |_, _| Ok ( ( ) ) ) ;
347
359
let locals_with_user_names = collect_user_names ( body) ;
348
- let param_env = tcx. param_env ( def_id) . with_reveal_all_normalized ( tcx) ;
349
360
let is_closure_like = tcx. is_closure_like ( def_id. to_def_id ( ) ) ;
350
361
let move_data = MoveData :: gather_moves ( body, tcx, param_env, |_| true ) ;
351
362
let maybe_init = MaybeInitializedPlaces :: new ( tcx, body, & move_data) ;
@@ -402,7 +413,13 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
402
413
}
403
414
let observer_ty = move_path. place . ty ( body, tcx) . ty ;
404
415
// d) The collect local has no custom destructor.
405
- if !observer_ty. has_significant_drop ( tcx, param_env) {
416
+ if ty_dropped_components
417
+ . entry ( observer_ty)
418
+ . or_insert_with ( || {
419
+ extract_component_with_significant_dtor ( tcx, param_env, observer_ty)
420
+ } )
421
+ . is_empty ( )
422
+ {
406
423
debug ! ( ?dropped_local, "skip non-droppy types" ) ;
407
424
to_exclude. insert ( path_idx) ;
408
425
continue ;
@@ -450,12 +467,26 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
450
467
}
451
468
452
469
// Collect spans of the custom destructors.
453
- let destructors =
454
- extract_component_with_significant_dtor ( tcx, param_env, linted_local_decl. ty )
455
- . into_iter ( )
456
- . filter_map ( |ty| ty_dtor_span ( tcx, ty) )
457
- . map ( |span| DestructorLabel { span, name } )
458
- . collect ( ) ;
470
+ let mut seen_dyn = false ;
471
+ let destructors = ty_dropped_components
472
+ . get ( & linted_local_decl. ty )
473
+ . unwrap ( )
474
+ . iter ( )
475
+ . filter_map ( |& ty| {
476
+ if let Some ( span) = ty_dtor_span ( tcx, ty) {
477
+ Some ( DestructorLabel { span, name, dtor_kind : "concrete" } )
478
+ } else if matches ! ( ty. kind( ) , ty:: Dynamic ( ..) ) {
479
+ if seen_dyn {
480
+ None
481
+ } else {
482
+ seen_dyn = true ;
483
+ Some ( DestructorLabel { span : DUMMY_SP , name, dtor_kind : "dyn" } )
484
+ }
485
+ } else {
486
+ None
487
+ }
488
+ } )
489
+ . collect ( ) ;
459
490
local_labels. push ( LocalLabel {
460
491
span : linted_local_decl. source_info . span ,
461
492
destructors,
@@ -477,10 +508,23 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
477
508
} ;
478
509
let name = name. as_str ( ) ;
479
510
511
+ let mut seen_dyn = false ;
480
512
let destructors = extract_component_with_significant_dtor ( tcx, param_env, observer_ty)
481
513
. into_iter ( )
482
- . filter_map ( |ty| ty_dtor_span ( tcx, ty) )
483
- . map ( |span| DestructorLabel { span, name } )
514
+ . filter_map ( |ty| {
515
+ if let Some ( span) = ty_dtor_span ( tcx, ty) {
516
+ Some ( DestructorLabel { span, name, dtor_kind : "concrete" } )
517
+ } else if matches ! ( ty. kind( ) , ty:: Dynamic ( ..) ) {
518
+ if seen_dyn {
519
+ None
520
+ } else {
521
+ seen_dyn = true ;
522
+ Some ( DestructorLabel { span : DUMMY_SP , name, dtor_kind : "dyn" } )
523
+ }
524
+ } else {
525
+ None
526
+ }
527
+ } )
484
528
. collect ( ) ;
485
529
local_labels. push ( LocalLabel {
486
530
span : observer_local_decl. source_info . span ,
@@ -583,5 +627,6 @@ impl Subdiagnostic for LocalLabel<'_> {
583
627
struct DestructorLabel < ' a > {
584
628
#[ primary_span]
585
629
span : Span ,
630
+ dtor_kind : & ' static str ,
586
631
name : & ' a str ,
587
632
}
0 commit comments