Skip to content

Commit

Permalink
try to peak into adts for significant droppers
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Oct 7, 2024
1 parent 8f09388 commit 80c5c8f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 15 deletions.
11 changes: 11 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,17 @@ rustc_queries! {
cache_on_disk_if { false }
}

/// A list of types where a type requires drop if and only if any of those types
/// has significant drop. A type marked with the attribute `rustc_insignificant_dtor`
/// is considered to not be significant. A drop is significant if it is implemented
/// by the user or does anything that will have any observable behavior (other than
/// freeing up memory). If the type is known to have a significant destructor then
/// `Err(AlwaysRequiresDrop)` is returned.
query list_significant_drop_tys(ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
desc { |tcx| "computing when `{}` has a significant destructor", ty.value }
cache_on_disk_if { false }
}

/// Computes the layout of a type. Note that this implicitly
/// executes in "reveal all" mode, and will normalize the input type.
query layout_of(
Expand Down
22 changes: 8 additions & 14 deletions compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use itertools::Itertools;
use rustc_data_structures::unord::UnordSet;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::BitSet;
use rustc_macros::LintDiagnostic;
use rustc_middle::mir::{
Expand All @@ -13,7 +13,7 @@ use rustc_mir_dataflow::move_paths::{MoveData, MovePathIndex};
use rustc_mir_dataflow::{Analysis, MaybeReachable};
use rustc_session::lint;
use rustc_span::Span;
use tracing::debug;
use tracing::{debug, instrument};

fn place_has_common_prefix<'tcx>(left: &Place<'tcx>, right: &Place<'tcx>) -> bool {
left.local == right.local
Expand Down Expand Up @@ -68,9 +68,10 @@ fn print_ty_without_trimming(ty: Ty<'_>) -> String {
ty::print::with_no_trimmed_paths!(format!("{}", ty))
}

#[instrument(level = "debug", skip(tcx, param_env))]
fn extract_component_with_significant_dtor<'tcx>(
tcx: TyCtxt<'tcx>,
_body_did: DefId,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> (String, Vec<Span>) {
let ty_def_span = |ty: Ty<'_>| match ty.kind() {
Expand Down Expand Up @@ -104,10 +105,7 @@ fn extract_component_with_significant_dtor<'tcx>(
// I honestly don't know how to extract the span reliably from a param arbitrarily nested
ty::Param(_) => None,
};
let Some(adt_def) = ty.ty_adt_def() else {
return (print_ty_without_trimming(ty), vec![]);
};
let Ok(tys) = tcx.adt_significant_drop_tys(adt_def.did()) else {
let Ok(tys) = tcx.list_significant_drop_tys(param_env.and(ty)) else {
return (print_ty_without_trimming(ty), vec![]);
};
let ty_names = tys.iter().map(print_ty_without_trimming).join(", ");
Expand Down Expand Up @@ -164,7 +162,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
}

dump_mir(tcx, false, "lint_tail_expr_drop_order", &0 as _, body, |_, _| Ok(()));
let param_env = tcx.param_env(def_id);
let param_env = tcx.param_env(def_id).with_reveal_all_normalized(tcx);
let is_closure_like = tcx.is_closure_like(def_id.to_def_id());
let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
let maybe_init = MaybeInitializedPlaces::new(tcx, body, &move_data);
Expand Down Expand Up @@ -216,15 +214,11 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
let observer_local_decl = &body.local_decls[move_path.place.local];
let (ty_drop_components, ty_spans) = extract_component_with_significant_dtor(
tcx,
def_id.to_def_id(),
param_env,
linted_local_decl.ty,
);
let (observer_ty_drop_components, observer_ty_spans) =
extract_component_with_significant_dtor(
tcx,
def_id.to_def_id(),
observer_ty,
);
extract_component_with_significant_dtor(tcx, param_env, observer_ty);
debug!(?candidate, ?place, ?move_path.place);
tcx.emit_node_span_lint(
lint::builtin::TAIL_EXPR_DROP_ORDER,
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_ty_utils/src/needs_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::ty::util::{AlwaysRequiresDrop, needs_drop_components};
use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt};
use rustc_session::Limit;
use rustc_span::sym;
use tracing::debug;
use tracing::{debug, instrument};

use crate::errors::NeedsDropOverflow;

Expand Down Expand Up @@ -400,13 +400,30 @@ fn adt_significant_drop_tys(
.map(|components| tcx.mk_type_list(&components))
}

#[instrument(level = "debug", skip(tcx))]
fn list_significant_drop_tys<'tcx>(
tcx: TyCtxt<'tcx>,
ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
drop_tys_helper(
tcx,
ty.value, // identical to `tcx.make_adt(def, identity_args)`
ty.param_env,
adt_consider_insignificant_dtor(tcx),
true,
)
.collect::<Result<Vec<_>, _>>()
.map(|components| tcx.mk_type_list(&components))
}

pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
needs_drop_raw,
needs_async_drop_raw,
has_significant_drop_raw,
adt_drop_tys,
adt_significant_drop_tys,
list_significant_drop_tys,
..*providers
};
}

0 comments on commit 80c5c8f

Please sign in to comment.