Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to resolve modules for THIR visitor? #129646

Closed
mrdgo opened this issue Aug 27, 2024 · 4 comments
Closed

How to resolve modules for THIR visitor? #129646

mrdgo opened this issue Aug 27, 2024 · 4 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@mrdgo
Copy link

mrdgo commented Aug 27, 2024

Problem statement

I want to do static analysis on rust programs. For AST-only, syn is excellent. But I ran into issues and want to implement a visitor to visit the THIR. There is some docs on how to run an analysis over a typed program. Sadly, it doesn't resolve modules or externs. My question: how can I use the resolver of the compiler to study the functions used in other modules?

What I did so far

  • Copy the aforementioned code snippet and run a sample analysis (output names of functions)
  • Run cargo build -vv to see all the flags that cargo sets and set them accordingly in the config of my invocation
  • Fork rustc to printf-debug the options that I didn't find out how to set looking at the docs and add them to the snippet (I hardcoded a few more to see, if that makes a difference, but it didn't - didn't push them because they contain full paths and the error still remains the same.)

Log

error[E0583]: file not found for module `thir_analysis`
 --> <src/main.rs>:4:1
  |
4 | mod thir_analysis;
  | ^^^^^^^^^^^^^^^^^^
  |
  = help: to create the module `thir_analysis`, create file "<src/thir_analysis.rs" or "<src/thir_analysis/mod.rs"
  = note: if there is a `mod thir_analysis` elsewhere in the crate already, import it with `use crate::...` instead

error[E0463]: can't find crate for `walkdir`
 --> <src/main.rs>:5:5
  |
5 | use walkdir::WalkDir;
  |     ^^^^^^^ can't find crate

error[E0425]: cannot find function `thir_analysis` in module `thir_analysis`
  --> <src/main.rs>:30:20
   |
30 |     thir_analysis::thir_analysis(file_name, contents);
   |                    ^^^^^^^^^^^^^ not found in `thir_analysis`


Function definition: get_rust_files

Function definition: main
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0425, E0463, E0583.
For more information about an error, try `rustc --explain E0425`.

Lesson from output

As you can see, the analysis successfully runs and outputs the function names. But it fails to resolve both thir_analysis and walkdir::WalkDir, though cargo run clearly found them.

To reproduce

  • clone my repo
  • run cargo run -- src/main.rs

Question

How do I correctly invoke the compiler to run a static analysis that also resolves modules?

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Aug 27, 2024
@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 27, 2024
@mrdgo
Copy link
Author

mrdgo commented Sep 2, 2024

Update: I found out that there is

let (resolver, _) = &*tcx.resolver_for_lowering().borrow();

This resolver appears to correctly infer that my submodule is a module. But the error that the module cannot be resolved is triggered before I even invoke this function. So the following is the code in question:

    rustc_interface::run_compiler(config, |compiler| {
        compiler.enter(|queries| {
            queries.global_ctxt().unwrap().enter(|tcx| {
                let hir_krate = tcx.hir();
                // No error thrown
                println!("After HIR query");
                for id in hir_krate.items() {
                    // Errors thrown that all items that are not defined in `src/main.rs` 
                    //(the main file of the program that I want to analyze) could not have been found.
                    // The error messages appear BEFORE the FIRST print
                    println!("Hello item!");
                    let item = hir_krate.item(id);
                    // do stuff with the item
                }
            });
        });
    });

The error is thrown precisely at the hir_krate.items() invocation. How do I tell this query to resolve modules?

@mrdgo
Copy link
Author

mrdgo commented Sep 2, 2024

                    match item.kind {
                        rustc_hir::ItemKind::Fn(_signature, _generics, body_id) => {
                            let func_hir = &tcx.hir().body(body_id);
                            let body_expr = func_hir.value;
                            match body_expr.kind {
                                rustc_hir::ExprKind::Block(_, _) => {
                                    match &tcx.thir_body(body_expr.hir_id.owner) {
                                        Ok((thir_ro, expr_id)) => {
                                            // this is where I want to do my analysis
                                        },
                                        Err(x) => {
                                            // But I always get an `ErrorGuaranteed` here
                                            dbg!(x);
                                        }
                                    };
                                }
                                _ => {
                                    dbg!("Function body, that is no block..?");
                                }
                            }
                        }
                        _ => (),
                    }

@cjgillot
Copy link
Contributor

cjgillot commented Sep 2, 2024

Could you move this discussion to zulip? https://rust-lang.zulipchat.com/
That will be more practical to answer you.
And could you please explain in detail (in zulip) what you are trying to do. The resolver works on the AST. THIR is fully resolved, so you should never need both the resolver and THIR at the same time.

@cjgillot cjgillot closed this as completed Sep 2, 2024
@mrdgo
Copy link
Author

mrdgo commented Sep 3, 2024

Alright, thanks
discussion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants