mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-28 01:01:53 +03:00
type checking errors so far
This commit is contained in:
parent
1a25db8e23
commit
4612602807
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_errors::TypeCheckerError;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// A binary operator.
|
||||
@ -167,8 +169,10 @@ impl Node for BinaryExpression {
|
||||
match (left, right) {
|
||||
(Some(t1), Some(t2)) if t1 == t2 => Ok(Some(t1)),
|
||||
(None, None) => Ok(None),
|
||||
(Some(t1), Some(t2)) => todo!("throw err"),
|
||||
(None, Some(t)) | (Some(t), None) => todo!("throw err"),
|
||||
(Some(t1), Some(t2)) => Err(TypeCheckerError::types_do_not_match(t1, t2, self.span()).into()),
|
||||
(None, Some(t)) | (Some(t), None) => {
|
||||
Err(TypeCheckerError::type_expected_but_not_found(t, self.span()).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,15 +15,20 @@
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use leo_ast::*;
|
||||
use leo_errors::Result;
|
||||
use leo_errors::{Result, TypeCheckerError};
|
||||
use leo_span::Span;
|
||||
|
||||
use crate::TypeChecker;
|
||||
|
||||
impl<'a> TypeChecker<'a> {
|
||||
fn compare_types(&self, t1: Result<Option<Type>>, t2: Result<Option<Type>>) {
|
||||
fn compare_types(&self, t1: Result<Option<Type>>, t2: Result<Option<Type>>, span: &Span) {
|
||||
match (t1, t2) {
|
||||
(Ok(Some(t1)), Ok(Some(t2))) if t1 != t2 => self.handler.emit_err(todo!()),
|
||||
(Ok(Some(t)), Ok(None)) | (Ok(None), Ok(Some(t))) => self.handler.emit_err(todo!()),
|
||||
(Ok(Some(t1)), Ok(Some(t2))) if t1 != t2 => self
|
||||
.handler
|
||||
.emit_err(TypeCheckerError::types_do_not_match(t1, t2, span).into()),
|
||||
(Ok(Some(t)), Ok(None)) | (Ok(None), Ok(Some(t))) => self
|
||||
.handler
|
||||
.emit_err(TypeCheckerError::type_expected_but_not_found(t, span).into()),
|
||||
(Err(err), Ok(None)) | (Ok(None), Err(err)) => self.handler.emit_err(err),
|
||||
(Err(err1), Err(err2)) => {
|
||||
self.handler.emit_err(err1);
|
||||
@ -43,7 +48,7 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
let parent = self.parent.unwrap();
|
||||
|
||||
if let Some(func) = self.symbol_table.lookup_fn(&parent) {
|
||||
self.compare_types(func.get_type(), input.get_type());
|
||||
self.compare_types(func.get_type(), input.get_type(), input.span());
|
||||
}
|
||||
|
||||
VisitResult::VisitChildren
|
||||
@ -54,6 +59,8 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
if let Err(err) = self.symbol_table.insert_variable(v.identifier.name, input) {
|
||||
self.handler.emit_err(err);
|
||||
}
|
||||
|
||||
self.compare_types(input.get_type(), input.get_type(), input.span());
|
||||
});
|
||||
|
||||
VisitResult::VisitChildren
|
||||
@ -65,12 +72,33 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
||||
|
||||
match (input_var, var) {
|
||||
(Some(var), None) => {
|
||||
self.compare_types(var.get_type(), input.value.get_type());
|
||||
let inner = var.get_variable();
|
||||
if inner.mode() == ParamMode::Constant {
|
||||
self.handler.emit_err(
|
||||
TypeCheckerError::cannont_assign_to_const_input(&inner.identifier.name, var.span()).into(),
|
||||
);
|
||||
}
|
||||
|
||||
self.compare_types(var.get_type(), input.value.get_type(), input.span());
|
||||
}
|
||||
(None, Some(var)) => {
|
||||
self.compare_types(var.get_type(), input.value.get_type());
|
||||
if var.declaration_type == Declare::Const {
|
||||
// there will always be one variable name
|
||||
// as we don't allow tuples at the moment.
|
||||
self.handler.emit_err(
|
||||
TypeCheckerError::cannont_assign_to_const_input(
|
||||
&var.variable_names[0].identifier.name,
|
||||
var.span(),
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
self.compare_types(var.get_type(), input.value.get_type(), input.span());
|
||||
}
|
||||
(None, None) => self.handler.emit_err(todo!()),
|
||||
(None, None) => self
|
||||
.handler
|
||||
.emit_err(TypeCheckerError::unknown_assignee(&input.assignee.identifier.name, input.span()).into()),
|
||||
// Don't have to error here as shadowing checks are done during insertions.
|
||||
_ => {}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ use std::fmt::{Debug, Display};
|
||||
create_messages!(
|
||||
/// InputError enum that represents all the errors for the inputs part of `leo-ast` crate.
|
||||
InputError,
|
||||
code_mask: 8000i32,
|
||||
code_mask: 1000i32,
|
||||
code_prefix: "INP",
|
||||
|
||||
/// For when declared variable type mismatches actual type.
|
||||
|
@ -41,6 +41,10 @@ pub use self::package::*;
|
||||
pub mod parser;
|
||||
pub use self::parser::*;
|
||||
|
||||
/// Contains the Type Checker error definitions.
|
||||
pub mod type_checker;
|
||||
pub use self::type_checker::*;
|
||||
|
||||
/// The LeoError type that contains all sub error types.
|
||||
/// This allows a unified error type throughout the Leo crates.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@ -63,6 +67,9 @@ pub enum LeoError {
|
||||
/// Represents an Parser Error in a Leo Error.
|
||||
#[error(transparent)]
|
||||
ParserError(#[from] ParserError),
|
||||
/// Represents an Type Checker Error in a Leo Error.
|
||||
#[error(transparent)]
|
||||
TypeCheckerError(#[from] TypeCheckerError),
|
||||
}
|
||||
|
||||
impl LeoError {
|
||||
@ -77,6 +84,7 @@ impl LeoError {
|
||||
InputError(error) => error.error_code(),
|
||||
ParserError(error) => error.error_code(),
|
||||
PackageError(error) => error.error_code(),
|
||||
TypeCheckerError(error) => error.error_code(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +99,7 @@ impl LeoError {
|
||||
InputError(error) => error.exit_code(),
|
||||
ParserError(error) => error.exit_code(),
|
||||
PackageError(error) => error.exit_code(),
|
||||
TypeCheckerError(error) => error.exit_code(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
19
leo/errors/src/errors/type_checker/mod.rs
Normal file
19
leo/errors/src/errors/type_checker/mod.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/// This module contains the Input error definitions.
|
||||
pub mod type_checker_error;
|
||||
pub use self::type_checker_error::*;
|
75
leo/errors/src/errors/type_checker/type_checker_error.rs
Normal file
75
leo/errors/src/errors/type_checker/type_checker_error.rs
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::create_messages;
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
create_messages!(
|
||||
/// InputError enum that represents all the errors for the inputs part of `leo-ast` crate.
|
||||
TypeCheckerError,
|
||||
code_mask: 2000i32,
|
||||
code_prefix: "TYC",
|
||||
|
||||
/// For when types do not match.
|
||||
@formatted
|
||||
types_do_not_match {
|
||||
args: (lhs: impl Display, rhs: impl Display),
|
||||
msg: format!(
|
||||
"unexpected type, lhs type is: '{lhs}', but rhs type is: '{rhs}'",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when types do not match.
|
||||
@formatted
|
||||
type_expected_but_not_found {
|
||||
args: (known: impl Display),
|
||||
msg: format!(
|
||||
"One side has type: '{known}', but the other has no type",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when the user tries to assign to a unknown variable.
|
||||
@formatted
|
||||
unknown_assignee {
|
||||
args: (var: impl Display),
|
||||
msg: format!(
|
||||
"Unknown assignee `{var}`",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when the user tries to assign to a const input.
|
||||
@formatted
|
||||
cannont_assign_to_const_input {
|
||||
args: (input: impl Display),
|
||||
msg: format!(
|
||||
"Cannot assign to const input `{input}`",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
|
||||
/// For when the user tries to assign to a const input.
|
||||
@formatted
|
||||
cannont_assign_to_const_var {
|
||||
args: (var: impl Display),
|
||||
msg: format!(
|
||||
"Cannot assign to const variable `{var}`",
|
||||
),
|
||||
help: None,
|
||||
}
|
||||
);
|
Loading…
Reference in New Issue
Block a user