Skip to content

Commit

Permalink
implement ignore_arg_types in the checker
Browse files Browse the repository at this point in the history
  • Loading branch information
bufferhe4d committed Nov 11, 2024
1 parent a992dd6 commit b243dce
Showing 1 changed file with 34 additions and 16 deletions.
50 changes: 34 additions & 16 deletions src/type_checker/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ use serde::{Deserialize, Serialize};

use crate::{
backends::Backend,
cli::packages::UserRepo,
constants::Span,
error::{ErrorKind, Result},
imports::FnKind,
parser::{
types::{
is_numeric, FnSig, ForLoopArgument, FunctionDef, Stmt, StmtKind, Symbolic, Ty, TyKind,
is_numeric, ModulePath, FnSig, ForLoopArgument, FunctionDef, Stmt, StmtKind, Symbolic, Ty, TyKind,
},
CustomType, Expr, ExprKind, Op2,
},
syntax::is_type,
stdlib::builtins::QUALIFIED_BUILTINS,
};

use super::{FullyQualified, TypeChecker, TypeInfo, TypedFnEnv};
Expand All @@ -38,7 +40,7 @@ where
impl<B: Backend> FnInfo<B> {
pub fn sig(&self) -> &FnSig {
match &self.kind {
FnKind::BuiltIn(sig, _) => sig,
FnKind::BuiltIn(sig, _, _) => sig,
FnKind::Native(func) => &func.sig,
}
}
Expand Down Expand Up @@ -833,6 +835,19 @@ impl<B: Backend> TypeChecker<B> {
None => (),
};

// get the ignore_arg_types flag from the function info if it's a builtin
let ignore_arg_types = match self
.fn_info(&FullyQualified::new(
&ModulePath::Absolute(UserRepo::new(QUALIFIED_BUILTINS)),
&fn_sig.name.value,
))
.map(|info| &info.kind)
{
// check builtin
Some(FnKind::BuiltIn(_, _, ignore)) => *ignore,
_ => false,
};

// canonicalize the arguments depending on method call or not
let expected: Vec<_> = if method_call {
fn_sig
Expand Down Expand Up @@ -862,21 +877,24 @@ impl<B: Backend> TypeChecker<B> {
));
}

// compare argument types with the function signature
for (sig_arg, (typ, span)) in expected.iter().zip(observed) {
// when const attribute presented, the argument must be a constant
if sig_arg.is_constant() && !matches!(typ, TyKind::Field { constant: true }) {
return Err(self.error(
ErrorKind::ArgumentTypeMismatch(sig_arg.typ.kind.clone(), typ),
span,
));
}
// skip argument type checking if ignore_arg_types is true
if !ignore_arg_types {
// compare argument types with the function signature
for (sig_arg, (typ, span)) in expected.iter().zip(observed) {
// when const attribute presented, the argument must be a constant
if sig_arg.is_constant() && !matches!(typ, TyKind::Field { constant: true }) {
return Err(self.error(
ErrorKind::ArgumentTypeMismatch(sig_arg.typ.kind.clone(), typ),
span,
));
}

if !typ.match_expected(&sig_arg.typ.kind, false) {
return Err(self.error(
ErrorKind::ArgumentTypeMismatch(sig_arg.typ.kind.clone(), typ),
span,
));
if !typ.match_expected(&sig_arg.typ.kind, false) {
return Err(self.error(
ErrorKind::ArgumentTypeMismatch(sig_arg.typ.kind.clone(), typ),
span,
));
}
}
}

Expand Down

0 comments on commit b243dce

Please sign in to comment.