- 
                Notifications
    
You must be signed in to change notification settings  - Fork 18
 
Description
Problem
The .name() API doc indicates returned path is absolute, however, it's not true because for local functions ("local" means that the crate is being compiled), the fn name doesn't include crate root.
Retrieve the instance name for diagnostic messages.
This will return the specialized name, e.g., std::vec::Vec::new.
src: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_public/mir/mono/struct.Instance.html#method.name
(local ) [test    ] a                              - (instance) a // NOT test::a π₯
(local ) [test    ] b                              - (instance) b // NOT test::b π₯
(extern) [std     ] std::rt::__rust_abort          - (instance) std::rt::__rust_abort
(extern) [std     ] std::rt::handle_rt_panic       - (instance) Item requires monomorphization
(extern) [core    ] core::contracts::build_check_ensures - (instance) Item requires monomorphization
(extern) [core    ] core::f128::<impl f128>::is_nan - (instance) core::f128::<impl f128>::is_nanThat brings a problem when libcore is compiled directly with smir to get names like
num::nonzero::<impl convert::From<num::nonzero::NonZero<u64>> for u64>::from,
in which num and convert are submodules in core rather than external crates.
You may argue that the path is for diagnostics, thus slimmed local item names are fine, but it'd be good for smir to make a good uniform path in a less surprising manner. This can be even quite troublesome for quering because fn names from local and external crates need to be carefully handled.
I think the ideal solution may have a dedicated (typed) ItemPath API. The above fn path invloves module path, trait path, and struct path. cc #68
Maybe the current only choice is resorting to internal DefPath.
Reproduce
Details
$ cat test.rs
pub fn a() {}
fn b() {}
$ export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib
$ ./target/debug/smir-fn-name --crate-type=lib test.rs// smir-fn-name/src/main.rs
#![feature(rustc_private)]
extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_middle;
extern crate rustc_public;
use rustc_public::{mir::mono::Instance, ty::FnDef, CrateDef, CrateItem};
fn main() {
    let args: Vec<_> = std::env::args().collect();
    _ = rustc_public::run!(&args, || {
        analyze();
        ControlFlow::<(), ()>::Break(())
    });
}
fn analyze() {
    let local_crate = rustc_public::local_crate();
    let crate_name = &*local_crate.name;
    for f in local_crate.fn_defs() {
        let inst_name = name_from_instance(&f);
        println!(
            "(local ) [{crate_name:8}] {:30} - (instance) {inst_name}",
            f.name()
        );
    }
    for extern_krate in rustc_public::external_crates() {
        let root = &*extern_krate.name;
        for f in extern_krate.fn_defs().iter().take(2) {
            let inst_name = name_from_instance(f);
            println!(
                "(extern) [{root:8}] {:30} - (instance) {inst_name}",
                f.name()
            );
        }
    }
}
fn name_from_instance(f: &FnDef) -> String {
    Instance::try_from(CrateItem(f.def_id()))
        .map(|inst| inst.name())
        .unwrap_or_else(|err| err.to_string())
}