rusty_cpp/analysis/
lifetimes.rs1use crate::ir::Lifetime;
2use std::collections::HashMap;
3
4#[derive(Debug)]
5#[allow(dead_code)]
6pub struct LifetimeAnalyzer {
7 lifetimes: HashMap<String, Lifetime>,
8 constraints: Vec<LifetimeConstraint>,
9}
10
11#[derive(Debug, Clone)]
12#[allow(dead_code)]
13pub enum LifetimeConstraint {
14 Outlives(String, String), Equal(String, String), }
17
18impl LifetimeAnalyzer {
19 #[allow(dead_code)]
20 pub fn new() -> Self {
21 Self {
22 lifetimes: HashMap::new(),
23 constraints: Vec::new(),
24 }
25 }
26
27 #[allow(dead_code)]
28 pub fn add_lifetime(&mut self, name: String, scope_start: usize, scope_end: usize) {
29 self.lifetimes.insert(
30 name.clone(),
31 Lifetime {
32 name,
33 scope_start,
34 scope_end,
35 },
36 );
37 }
38
39 #[allow(dead_code)]
40 pub fn add_constraint(&mut self, constraint: LifetimeConstraint) {
41 self.constraints.push(constraint);
42 }
43
44 #[allow(dead_code)]
45 pub fn check_constraints(&self) -> Result<(), Vec<String>> {
46 let mut errors = Vec::new();
47
48 for constraint in &self.constraints {
49 match constraint {
50 LifetimeConstraint::Outlives(longer, shorter) => {
51 if let (Some(l1), Some(l2)) = (self.lifetimes.get(longer), self.lifetimes.get(shorter)) {
52 if l1.scope_end < l2.scope_end {
53 errors.push(format!(
54 "Lifetime '{}' does not outlive '{}'",
55 longer, shorter
56 ));
57 }
58 }
59 }
60 LifetimeConstraint::Equal(a, b) => {
61 if let (Some(l1), Some(l2)) = (self.lifetimes.get(a), self.lifetimes.get(b)) {
62 if l1.scope_start != l2.scope_start || l1.scope_end != l2.scope_end {
63 errors.push(format!(
64 "Lifetimes '{}' and '{}' are not equal",
65 a, b
66 ));
67 }
68 }
69 }
70 }
71 }
72
73 if errors.is_empty() {
74 Ok(())
75 } else {
76 Err(errors)
77 }
78 }
79
80 #[allow(dead_code)]
81 pub fn infer_lifetimes(&mut self) -> HashMap<String, Lifetime> {
82 self.lifetimes.clone()
85 }
86}