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_hir::{CRATE_OWNER_ID, find_attr};
8use rustc_middle::ty::print::with_no_trimmed_paths;
9use rustc_middle::ty::{GenericArgs, Instance, TyCtxt};
10
11pub fn dump_symbol_names_and_def_paths(tcx: TyCtxt<'_>) {
12    // if the `rustc_attrs` feature is not enabled, then the
13    // attributes we are interested in cannot be present anyway, so
14    // skip the walk.
15    if !tcx.features().rustc_attrs() {
16        return;
17    }
18
19    tcx.dep_graph.with_ignore(|| {
20        for id in tcx.hir_crate_items(()).owners() {
21            if id == CRATE_OWNER_ID {
22                continue;
23            }
24
25            // The format `$tag($value)` is chosen so that tests can elect to test the
26            // entirety of the string, if they choose, or else just some subset.
27
28            if let Some(&span) = {
    {
        'done:
            {
            for i in ::rustc_hir::attrs::HasAttrs::get_attrs(id.def_id, &tcx)
                {
                #[allow(unused_imports)]
                use rustc_hir::attrs::AttributeKind::*;
                let i: &rustc_hir::Attribute = i;
                match i {
                    rustc_hir::Attribute::Parsed(RustcDumpSymbolName(span)) => {
                        break 'done Some(span);
                    }
                    rustc_hir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }
}find_attr!(tcx, id.def_id, RustcDumpSymbolName(span) => span) {
29                let def_id = id.def_id.to_def_id();
30                let args = GenericArgs::identity_for_item(tcx, id.def_id);
31                let args = tcx.erase_and_anonymize_regions(args);
32                let instance = Instance::new_raw(def_id, args);
33                let mangled = tcx.symbol_name(instance);
34
35                tcx.dcx().span_err(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("symbol-name({0})", mangled))
    })format!("symbol-name({mangled})"));
36
37                if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) {
38                    tcx.dcx().span_err(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("demangling({0})", demangling))
    })format!("demangling({demangling})"));
39                    tcx.dcx().span_err(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("demangling-alt({0:#})",
                demangling))
    })format!("demangling-alt({demangling:#})"));
40                }
41            }
42
43            if let Some(&span) = {
    {
        'done:
            {
            for i in ::rustc_hir::attrs::HasAttrs::get_attrs(id.def_id, &tcx)
                {
                #[allow(unused_imports)]
                use rustc_hir::attrs::AttributeKind::*;
                let i: &rustc_hir::Attribute = i;
                match i {
                    rustc_hir::Attribute::Parsed(RustcDumpDefPath(span)) => {
                        break 'done Some(span);
                    }
                    rustc_hir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }
}find_attr!(tcx, id.def_id, RustcDumpDefPath(span) => span) {
44                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));
45                tcx.dcx().span_err(span, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("def-path({0})", def_path))
    })format!("def-path({def_path})"));
46            }
47        }
48    })
49}