nichlink/registry_core/mir/model.rs
1//! Shared MIR vocabulary: parsed candidates, evidence-aware relations, errors.
2//! 共享 MIR 词汇:已解析候选、带证据等级的关系、错误。
3//!
4//! The parsers live beside this page: `super::text` reads rustc
5//! `-Zunpretty=mir` text, `super::jsonl` reads the compact JSONL artifact,
6//! `super::render` writes both artifacts back, and `super::merge` merges
7//! static candidates with live edges.
8//! 解析器位于本页旁边:`super::text` 读取 rustc `-Zunpretty=mir` 文本,
9//! `super::jsonl` 读取紧凑 JSONL artifact,`super::render` 把两种 artifact 写回,
10//! `super::merge` 将静态候选与 live 边归并。
11
12use std::collections::BTreeSet;
13use std::fmt;
14
15use crate::registry_core::declaration::{EvidenceKind, SourceLocation};
16
17/// One direct call sighting extracted from a MIR artifact.
18/// 从 MIR artifact 中提取到的一条直接调用观测。
19#[derive(Clone, Debug, PartialEq, Eq)]
20pub struct MirCall {
21 /// Function symbol the call appears in.
22 /// 调用所在的函数符号。
23 pub caller: String,
24 /// Function symbol being called.
25 /// 被调用的函数符号。
26 pub callee: String,
27 /// 1-based position of this record within the parsed MIR, not a source line.
28 /// 该记录在已解析 MIR 内以 1 起始的位置,不是源码行号。
29 pub mir_line: usize,
30}
31
32/// One local binding sighting extracted from a MIR artifact.
33/// 从 MIR artifact 中提取到的一条局部绑定观测。
34#[derive(Clone, Debug, PartialEq, Eq)]
35pub struct MirLocal {
36 /// Function symbol owning the local.
37 /// 拥有该局部变量的函数符号。
38 pub function: String,
39 /// Local binding name as written in MIR, such as `_1`.
40 /// MIR 中书写的局部绑定名,例如 `_1`。
41 pub name: String,
42 /// Declared type text of the binding.
43 /// 该绑定的声明类型文本。
44 pub type_name: String,
45 /// 1-based position of this record within the parsed MIR, not a source line.
46 /// 该记录在已解析 MIR 内以 1 起始的位置,不是源码行号。
47 pub mir_line: usize,
48}
49
50/// Unified evidence attached to one logical call relation.
51/// 一条逻辑调用关系携带的统一证据等级。
52pub type CallEvidence = EvidenceKind;
53
54/// One call edge normalized across runtime, MIR, and source evidence.
55/// 跨运行时、MIR、源码证据统一表示的一条调用边。
56#[derive(Clone, Debug, PartialEq, Eq)]
57pub struct CallRelation {
58 /// Function symbol making the call.
59 /// 发起调用的函数符号。
60 pub caller: String,
61 /// Function symbol being called.
62 /// 被调用的函数符号。
63 pub callee: String,
64 /// Strongest evidence supporting this relation: live over MIR.
65 /// 支持该关系的最高证据等级:Live 优先于 MIR。
66 pub evidence: EvidenceKind,
67 /// Source location of the callee, when known.
68 /// 已知时,被调用方的源码位置。
69 pub source: Option<SourceLocation>,
70 /// MIR record position for a MIR-only relation; `None` for a live edge.
71 /// 仅由 MIR 支持时为 MIR 记录位置;live 边为 `None`。
72 pub mir_line: Option<usize>,
73 /// Runtime frame id of the caller; `None` for a static-only relation.
74 /// 调用方的运行期帧 id;仅静态关系为 `None`。
75 pub caller_frame: Option<u64>,
76 /// Runtime frame id of the callee; `None` for a static-only relation.
77 /// 被调用方的运行期帧 id;仅静态关系为 `None`。
78 pub callee_frame: Option<u64>,
79}
80
81impl CallRelation {
82 /// A relation whose two ends are known but whose provenance is only the text
83 /// of the call site: no MIR record, no runtime frame.
84 /// 两端已知、但来源只是调用点文本的关系:没有 MIR 记录,也没有运行期帧。
85 ///
86 /// Studio's source scan produces these, which is why the type has to be
87 /// constructible without inventing a MIR line or a frame id.
88 /// Studio 的源码扫描产生的正是它们,因此该类型必须能在不编造 MIR 行号或帧 id 的情况下构造。
89 pub fn from_symbols(
90 caller: impl Into<String>,
91 callee: impl Into<String>,
92 evidence: EvidenceKind,
93 ) -> Self {
94 Self {
95 caller: caller.into(),
96 callee: callee.into(),
97 evidence,
98 source: None,
99 mir_line: None,
100 caller_frame: None,
101 callee_frame: None,
102 }
103 }
104}
105
106/// Every candidate one MIR artifact offered, before any merge.
107/// 一份 MIR artifact 提供的全部候选,尚未归并。
108#[derive(Clone, Debug, Default, PartialEq, Eq)]
109pub struct MirGraph {
110 /// Function symbols the artifact declared.
111 /// artifact 声明过的函数符号。
112 pub functions: BTreeSet<String>,
113 /// Direct call sightings, in artifact order.
114 /// 直接调用观测,按 artifact 顺序。
115 pub calls: Vec<MirCall>,
116 /// Local binding sightings, in artifact order.
117 /// 局部绑定观测,按 artifact 顺序。
118 pub locals: Vec<MirLocal>,
119}
120
121/// Why one line of a MIR artifact could not be read.
122/// MIR artifact 某一行无法读取的原因。
123#[derive(Clone, Debug, PartialEq, Eq)]
124pub struct MirParseError {
125 /// 1-based line of the offending input.
126 /// 出错输入以 1 起始的行号。
127 pub line: usize,
128 /// Description of what the line got wrong.
129 /// 对该行错误之处的描述。
130 pub message: String,
131}
132
133impl fmt::Display for MirParseError {
134 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
135 write!(formatter, "MIR graph line {}: {}", self.line, self.message)
136 }
137}
138
139impl std::error::Error for MirParseError {}