Skip to main content

rustc_symbol_mangling/
test.rs

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.
6
7use 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};
11
12pub 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.
16    if !tcx.features().rustc_attrs() {
17        return;
18    }
19
20    tcx.dep_graph.with_ignore(|| {
21        for id in tcx.hir_crate_items(()).owners() {
22            if id == CRATE_OWNER_ID {
23                continue;
24            }
25
26            // 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.
28
29            if 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) {
30                let def_id = id.def_id.to_def_id();
31                let args = GenericArgs::identity_for_item(tcx, id.def_id);
32                let args = tcx.erase_and_anonymize_regions(args);
33                let instance = Instance::new_raw(def_id, args);
34                let mangled = tcx.symbol_name(instance);
35                let def_span = tcx.def_span(def_id);
36                let span = span.to(def_span);
37
38                let 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})"));
39
40                if 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            }
46
47            if 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) {
48                let 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}