Skip to main content

dada_ir_sym/check/red/
sub.rs

1use dada_ir_ast::diagnostic::Errors;
2
3use crate::check::env::Env;
4
5use super::{RedChain, RedLink};
6
7pub fn chain_sub_chain<'db>(
8    env: &Env<'db>,
9    lower_chain: RedChain<'db>,
10    upper_chain: RedChain<'db>,
11) -> Errors<bool> {
12    let db = env.db();
13    links_sub_links(env, lower_chain.links(db), upper_chain.links(db))
14}
15
16fn links_sub_links<'db>(
17    env: &Env<'db>,
18    lower_links: &[RedLink<'db>],
19    upper_links: &[RedLink<'db>],
20) -> Errors<bool> {
21    macro_rules! rules {
22        ($($pat:pat => $cond:expr,)*) => {
23            match (lower_links, upper_links) {
24                $(
25                    $pat if $cond => Ok(true),
26                )*
27                _ => Ok(false),
28            }
29        };
30    }
31
32    rules! {
33        ([], []) => true,
34
35        ([RedLink::Our], links_u) => RedLink::are_copy(env, links_u)?,
36
37        ([RedLink::Our, tail_l @ ..], [head_u, tail_u @ ..]) => {
38            head_u.is_copy(env)?
39            && links_sub_links(env, tail_l, tail_u)?
40        },
41
42        (
43            [
44                RedLink::Ref(_, place_l),
45                tail_l @ ..,
46            ],
47            [
48                RedLink::Ref(_, place_u),
49                tail_u @ ..,
50            ],
51        )
52        | (
53            [
54                RedLink::Mut(_, place_l),
55                tail_l @ ..,
56            ],
57            [
58                RedLink::Mut(_, place_u),
59                tail_u @ ..,
60            ],
61        )
62        | (
63            [
64                RedLink::Ref(_, place_l),
65                tail_l @ ..,
66            ],
67            [
68                RedLink::Our,
69                RedLink::Mut(_, place_u),
70                tail_u @ ..,
71            ],
72        ) => {
73            place_u.is_prefix_of(env.db(), *place_l)
74            && links_sub_links(env, tail_l, tail_u)?
75        },
76
77        ([RedLink::Var(var_l), tail_l @ ..], [RedLink::Var(var_u), tail_u @ ..]) => {
78            var_l == var_u && links_sub_links(env, tail_l, tail_u)?
79        },
80
81
82    }
83}