tinymist_analysis/ty/
apply.rs1use std::sync::LazyLock;
2
3use super::{Sig, SigChecker, SigSurfaceKind, TyCtx};
4use crate::ty::prelude::*;
5
6pub trait ApplyChecker: TyCtx {
8 fn apply(&mut self, sig: Sig, arguments: &Interned<ArgsTy>, pol: bool);
10}
11
12static EMPTY_ARGS: LazyLock<Interned<ArgsTy>> = LazyLock::new(|| ArgsTy::default().into());
14
15impl Ty {
16 pub fn call(&self, args: &Interned<ArgsTy>, pol: bool, c: &mut impl ApplyChecker) {
18 ApplySigChecker(c, args).ty(self, SigSurfaceKind::Call, pol);
19 }
20
21 pub fn tuple_element_of(&self, pol: bool, c: &mut impl ApplyChecker) {
23 ApplySigChecker(c, &EMPTY_ARGS).ty(self, SigSurfaceKind::Array, pol);
24 }
25
26 pub fn element_of(&self, pol: bool, c: &mut impl ApplyChecker) {
28 ApplySigChecker(c, &EMPTY_ARGS).ty(self, SigSurfaceKind::ArrayOrDict, pol);
29 }
30}
31
32#[derive(BindTyCtx)]
34#[bind(0)]
35pub struct ApplySigChecker<'a, T: ApplyChecker>(&'a mut T, &'a Interned<ArgsTy>);
36
37impl<T: ApplyChecker> ApplySigChecker<'_, T> {
38 fn ty(&mut self, ty: &Ty, surface: SigSurfaceKind, pol: bool) {
40 ty.sig_surface(pol, surface, self)
41 }
42}
43
44impl<T: ApplyChecker> SigChecker for ApplySigChecker<'_, T> {
45 fn check(&mut self, cano_sig: Sig, ctx: &mut super::SigCheckContext, pol: bool) -> Option<()> {
47 let (cano_sig, is_partialize) = match cano_sig {
48 Sig::Partialize(sig) => (*sig, true),
49 sig => (sig, false),
50 };
51 let partial_sig = if ctx.args.is_empty() {
53 cano_sig
54 } else {
55 Sig::With {
56 sig: &cano_sig,
57 withs: &ctx.args,
58 at: &ctx.at,
59 }
60 };
61 let partial_sig = if is_partialize {
62 Sig::Partialize(&partial_sig)
63 } else {
64 partial_sig
65 };
66
67 self.0.apply(partial_sig, self.1, pol);
68 Some(())
69 }
70}