Skip to content

Commit 509f9d0

Browse files
filter out ecosystem types earlier
1 parent 1bfa639 commit 509f9d0

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

compiler/rustc_mir_transform/messages.ftl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ mir_transform_tail_expr_drop_order = relative drop order changing in Rust 2024
4040
*[false] `{$name}` will be dropped later since Edition 2024
4141
}
4242
43-
mir_transform_tail_expr_dtor = `{$name}` invokes this custom destructor
43+
mir_transform_tail_expr_dtor = {$dtor_kind ->
44+
[dyn] `{$name}` may invoke a custom destructor because contains a trait object
45+
*[concrete] `{$name}` invokes this custom destructor
46+
}
4447
4548
mir_transform_tail_expr_local = {$is_generated_name ->
4649
[true] this value will be stored in a temporary; let us call it `{$name}`

compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::hash_map;
33
use std::rc::Rc;
44

55
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6-
use rustc_data_structures::unord::UnordSet;
6+
use rustc_data_structures::unord::{UnordMap, UnordSet};
77
use rustc_errors::Subdiagnostic;
88
use rustc_hir::CRATE_HIR_ID;
99
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -20,7 +20,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
2020
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
2121
use rustc_mir_dataflow::{Analysis, MaybeReachable, ResultsCursor};
2222
use rustc_session::lint;
23-
use rustc_span::{Span, Symbol};
23+
use rustc_span::{DUMMY_SP, Span, Symbol};
2424
use rustc_type_ir::data_structures::IndexMap;
2525
use smallvec::{SmallVec, smallvec};
2626
use tracing::{debug, instrument};
@@ -170,7 +170,9 @@ fn true_significant_drop_ty<'tcx>(
170170
debug!(?name_str);
171171
match name_str[..] {
172172
// 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![]),
174176
// These are important types from Rust ecosystem
175177
["tracing", "instrument", "Instrumented"] | ["bytes", "Bytes"] => Some(smallvec![]),
176178
["hashbrown", "raw", "RawTable" | "RawIntoIter"] => {
@@ -328,9 +330,19 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
328330
// because they tend to be scheduled in the same drop ladder block.
329331
let mut bid_per_block = IndexMap::default();
330332
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();
331335
for (block, data) in body.basic_blocks.iter_enumerated() {
332336
for (statement_index, stmt) in data.statements.iter().enumerate() {
333337
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+
}
334346
bid_per_block
335347
.entry(block)
336348
.or_insert(vec![])
@@ -345,7 +357,6 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
345357

346358
dump_mir(tcx, false, "lint_tail_expr_drop_order", &0 as _, body, |_, _| Ok(()));
347359
let locals_with_user_names = collect_user_names(body);
348-
let param_env = tcx.param_env(def_id).with_reveal_all_normalized(tcx);
349360
let is_closure_like = tcx.is_closure_like(def_id.to_def_id());
350361
let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
351362
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<
402413
}
403414
let observer_ty = move_path.place.ty(body, tcx).ty;
404415
// 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+
{
406423
debug!(?dropped_local, "skip non-droppy types");
407424
to_exclude.insert(path_idx);
408425
continue;
@@ -450,12 +467,26 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
450467
}
451468

452469
// 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();
459490
local_labels.push(LocalLabel {
460491
span: linted_local_decl.source_info.span,
461492
destructors,
@@ -477,10 +508,23 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
477508
};
478509
let name = name.as_str();
479510

511+
let mut seen_dyn = false;
480512
let destructors = extract_component_with_significant_dtor(tcx, param_env, observer_ty)
481513
.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+
})
484528
.collect();
485529
local_labels.push(LocalLabel {
486530
span: observer_local_decl.source_info.span,
@@ -583,5 +627,6 @@ impl Subdiagnostic for LocalLabel<'_> {
583627
struct DestructorLabel<'a> {
584628
#[primary_span]
585629
span: Span,
630+
dtor_kind: &'static str,
586631
name: &'a str,
587632
}

0 commit comments

Comments
 (0)