• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TyRoXx / NonlocalityOS / 13852727264

14 Mar 2025 08:30AM UTC coverage: 79.181% (-0.6%) from 79.739%
13852727264

Pull #202

github

web-flow
Merge 2ad6a92a0 into 49862011f
Pull Request #202: Compiler update

4024 of 5082 relevant lines covered (79.18%)

1854.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/lambda/src/type_checking.rs
1
use astraea::tree::BlobDigest;
2

3
use crate::{
4
    expressions::{Expression, LambdaExpression},
5
    types::{Interface, Name, Signature, Type, TypedExpression},
6
};
7
use std::{pin::Pin, sync::Arc};
8

9
pub type FindInterface<'t, 'u> =
10
    dyn Fn(
11
        &'u BlobDigest,
12
        Arc<Type>,
13
    ) -> Pin<Box<dyn core::future::Future<Output = Option<Arc<Interface>>> + Send + 't>>;
14

15
async fn type_of_lambda_expression<'t, 'u, 'v, 'w>(
2✔
16
    unchecked: &'w LambdaExpression,
17
    find_variable: &dyn Fn(&Name) -> Option<Type>,
18
    find_interface: &'u FindInterface<'t, 'w>,
19
) -> std::result::Result<Type, TypeCheckingError>
20
where
21
    'w: 't,
22
    'w: 'v,
23
{
24
    let find_lambda_variable = {
2✔
25
        let parameter_type = unchecked.parameter_type.clone();
2✔
26
        let parameter_name = unchecked.parameter_name.clone();
2✔
27
        move |name: &Name| -> Option<Type> {
1✔
28
            if name == &parameter_name {
1✔
29
                let parameter_type = parameter_type.clone();
1✔
30
                Some(parameter_type)
1✔
31
            } else {
32
                find_variable(name)
×
33
            }
34
        }
35
    };
36
    let result_type =
2✔
37
        Box::pin(
38
            async move { type_of(&unchecked.body, &find_lambda_variable, find_interface).await },
8✔
39
        )
40
        .await?;
2✔
41
    Ok(Type::Function(Box::new(Signature::new(
×
42
        unchecked.parameter_type.clone(),
×
43
        result_type,
×
44
    ))))
45
}
46

47
pub async fn type_of<'t, 'u, 'v, 'w>(
14✔
48
    unchecked: &'w Expression,
49
    find_variable: &dyn Fn(&Name) -> Option<Type>,
50
    find_interface: &'u FindInterface<'t, 'w>,
51
) -> std::result::Result<Type, TypeCheckingError>
52
where
53
    'w: 't,
54
    'w: 'v,
55
{
56
    match &unchecked {
14✔
57
        Expression::Unit => Ok(Type::Unit),
4✔
58
        Expression::Literal(literal_type, _blob_digest) => {
3✔
59
            /*TODO: check if the value behind _blob_digest is valid for this type*/
3✔
60
            Ok(literal_type.clone())
3✔
61
        }
62
        Expression::Apply(application) => {
3✔
63
            let callee_type = Arc::new(
64
                Box::pin(type_of(&application.callee, find_variable, find_interface)).await?,
3✔
65
            );
66
            let argument_type = Box::pin(type_of(
3✔
67
                &application.argument,
×
68
                find_variable,
×
69
                find_interface,
×
70
            ))
71
            .await?;
×
72
            let interface =
3✔
73
                match find_interface(&application.callee_interface, callee_type.clone()).await {
×
74
                    Some(found) => found,
3✔
75
                    None => {
×
76
                        return Err(TypeCheckingError {
×
77
                            kind: TypeCheckingErrorKind::CouldNotFindInterface {
×
78
                                callee_interface: application.callee_interface,
×
79
                                callee_type: callee_type,
×
80
                            },
81
                        })
82
                    }
83
                };
84
            let signature = match interface.methods.get(&application.method) {
6✔
85
                Some(found) => found,
3✔
86
                None => todo!(),
87
            };
88
            if is_convertible(&argument_type, &signature.argument) {
3✔
89
                Ok(signature.result.clone())
3✔
90
            } else {
91
                Err(TypeCheckingError {
×
92
                    kind: TypeCheckingErrorKind::NoConversionPossible {
×
93
                        from: argument_type.clone(),
×
94
                        to: signature.argument.clone(),
×
95
                    },
96
                })
97
            }
98
        }
99
        Expression::ReadVariable(name) => match find_variable(name) {
2✔
100
            Some(found) => Ok(found),
2✔
101
            None => Err(TypeCheckingError {
×
102
                kind: TypeCheckingErrorKind::UnknownIdentifier(name.clone()),
×
103
            }),
104
        },
105
        Expression::Lambda(lambda_expression) => {
2✔
106
            type_of_lambda_expression(&lambda_expression, find_variable, find_interface).await
2✔
107
        }
108
    }
109
}
110

111
pub fn is_convertible(from: &Type, into: &Type) -> bool {
9✔
112
    // TODO
113
    from == into
9✔
114
}
115

116
#[derive(Debug, PartialEq)]
117
pub enum TypeCheckingErrorKind {
118
    NoConversionPossible {
119
        from: Type,
120
        to: Type,
121
    },
122
    UnknownIdentifier(Name),
123
    CouldNotFindInterface {
124
        callee_interface: BlobDigest,
125
        callee_type: Arc<Type>,
126
    },
127
}
128

129
#[derive(Debug, PartialEq)]
130
pub struct TypeCheckingError {
131
    pub kind: TypeCheckingErrorKind,
132
}
133

134
#[derive(Debug, PartialEq, PartialOrd, Hash, Clone)]
135
pub struct TypeCheckedExpression {
136
    correct: TypedExpression,
137
}
138

139
impl TypeCheckedExpression {
140
    pub async fn check<'t, 'u, 'v>(
6✔
141
        unchecked: &'v TypedExpression,
142
        find_variable: &dyn Fn(&Name) -> Option<Type>,
143
        find_interface: &'u FindInterface<'t, 'v>,
144
    ) -> std::result::Result<TypeCheckedExpression, TypeCheckingError>
145
    where
146
        'v: 't,
147
    {
148
        let actual_type = type_of(&unchecked.expression, find_variable, find_interface).await?;
12✔
149
        if is_convertible(&actual_type, &unchecked.type_) {
×
150
            Ok(TypeCheckedExpression {
3✔
151
                correct: unchecked.clone(),
3✔
152
            })
153
        } else {
154
            Err(TypeCheckingError {
3✔
155
                kind: TypeCheckingErrorKind::NoConversionPossible {
3✔
156
                    from: actual_type,
3✔
157
                    to: unchecked.type_.clone(),
3✔
158
                },
159
            })
160
        }
161
    }
162

163
    pub fn correct(&self) -> &TypedExpression {
3✔
164
        &self.correct
3✔
165
    }
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc