mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 10:12:21 +03:00
Implement type checking for cast expressions
This commit is contained in:
parent
c80f9c317c
commit
ccb4c0f38f
@ -512,6 +512,20 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_cast(&mut self, input: &'a CastExpression, expected: &Self::AdditionalInput) -> Self::Output {
|
||||
// Check that the target type of the cast expression is a primitive type.
|
||||
if !Self::is_primitive_type(&input.type_) {
|
||||
self.emit_err(TypeCheckerError::cast_must_be_to_primitive(input.span()));
|
||||
}
|
||||
// Check that the expression being casted matches the target type.
|
||||
let target_type = input.type_.clone();
|
||||
let expression_type = self.visit_expression(&input.expression, &None);
|
||||
self.assert_type(&expression_type, &target_type, input.expression.span());
|
||||
|
||||
// Check that the expected type matches the target type.
|
||||
Some(self.assert_and_return_type(target_type, expected, input.span()))
|
||||
}
|
||||
|
||||
fn visit_struct_init(&mut self, input: &'a StructExpression, additional: &Self::AdditionalInput) -> Self::Output {
|
||||
let struct_ = self.symbol_table.borrow().lookup_struct(input.name.name).cloned();
|
||||
if let Some(struct_) = struct_ {
|
||||
|
@ -163,6 +163,20 @@ impl<'a> TypeChecker<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the given type is a primitive type.
|
||||
pub(crate) fn is_primitive_type(type_: &Type) -> bool {
|
||||
match type_ {
|
||||
Type::Address
|
||||
| Type::Boolean
|
||||
| Type::Field
|
||||
| Type::Group
|
||||
| Type::Integer(_)
|
||||
| Type::Scalar
|
||||
| Type::String => true,
|
||||
Type::Identifier(_) | Type::Mapping(_) | Type::Tuple(_) | Type::Unit | Type::Err => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Use this method when you know the actual type.
|
||||
/// Emits an error to the handler if the `actual` type is not equal to the `expected` type.
|
||||
pub(crate) fn assert_and_return_type(&self, actual: Type, expected: &Option<Type>, span: Span) -> Type {
|
||||
|
@ -635,4 +635,11 @@ create_messages!(
|
||||
msg: format!("`{operation}` is not a valid operand in a finalize context."),
|
||||
help: None,
|
||||
}
|
||||
|
||||
@formatted
|
||||
cast_must_be_to_primitive {
|
||||
args: (),
|
||||
msg: format!("A cast must be to a primitive type."),
|
||||
help: None,
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user