Skip to main content

luaur_analysis/methods/
refinement_arena_negation_control_flow_graph.rs

1//! Source: `Analysis/src/ControlFlowGraph.cpp:38-49` (hand-ported)
2//! C++ `RefinementId RefinementArena::negation(RefinementId r)`.
3use crate::records::conjunction_control_flow_graph::Conjunction;
4use crate::records::disjunction_control_flow_graph::Disjunction;
5use crate::records::negation_control_flow_graph::Negation;
6use crate::records::proposition_control_flow_graph::Proposition;
7use crate::records::refinement_arena_control_flow_graph::RefinementArena;
8use crate::type_aliases::refinement_control_flow_graph::{Refinement, RefinementMember};
9use crate::type_aliases::refinement_id_control_flow_graph::RefinementId;
10use luaur_common::macros::luau_assert::LUAU_ASSERT;
11
12impl RefinementArena {
13    pub fn negation_mut(&mut self, r: RefinementId) -> RefinementId {
14        // C++ `get<T>(r)` == `get_if<T>(r.get())`. `r` is `*mut Refinement`.
15        let refinement: &Refinement = unsafe { &*r };
16
17        // if (auto* conj = get<Conjunction>(r))
18        //     return disjunction(negation(conj->lhs), negation(conj->rhs));
19        if let Some(conj) = <Conjunction as RefinementMember>::get_if(refinement) {
20            let (lhs, rhs) = (conj.lhs, conj.rhs);
21            let nl = self.negation_mut(lhs);
22            let nr = self.negation_mut(rhs);
23            return self.disjunction_mut(nl, nr);
24        }
25
26        // if (auto* disj = get<Disjunction>(r))
27        //     return conjunction(negation(disj->lhs), negation(disj->rhs));
28        if let Some(disj) = <Disjunction as RefinementMember>::get_if(refinement) {
29            let (lhs, rhs) = (disj.lhs, disj.rhs);
30            let nl = self.negation_mut(lhs);
31            let nr = self.negation_mut(rhs);
32            return self.conjunction_mut(nl, nr);
33        }
34
35        // if (auto* neg = get<Negation>(r))
36        //     return neg->refinement;
37        if let Some(neg) = <Negation as RefinementMember>::get_if(refinement) {
38            return neg.refinement;
39        }
40
41        // LUAU_ASSERT(get<Proposition>(r));
42        LUAU_ASSERT!(<Proposition as RefinementMember>::get_if(refinement).is_some());
43        // return NotNull{allocator.allocate(Negation{r})};
44        self.allocator
45            .allocate(Refinement::Negation(Negation { refinement: r }))
46    }
47}