fold/docs/internal/rustc-analysis-api-research.md
trvon 04642c46af
docs: rustc internals research for HIR/MIR analysis in fold-rust
- rustc_driver Callbacks, TyCtxt, HIR ExprKind, MIR BasicBlock/Rvalue
- TyKind type system: bit-width queries via LayoutS
- Borrow checker: BorrowKind, loan scopes, BorrowTracker usage
2026-05-28 20:09:14 -04:00

3.9 KiB

Rustc Internals for HIR/MIR Analysis in fold-rust

Generated 2026-05-28. Research on rustc APIs available for fold-rust scanning.

rustc_driver + rustc_interface

fold-rust uses rustc_driver::Callbacks to intercept compilation:

struct FoldCallbacks;
impl Callbacks for FoldCallbacks {
    fn after_analysis<'tcx>(&mut self, _compiler: &Compiler,
                            queries: &'tcx Queries<'tcx>) -> Compilation {
        queries.global_ctxt().unwrap().enter(|tcx| {
            // tcx: TyCtxt<'tcx> — access to all compiler state
            for def_id in tcx.hir().body_owners() {
                emit_function(tcx, sm, def_id);
            }
        });
        Compilation::Continue
    }
}

Key APIs:

  • TyCtxt<'tcx> — central query context: types, HIR, MIR, borrow checker
  • tcx.hir() — access HIR (High-level IR)
  • tcx.optimized_mir(def_id) — access MIR after optimizations
  • tcx.typeck(def_id) — type-checking results

HIR (High-level IR)

rustc_hir::Expr with ExprKind variants:

ExprKind Security relevance
Unary(UnOp::Deref, sub) Raw pointer deref — null-deref detection
MethodCall(segment, receiver, args) Method dispatch — taint tracking
Call(callee, args) Function call — interprocedural boundary
Binary(op, lhs, rhs) Arithmetic — overflow detection
Index(base, index) Array access — OOB detection
If(cond, then, else_opt) Branch — path predicate forking
AddrOf(..) Address-of — pointer tracking
Cast(expr, ty) Type cast — truncation detection

fold-rust's DerefHunter visitor walks HIR and matches these patterns.

MIR (Mid-level IR)

rustc_middle::mir::Body with BasicBlocks:

  • StatementKind::Assign(box (place, rvalue)) — variable assignment
  • StatementKind::StorageLive(local) — variable comes into scope
  • StatementKind::StorageDead(local) — variable goes out of scope
  • TerminatorKind::Call { func, args, destination, .. } — function call
  • TerminatorKind::SwitchInt { discr, targets } — enum/switch dispatch
  • TerminatorKind::Return — function exit
  • TerminatorKind::Goto { target } — unconditional branch

Rvalue variants:

  • Use(operand) — copy/move
  • Ref(region, kind, place) — borrow
  • BinaryOp(op, box (lhs, rhs)) — arithmetic
  • CheckedBinaryOp(op, box (lhs, rhs)) — checked arithmetic
  • Cast(kind, operand, ty) — type cast
  • RawPtr(..) — raw pointer creation
  • Discriminant(place) — enum discriminant

Type System

TyKind variants accessible via tcx.type_of(def_id):

  • TyKind::Int(IntTy) — signed integers (i8, i16, i32, i64, i128, isize)
  • TyKind::Uint(UintTy) — unsigned integers (u8, u16, u32, u64, u128, usize)
  • TyKind::Bool, TyKind::Char, TyKind::Float(FloatTy)
  • TyKind::Ref(region, ty, mutability) — references
  • TyKind::RawPtr(TypeAndMut { ty, mutbl }) — raw pointers
  • TyKind::Adt(def, substs) — structs, enums, unions
  • TyKind::Array(ty, len) — fixed-size arrays
  • TyKind::Slice(ty) — dynamically-sized slices
  • TyKind::FnDef(def_id, substs) — function types

Bit-width queries:

  • tcx.layout_of(param_env.and(ty)) → LayoutS with size, align, abi
  • layout.size.bits() → bit-width (for encoding)

Borrow Checker

rustc_borrowck::consumers::BodyWithBorrowckFacts provides:

  • BorrowKind: Shared, Unique, Mut
  • Loan scopes: which regions a borrow covers
  • Move tracking: which locals are moved

fold-rust's mir_analysis::BorrowTracker uses this to determine which pointers are borrow-backed (safe) vs raw-pointer (potentially unsafe).

Recommendations for fold

  1. Use MIR BasicBlock structure for control flow in the Z3 encoder (task 120)
  2. Thread TyKind signedness through observer hooks (done: 93439bf)
  3. Leverage LayoutS::size for precise bit-widths in symbolic encoding
  4. Use borrow checker facts for null-deref suppression (BorrowTracker, wired in task 102)