Rework rustc_dump_vtable
This commit is contained in:
parent
5a45ab9738
commit
08d7e9dfe5
23 changed files with 603 additions and 381 deletions
|
@ -1,7 +1,8 @@
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::sym;
|
||||
|
||||
pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
|
||||
|
@ -87,3 +88,82 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||
for id in tcx.hir().items() {
|
||||
let def_id = id.owner_id.def_id;
|
||||
|
||||
let Some(attr) = tcx.get_attr(def_id, sym::rustc_dump_vtable) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let vtable_entries = match tcx.hir().item(id).kind {
|
||||
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
|
||||
let trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate_identity();
|
||||
if trait_ref.has_non_region_param() {
|
||||
tcx.dcx().span_err(
|
||||
attr.span,
|
||||
"`rustc_dump_vtable` must be applied to non-generic impl",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if !tcx.is_dyn_compatible(trait_ref.def_id) {
|
||||
tcx.dcx().span_err(
|
||||
attr.span,
|
||||
"`rustc_dump_vtable` must be applied to dyn-compatible trait",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
let Ok(trait_ref) = tcx
|
||||
.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref)
|
||||
else {
|
||||
tcx.dcx().span_err(
|
||||
attr.span,
|
||||
"`rustc_dump_vtable` applied to impl header that cannot be normalized",
|
||||
);
|
||||
continue;
|
||||
};
|
||||
tcx.vtable_entries(ty::Binder::dummy(trait_ref))
|
||||
}
|
||||
hir::ItemKind::TyAlias(_, _) => {
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
if ty.has_non_region_param() {
|
||||
tcx.dcx().span_err(
|
||||
attr.span,
|
||||
"`rustc_dump_vtable` must be applied to non-generic type",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
let Ok(ty) =
|
||||
tcx.try_normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty)
|
||||
else {
|
||||
tcx.dcx().span_err(
|
||||
attr.span,
|
||||
"`rustc_dump_vtable` applied to type alias that cannot be normalized",
|
||||
);
|
||||
continue;
|
||||
};
|
||||
let ty::Dynamic(data, _, _) = *ty.kind() else {
|
||||
tcx.dcx().span_err(attr.span, "`rustc_dump_vtable` to type alias of dyn type");
|
||||
continue;
|
||||
};
|
||||
if let Some(principal) = data.principal() {
|
||||
tcx.vtable_entries(
|
||||
principal.map_bound(|principal| principal.with_self_ty(tcx, ty)),
|
||||
)
|
||||
} else {
|
||||
TyCtxt::COMMON_VTABLE_ENTRIES
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
tcx.dcx().span_err(
|
||||
attr.span,
|
||||
"`rustc_dump_vtable` only applies to impl, or type alias of dyn type",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
tcx.dcx().span_err(tcx.def_span(def_id), format!("vtable entries: {vtable_entries:#?}"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,11 +152,14 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
|||
});
|
||||
|
||||
if tcx.features().rustc_attrs() {
|
||||
tcx.sess.time("outlives_dumping", || outlives::dump::inferred_outlives(tcx));
|
||||
tcx.sess.time("variance_dumping", || variance::dump::variances(tcx));
|
||||
collect::dump::opaque_hidden_types(tcx);
|
||||
collect::dump::predicates_and_item_bounds(tcx);
|
||||
collect::dump::def_parents(tcx);
|
||||
tcx.sess.time("dumping_rustc_attr_data", || {
|
||||
outlives::dump::inferred_outlives(tcx);
|
||||
variance::dump::variances(tcx);
|
||||
collect::dump::opaque_hidden_types(tcx);
|
||||
collect::dump::predicates_and_item_bounds(tcx);
|
||||
collect::dump::def_parents(tcx);
|
||||
collect::dump::vtables(tcx);
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure we evaluate all static and (non-associated) const items, even if unused.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue