Skip to content

Commit 60cc27e

Browse files
committed
Record body binding facts in HIR
1 parent 6f3ab55 commit 60cc27e

3 files changed

Lines changed: 226 additions & 43 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ It currently implements:
1717
- HIR type and field tables for class/struct/resource declarations and handle fields
1818
- HIR constructor signatures derived from declared type fields
1919
- HIR call-site facts with resolved builtin, user function, constructor, enum variant, and unknown callees
20+
- HIR body binding facts for parameters, managed lets, local lets, and best-effort initial value types
2021
- AST-driven mode and call checks for local-only features, named arguments, data effects, and retaining APIs
2122
- AST-driven body checks for local moves, early-exit-aware `fresh` returns, resource escape, resolved handle-field `take`, and managed closure captures
2223
- Focused check modules for mode, calls, body semantics, and forbidden operator behavior

src/checks/body.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
22

33
use crate::analyzer::Analyzer;
44
use crate::diagnostic::{Diagnostic, code};
5-
use crate::hir::{CallResolution, HirTypeKind, ResolvedCalleeKind};
5+
use crate::hir::{CallResolution, HirBindingKind, HirTypeKind, ResolvedCalleeKind};
66
use crate::syntax::ast::{
77
Block, CallArg, Callee, DataEffect, Expr, FunctionDecl, Item, LetKind, Stmt,
88
};
@@ -20,11 +20,7 @@ pub(crate) fn check(analyzer: &mut Analyzer<'_>) {
2020

2121
for function in functions {
2222
let mut state = BodyState::default();
23-
for param in &function.params {
24-
state
25-
.value_types
26-
.insert(param.name.clone(), param.ty.name.clone());
27-
}
23+
seed_function_bindings(analyzer, &function, &mut state);
2824
check_block(analyzer, &function, &function.body, &mut state);
2925
}
3026
}
@@ -38,6 +34,19 @@ struct BodyState {
3834
value_types: HashMap<String, String>,
3935
}
4036

37+
fn seed_function_bindings(analyzer: &Analyzer<'_>, function: &FunctionDecl, state: &mut BodyState) {
38+
for binding in analyzer.hir.function_bindings(&function.name) {
39+
if binding.kind != HirBindingKind::Param {
40+
continue;
41+
}
42+
if let Some(type_name) = &binding.type_name {
43+
state
44+
.value_types
45+
.insert(binding.name.clone(), type_name.clone());
46+
}
47+
}
48+
}
49+
4150
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4251
enum Flow {
4352
Fallthrough,
@@ -175,7 +184,9 @@ fn apply_stmt_effects(analyzer: &mut Analyzer<'_>, statement: &Stmt, state: &mut
175184
}
176185
}
177186
if let Some(value) = &stmt.value {
178-
if let Some(type_name) = infer_expr_type(analyzer, value, state) {
187+
if let Some(type_name) = hir_binding_type(analyzer, &stmt.span)
188+
.or_else(|| infer_expr_type(analyzer, value, state))
189+
{
179190
state.value_types.insert(stmt.name.clone(), type_name);
180191
}
181192
apply_expr_effects(analyzer, value, state);
@@ -197,6 +208,13 @@ fn apply_stmt_effects(analyzer: &mut Analyzer<'_>, statement: &Stmt, state: &mut
197208
}
198209
}
199210

211+
fn hir_binding_type(analyzer: &Analyzer<'_>, span: &crate::diagnostic::Span) -> Option<String> {
212+
analyzer
213+
.hir
214+
.binding(span)
215+
.and_then(|binding| binding.type_name.clone())
216+
}
217+
200218
fn merge_if_state(
201219
state: &mut BodyState,
202220
base: &BodyState,

0 commit comments

Comments
 (0)