dada_ir_sym/check/red/
sub.rs1use 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}