add new attribute rustc_insignificant_dtor and a query to check if a type has a significant drop
This commit is contained in:
parent
1025db84a6
commit
a7e1cec621
11 changed files with 333 additions and 13 deletions
|
@ -1035,6 +1035,10 @@ rustc_queries! {
|
|||
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` needs drop", env.value }
|
||||
}
|
||||
/// Query backing `TyS::has_significant_drop_raw`.
|
||||
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "computing whether `{}` has a significant drop", env.value }
|
||||
}
|
||||
|
||||
/// Query backing `TyS::is_structural_eq_shallow`.
|
||||
///
|
||||
|
@ -1055,6 +1059,17 @@ rustc_queries! {
|
|||
cache_on_disk_if { true }
|
||||
}
|
||||
|
||||
/// A list of types where the ADT 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 ADT is known to have a significant destructor then
|
||||
/// `Err(AlwaysRequiresDrop)` is returned.
|
||||
query adt_significant_drop_tys(def_id: DefId) -> Result<&'tcx ty::List<Ty<'tcx>>, AlwaysRequiresDrop> {
|
||||
desc { |tcx| "computing when `{}` has a significant destructor", tcx.def_path_str(def_id) }
|
||||
cache_on_disk_if { false }
|
||||
}
|
||||
|
||||
query layout_raw(
|
||||
env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
|
||||
) -> Result<&'tcx rustc_target::abi::Layout, ty::layout::LayoutError<'tcx>> {
|
||||
|
|
|
@ -791,6 +791,39 @@ impl<'tcx> ty::TyS<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks if `ty` has has a significant drop.
|
||||
///
|
||||
/// Note that this method can return false even if `ty` has a destructor
|
||||
/// attached; even if that is the case then the adt has been marked with
|
||||
/// the attribute `rustc_insignificant_dtor`.
|
||||
///
|
||||
/// Note that this method is used to check for change in drop order for
|
||||
/// 2229 drop reorder migration analysis.
|
||||
#[inline]
|
||||
pub fn has_significant_drop(
|
||||
&'tcx self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> bool {
|
||||
// Avoid querying in simple cases.
|
||||
match needs_drop_components(self, &tcx.data_layout) {
|
||||
Err(AlwaysRequiresDrop) => true,
|
||||
Ok(components) => {
|
||||
let query_ty = match *components {
|
||||
[] => return false,
|
||||
// If we've got a single component, call the query with that
|
||||
// to increase the chance that we hit the query cache.
|
||||
[component_ty] => component_ty,
|
||||
_ => self,
|
||||
};
|
||||
// This doesn't depend on regions, so try to minimize distinct
|
||||
// query keys used.
|
||||
let erased = tcx.normalize_erasing_regions(param_env, query_ty);
|
||||
tcx.has_significant_drop_raw(param_env.and(erased))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if equality for this type is both reflexive and structural.
|
||||
///
|
||||
/// Reflexive equality for a type is indicated by an `Eq` impl for that type.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue