@@ -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, |_| true ) ;
351
362
let maybe_init = MaybeInitializedPlaces :: new ( tcx, body, & move_data) ;
@@ -401,7 +412,13 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
401
412
}
402
413
let observer_ty = move_path. place . ty ( body, tcx) . ty ;
403
414
// d) The collect local has no custom destructor.
404
- if !observer_ty. has_significant_drop ( tcx, param_env) {
415
+ if ty_dropped_components
416
+ . entry ( observer_ty)
417
+ . or_insert_with ( || {
418
+ extract_component_with_significant_dtor ( tcx, param_env, observer_ty)
419
+ } )
420
+ . is_empty ( )
421
+ {
405
422
debug ! ( ?dropped_local, "skip non-droppy types" ) ;
406
423
to_exclude. insert ( path_idx) ;
407
424
continue ;
@@ -449,12 +466,26 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
449
466
}
450
467
451
468
// Collect spans of the custom destructors.
452
- let destructors =
453
- extract_component_with_significant_dtor ( tcx, param_env, linted_local_decl. ty )
454
- . into_iter ( )
455
- . filter_map ( |ty| ty_dtor_span ( tcx, ty) )
456
- . map ( |span| DestructorLabel { span, name } )
457
- . collect ( ) ;
469
+ let mut seen_dyn = false ;
470
+ let destructors = ty_dropped_components
471
+ . get ( & linted_local_decl. ty )
472
+ . unwrap ( )
473
+ . iter ( )
474
+ . filter_map ( |& ty| {
475
+ if let Some ( span) = ty_dtor_span ( tcx, ty) {
476
+ Some ( DestructorLabel { span, name, dtor_kind : "concrete" } )
477
+ } else if matches ! ( ty. kind( ) , ty:: Dynamic ( ..) ) {
478
+ if seen_dyn {
479
+ None
480
+ } else {
481
+ seen_dyn = true ;
482
+ Some ( DestructorLabel { span : DUMMY_SP , name, dtor_kind : "dyn" } )
483
+ }
484
+ } else {
485
+ None
486
+ }
487
+ } )
488
+ . collect ( ) ;
458
489
local_labels. push ( LocalLabel {
459
490
span : linted_local_decl. source_info . span ,
460
491
destructors,
@@ -476,10 +507,23 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
476
507
} ;
477
508
let name = name. as_str ( ) ;
478
509
510
+ let mut seen_dyn = false ;
479
511
let destructors = extract_component_with_significant_dtor ( tcx, param_env, observer_ty)
480
512
. into_iter ( )
481
- . filter_map ( |ty| ty_dtor_span ( tcx, ty) )
482
- . map ( |span| DestructorLabel { span, name } )
513
+ . filter_map ( |ty| {
514
+ if let Some ( span) = ty_dtor_span ( tcx, ty) {
515
+ Some ( DestructorLabel { span, name, dtor_kind : "concrete" } )
516
+ } else if matches ! ( ty. kind( ) , ty:: Dynamic ( ..) ) {
517
+ if seen_dyn {
518
+ None
519
+ } else {
520
+ seen_dyn = true ;
521
+ Some ( DestructorLabel { span : DUMMY_SP , name, dtor_kind : "dyn" } )
522
+ }
523
+ } else {
524
+ None
525
+ }
526
+ } )
483
527
. collect ( ) ;
484
528
local_labels. push ( LocalLabel {
485
529
span : observer_local_decl. source_info . span ,
@@ -582,5 +626,6 @@ impl Subdiagnostic for LocalLabel<'_> {
582
626
struct DestructorLabel < ' a > {
583
627
#[ primary_span]
584
628
span : Span ,
629
+ dtor_kind : & ' static str ,
585
630
name : & ' a str ,
586
631
}
0 commit comments