| //! Walks the crate looking for items/impl-items/trait-items that have |
| //! either a `rustc_dump_symbol_name` or `rustc_dump_def_path` attribute and |
| //! generates an error giving, respectively, the symbol name or |
| //! def-path. This is used for unit testing the code that generates |
| //! paths etc in all kinds of annoying scenarios. |
| |
| use rustc_hir::{CRATE_OWNER_ID, find_attr}; |
| use rustc_middle::ty::print::with_no_trimmed_paths; |
| use rustc_middle::ty::{GenericArgs, Instance, TyCtxt}; |
| |
| pub fn dump_symbol_names_and_def_paths(tcx: TyCtxt<'_>) { |
| // if the `rustc_attrs` feature is not enabled, then the |
| // attributes we are interested in cannot be present anyway, so |
| // skip the walk. |
| if !tcx.features().rustc_attrs() { |
| return; |
| } |
| |
| tcx.dep_graph.with_ignore(|| { |
| for id in tcx.hir_crate_items(()).owners() { |
| if id == CRATE_OWNER_ID { |
| continue; |
| } |
| |
| // The format `$tag($value)` is chosen so that tests can elect to test the |
| // entirety of the string, if they choose, or else just some subset. |
| |
| if let Some(&span) = find_attr!(tcx, id.def_id, RustcDumpSymbolName(span) => span) { |
| let def_id = id.def_id.to_def_id(); |
| let args = GenericArgs::identity_for_item(tcx, id.def_id); |
| let args = tcx.erase_and_anonymize_regions(args); |
| let instance = Instance::new_raw(def_id, args); |
| let mangled = tcx.symbol_name(instance); |
| |
| tcx.dcx().span_err(span, format!("symbol-name({mangled})")); |
| |
| if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) { |
| tcx.dcx().span_err(span, format!("demangling({demangling})")); |
| tcx.dcx().span_err(span, format!("demangling-alt({demangling:#})")); |
| } |
| } |
| |
| if let Some(&span) = find_attr!(tcx, id.def_id, RustcDumpDefPath(span) => span) { |
| let def_path = with_no_trimmed_paths!(tcx.def_path_str(id.def_id)); |
| tcx.dcx().span_err(span, format!("def-path({def_path})")); |
| } |
| } |
| }) |
| } |