refactor(joinir): phase 100 P1 - add CapturedKind (Explicit/Pinned) to CapturedVar
- Add CapturedKind enum to types.rs (Explicit for traditional, Pinned for Phase 100) - Update CapturedVar struct to include kind field - Add insert() and insert_pinned() helper methods to CapturedEnv - Update analyzers.rs to specify kind field in all CapturedVar instantiations - Export CapturedKind from function_scope_capture module - Update scope_manager.rs test to include kind field 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -6,7 +6,7 @@ use crate::mir::ValueId;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use super::helpers::*;
|
||||
use super::types::{CapturedEnv, CapturedVar};
|
||||
use super::types::{CapturedEnv, CapturedKind, CapturedVar};
|
||||
|
||||
/// Analyzes function-scoped variables that can be safely captured for loop conditions/body.
|
||||
///
|
||||
@ -159,6 +159,7 @@ pub(crate) fn analyze_captured_vars(
|
||||
name: name.clone(),
|
||||
host_id: ValueId(0), // Placeholder, will be resolved in ConditionEnvBuilder
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Explicit,
|
||||
});
|
||||
}
|
||||
|
||||
@ -296,6 +297,7 @@ pub(crate) fn analyze_captured_vars_v2(
|
||||
name: name.clone(),
|
||||
host_id: ValueId(0), // Placeholder, will be resolved in ConditionEnvBuilder
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Explicit,
|
||||
});
|
||||
}
|
||||
|
||||
@ -343,6 +345,7 @@ pub(crate) fn analyze_captured_vars_v2(
|
||||
name: name.clone(),
|
||||
host_id: ValueId(0), // Placeholder, will be resolved in ConditionEnvBuilder
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Explicit,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -54,4 +54,4 @@ mod types;
|
||||
|
||||
// Public re-exports
|
||||
pub(crate) use analyzers::analyze_captured_vars_v2;
|
||||
pub use types::{CapturedEnv, CapturedVar};
|
||||
pub use types::{CapturedEnv, CapturedKind, CapturedVar};
|
||||
|
||||
@ -2,6 +2,18 @@
|
||||
|
||||
use crate::mir::ValueId;
|
||||
|
||||
/// Classification of captured variable (Phase 100 expansion)
|
||||
///
|
||||
/// - `Explicit`: Captured for condition/carrier usage (traditional, Phase 200-A/B)
|
||||
/// - `Pinned`: Read-only local from loop-outer scope, used as receiver in loop body (Phase 100)
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum CapturedKind {
|
||||
/// Traditional capture (condition variables, carriers)
|
||||
Explicit,
|
||||
/// Phase 100: read-only local (dynamic construction allowed, immutable in loop)
|
||||
Pinned,
|
||||
}
|
||||
|
||||
/// A variable captured from function scope for use in loop conditions/body.
|
||||
///
|
||||
/// Example: `local digits = "0123456789"` in JsonParser._atoi()
|
||||
@ -11,9 +23,10 @@ use crate::mir::ValueId;
|
||||
/// - `name`: Variable name as it appears in the source code
|
||||
/// - `host_id`: MIR ValueId of the original definition in the host function
|
||||
/// - `is_immutable`: True if the variable is never reassigned in the function
|
||||
/// - `kind`: Classification as Explicit (traditional) or Pinned (Phase 100 read-only)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CapturedVar {
|
||||
/// Variable name (e.g., "digits", "table")
|
||||
/// Variable name (e.g., "digits", "table", "s")
|
||||
pub name: String,
|
||||
|
||||
/// MIR ValueId of the original definition in the host function
|
||||
@ -24,6 +37,9 @@ pub struct CapturedVar {
|
||||
/// Phase 200-B will implement assignment analysis to determine this.
|
||||
/// For now, this is always set to true as a conservative default.
|
||||
pub is_immutable: bool,
|
||||
|
||||
/// Phase 100: Classification of captured variable
|
||||
pub kind: CapturedKind,
|
||||
}
|
||||
|
||||
/// Environment containing function-scoped captured variables.
|
||||
@ -53,6 +69,26 @@ impl CapturedEnv {
|
||||
self.vars.push(var);
|
||||
}
|
||||
|
||||
/// Add an explicit captured variable (traditional capture)
|
||||
pub fn insert(&mut self, name: String, host_id: ValueId) {
|
||||
self.add_var(CapturedVar {
|
||||
name,
|
||||
host_id,
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Explicit,
|
||||
});
|
||||
}
|
||||
|
||||
/// Add a pinned captured variable (Phase 100: read-only local)
|
||||
pub fn insert_pinned(&mut self, name: String, host_id: ValueId) {
|
||||
self.add_var(CapturedVar {
|
||||
name,
|
||||
host_id,
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Pinned,
|
||||
});
|
||||
}
|
||||
|
||||
/// Look up a captured variable by name
|
||||
///
|
||||
/// Returns `Some(&CapturedVar)` if found, `None` otherwise.
|
||||
@ -79,6 +115,7 @@ mod tests {
|
||||
name: "digits".to_string(),
|
||||
host_id: ValueId(42),
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Explicit,
|
||||
});
|
||||
|
||||
assert!(!env.is_empty());
|
||||
@ -86,6 +123,7 @@ mod tests {
|
||||
assert_eq!(var.name, "digits");
|
||||
assert_eq!(var.host_id, ValueId(42));
|
||||
assert!(var.is_immutable);
|
||||
assert_eq!(var.kind, CapturedKind::Explicit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -95,11 +133,13 @@ mod tests {
|
||||
name: "digits".to_string(),
|
||||
host_id: ValueId(42),
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Explicit,
|
||||
});
|
||||
env.add_var(CapturedVar {
|
||||
name: "table".to_string(),
|
||||
host_id: ValueId(100),
|
||||
is_immutable: true,
|
||||
kind: CapturedKind::Pinned,
|
||||
});
|
||||
|
||||
assert_eq!(env.vars.len(), 2);
|
||||
@ -107,4 +147,22 @@ mod tests {
|
||||
assert!(env.get("table").is_some());
|
||||
assert!(env.get("nonexistent").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_captured_env_insert_explicit() {
|
||||
let mut env = CapturedEnv::new();
|
||||
env.insert("x".to_string(), ValueId(10));
|
||||
|
||||
let var = env.get("x").unwrap();
|
||||
assert_eq!(var.kind, CapturedKind::Explicit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_captured_env_insert_pinned() {
|
||||
let mut env = CapturedEnv::new();
|
||||
env.insert_pinned("s".to_string(), ValueId(20));
|
||||
|
||||
let var = env.get("s").unwrap();
|
||||
assert_eq!(var.kind, CapturedKind::Pinned);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user