Skip to content

Commit 34e1f96

Browse files
filter out ecosystem types earlier
1 parent a5f7a34 commit 34e1f96

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, |_| true);
351362
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<
401412
}
402413
let observer_ty = move_path.place.ty(body, tcx).ty;
403414
// 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+
{
405422
debug!(?dropped_local, "skip non-droppy types");
406423
to_exclude.insert(path_idx);
407424
continue;
@@ -449,12 +466,26 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
449466
}
450467

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

510+
let mut seen_dyn = false;
479511
let destructors = extract_component_with_significant_dtor(tcx, param_env, observer_ty)
480512
.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+
})
483527
.collect();
484528
local_labels.push(LocalLabel {
485529
span: observer_local_decl.source_info.span,
@@ -582,5 +626,6 @@ impl Subdiagnostic for LocalLabel<'_> {
582626
struct DestructorLabel<'a> {
583627
#[primary_span]
584628
span: Span,
629+
dtor_kind: &'static str,
585630
name: &'a str,
586631
}

0 commit comments

Comments
 (0)