Implement type checking for cast expressions

This commit is contained in:
Pranav Gaddamadugu 2023-06-23 10:10:10 -04:00
parent c80f9c317c
commit ccb4c0f38f
3 changed files with 35 additions and 0 deletions

View File

@ -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_ {

View File

@ -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 {

View File

@ -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,
}
);