1//! Walks the crate looking for items/impl-items/trait-items that have
2//! either a `rustc_dump_symbol_name` or `rustc_dump_def_path` attribute and
3//! generates an error giving, respectively, the symbol name or
4//! def-path. This is used for unit testing the code that generates
5//! paths etc in all kinds of annoying scenarios.
67use rustc_attr_ir::find_attr;
8use rustc_hir::CRATE_OWNER_ID;
9use rustc_middle::ty::print::with_no_trimmed_paths;
10use rustc_middle::ty::{GenericArgs, Instance, TyCtxt};
1112pub fn dump_symbol_names_and_def_paths(tcx: TyCtxt<'_>) {
13// if the `rustc_attrs` feature is not enabled, then the
14 // attributes we are interested in cannot be present anyway, so
15 // skip the walk.
16if !tcx.features().rustc_attrs() {
17return;
18 }
1920tcx.dep_graph.with_ignore(|| {
21for id in tcx.hir_crate_items(()).owners() {
22if id == CRATE_OWNER_ID {
23continue;
24 }
2526// The format `$tag($value)` is chosen so that tests can elect to test the
27 // entirety of the string, if they choose, or else just some subset.
2829if let Some(&span) = {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(id.def_id, &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcDumpSymbolName(span))
=> {
break 'done Some(span);
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(tcx, id.def_id, RustcDumpSymbolName(span) => span) {
30let def_id = id.def_id.to_def_id();
31let args = GenericArgs::identity_for_item(tcx, id.def_id);
32let args = tcx.erase_and_anonymize_regions(args);
33let instance = Instance::new_raw(def_id, args);
34let mangled = tcx.symbol_name(instance);
35let def_span = tcx.def_span(def_id);
36let span = span.to(def_span);
3738let mut err = tcx.dcx().struct_span_err(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("symbol-name({0})", mangled))
})format!("symbol-name({mangled})"));
3940if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) {
41 err.note(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("demangling({0})", demangling))
})format!("demangling({demangling})"));
42 err.note(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("demangling-alt({0:#})",
demangling))
})format!("demangling-alt({demangling:#})"));
43 }
44 err.emit_err();
45 }
4647if let Some(&span) = {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(id.def_id, &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcDumpDefPath(span))
=> {
break 'done Some(span);
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}find_attr!(tcx, id.def_id, RustcDumpDefPath(span) => span) {
48let def_path = { let _guard = NoTrimmedGuard::new(); tcx.def_path_str(id.def_id) }with_no_trimmed_paths!(tcx.def_path_str(id.def_id));
49 tcx.dcx().span_err(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("def-path({0})", def_path))
})format!("def-path({def_path})"));
50 }
51 }
52 })
53}