diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/dump.rs | 82 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/lib.rs | 13 |
2 files changed, 89 insertions, 6 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index f1022d95753..4a508fc0cf6 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -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(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( + tcx.instantiate_bound_regions_with_erased(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:#?}")); + } +} diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index bc7d4365eee..03dd0cccf75 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -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. |
