flux_common/
dbg.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! This file contains functions and macros to log debugging information meant for developers.
use std::{
    fmt, fs,
    io::{self, Write},
};

use flux_config as config;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;

pub fn writer_for_item(
    tcx: TyCtxt,
    def_id: DefId,
    ext: impl AsRef<str>,
) -> io::Result<impl io::Write> {
    fs::create_dir_all(config::log_dir())?;
    let path = config::log_dir().join(dump_base_name(tcx, def_id, ext));
    let file = fs::File::create(path)?;
    let buf = std::io::BufWriter::new(file);
    Ok(buf)
}

pub fn dump_item_info<T: fmt::Debug>(
    tcx: TyCtxt,
    def_id: impl Into<DefId>,
    ext: impl AsRef<str>,
    val: T,
) -> io::Result<()> {
    let mut writer = writer_for_item(tcx, def_id.into(), ext)?;
    writeln!(writer, "{val:#?}")
}

#[macro_export]
macro_rules! _shape_mode_span {
    ($tcx:expr, $def_id:expr) => {{
        let path = $tcx.def_path(rustc_hir::def_id::DefId::from($def_id));
        let def_id = path.data.iter().join("::");
        tracing::info_span!("shape", def_id = def_id.as_str())
    }};
}
pub use crate::_shape_mode_span as shape_mode_span;

#[macro_export]
macro_rules! _refine_mode_span {
    ($tcx:expr, $def_id:expr, $bb_envs:expr) => {{
        let path = $tcx.def_path(rustc_hir::def_id::DefId::from($def_id));
        let def_id = path.data.iter().join("::");
        tracing::info_span!("refine", def_id = def_id.as_str(), bb_envs = ?$bb_envs)
    }};
}
pub use crate::_refine_mode_span as refine_mode_span;

#[macro_export]
macro_rules! _check_fn_span {
    ($tcx:expr, $def_id:expr) => {{
        let path = $tcx.def_path(rustc_hir::def_id::DefId::from($def_id));
        let def_id = path.data.iter().join("::");
        tracing::info_span!("check_fn", def_id = def_id.as_str())
    }};
}
pub use crate::_check_fn_span as check_fn_span;

#[macro_export]
macro_rules! _basic_block_start {
    ($bb:expr, $rcx:expr, $env:expr) => {{
        tracing::debug!(event = "basic_block_start", bb = ?$bb, rcx = ?$rcx, env = ?$env)
    }};
}
pub use crate::_basic_block_start as basic_block_start;

#[macro_export]
macro_rules! _statement{
    ($pos:literal, $stmt:expr, $infcx:expr, $env:expr, $span:expr, $checker:expr) => {{
        if config::dump_checker_trace() {
            let rcx = $infcx.cursor();
            let ck = $checker;
            let genv = ck.genv;
            let local_names = &ck.body.local_names;
            let local_decls = &ck.body.local_decls;
            let rcx_json = RefineCtxtTrace::new(genv, rcx);
            let env_json = TypeEnvTrace::new(genv, local_names, local_decls, $env);
            let span_json = SpanTrace::new(genv, $span);
            tracing::info!(event = concat!("statement_", $pos), stmt = ?$stmt, stmt_span = ?$span, rcx = ?rcx, env = ?$env, rcx_json = ?rcx_json, env_json = ?env_json, stmt_span_json = ?span_json)
        }
    }};
}
pub use crate::_statement as statement;

#[macro_export]
macro_rules! _terminator{
    ($pos:literal, $terminator:expr, $rcx:expr, $env:expr) => {{
        tracing::debug!(event = concat!("terminator_", $pos), terminator = ?$terminator, rcx = ?$rcx, env = ?$env)
    }};
}
pub use crate::_terminator as terminator;

#[macro_export]
macro_rules! _refine_goto {
    ($target:expr, $rcx:expr, $env:expr, $bb_env:expr) => {{
        tracing::debug!(event = "refine_goto", target = ?$target, rcx = ?$rcx, env = ?$env, bb_env = ?$bb_env)
    }};
}
pub use crate::_refine_goto as refine_goto;

#[macro_export]
macro_rules! _shape_goto_enter {
    ($target:expr, $env:expr, $bb_env:expr) => {{
        if let Some(bb_env) = &$bb_env {
            tracing::debug!(event = "shape_goto_enter", target = ?$target, env = ?&$env, ?bb_env)
        } else {
            tracing::debug!(event = "shape_goto_enter", target = ?$target, env = ?&$env, bb_env = "empty")
        }
    }};
}
pub use crate::_shape_goto_enter as shape_goto_enter;

#[macro_export]
macro_rules! _shape_goto_exit {
    ($target:expr, $bb_env:expr) => {{
        tracing::debug!(event = "shape_goto_exit", target = ?$target, bb_env = ?&$bb_env)
    }};
}
pub use crate::_shape_goto_exit as shape_goto_exit;

fn dump_base_name(tcx: TyCtxt, def_id: DefId, ext: impl AsRef<str>) -> String {
    let crate_name = tcx.crate_name(def_id.krate);
    let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate();
    format!("{crate_name}.{item_name}.{}", ext.as_ref())
}

#[macro_export]
macro_rules! _debug_assert_eq3 {
    ($e1:expr, $e2:expr, $e3:expr) => {{
        debug_assert!($e1 == $e2 && $e2 == $e3, "{:?} != {:?} != {:?}", $e1, $e2, $e3);
    }};
}
pub use crate::_debug_assert_eq3 as debug_assert_eq3;