From b243dce51ddbb96babf627fd3c1a8b5266d261ab Mon Sep 17 00:00:00 2001 From: Abdullah Talayhan Date: Mon, 11 Nov 2024 17:40:32 +0100 Subject: [PATCH] implement ignore_arg_types in the checker --- src/type_checker/checker.rs | 50 +++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/type_checker/checker.rs b/src/type_checker/checker.rs index cf8dda009..1929f5385 100644 --- a/src/type_checker/checker.rs +++ b/src/type_checker/checker.rs @@ -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}; @@ -38,7 +40,7 @@ where impl FnInfo { pub fn sig(&self) -> &FnSig { match &self.kind { - FnKind::BuiltIn(sig, _) => sig, + FnKind::BuiltIn(sig, _, _) => sig, FnKind::Native(func) => &func.sig, } } @@ -833,6 +835,19 @@ impl TypeChecker { 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 @@ -862,21 +877,24 @@ impl TypeChecker { )); } - // 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, + )); + } } }