diff --git a/crates/erg_compiler/context/initialize/mod.rs b/crates/erg_compiler/context/initialize/mod.rs index cba74156d..f3ec9aba9 100644 --- a/crates/erg_compiler/context/initialize/mod.rs +++ b/crates/erg_compiler/context/initialize/mod.rs @@ -34,7 +34,8 @@ use crate::ty::constructors::*; use crate::ty::free::Constraint; use crate::ty::value::ValueObj; use crate::ty::{ - BuiltinConstSubr, ConstSubr, GenConstSubr, ParamTy, Predicate, TyParam, Type, Visibility, + BuiltinConstSubr, ClosureData, ConstSubr, GenConstSubr, ParamTy, Predicate, TyParam, Type, + Visibility, }; use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use Mutability::*; @@ -798,28 +799,33 @@ impl Context { .iter() .filter_map(|ps| (!ps.has_default()).then_some(ParamTy::from(ps))) .collect::>(); - let num_nd = nd_params.len(); let d_params = ctx .params_spec .iter() .filter_map(|ps| ps.has_default().then_some(ParamTy::from(ps))) .collect::>(); - let num_d = d_params.len(); - let meta_t = - func(nd_params, None, d_params.clone(), v_enum(set! { ret_val })).quantify(); - let subr = move |args, _ctx: &Context| { + let meta_t = func( + nd_params.clone(), + None, + d_params.clone(), + v_enum(set! { ret_val }), + ) + .quantify(); + let subr = move |data: ClosureData, args, _ctx: &Context| { let passed = Vec::::from(args); - let lack = num_nd + num_d - passed.len(); - let erased = d_params + let lack = data.nd_params.len() + data.d_params.len() - passed.len(); + let erased = data + .d_params .clone() .into_iter() .take(lack) .map(|pt| TyParam::erased(pt.typ().clone())); let params = passed.into_iter().chain(erased).collect::>(); - Ok(ValueObj::builtin_type(poly(qual_name.clone(), params))) + Ok(ValueObj::builtin_type(poly(data.qual_name, params))) }; let subr = ConstSubr::Gen(GenConstSubr::new( t.local_name(), + ClosureData::new(nd_params, d_params, qual_name), subr, meta_t.clone(), Some(t.clone()), diff --git a/crates/erg_compiler/ty/const_subr.rs b/crates/erg_compiler/ty/const_subr.rs index 42928b133..bc1ef6534 100644 --- a/crates/erg_compiler/ty/const_subr.rs +++ b/crates/erg_compiler/ty/const_subr.rs @@ -1,5 +1,4 @@ use std::fmt; -use std::sync::Arc; use erg_common::dict::Dict; #[allow(unused_imports)] @@ -10,7 +9,7 @@ use erg_parser::ast::{Block, ConstBlock, Params}; use super::constructors::subr_t; use super::value::{EvalValueResult, ValueObj}; -use super::{Predicate, TyParam, Type}; +use super::{ParamTy, Predicate, TyParam, Type}; use crate::context::Context; @@ -122,18 +121,33 @@ impl BuiltinConstSubr { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ClosureData { + pub(crate) nd_params: Vec, + pub(crate) d_params: Vec, + pub(crate) qual_name: Str, +} + +impl ClosureData { + pub const fn new(nd_params: Vec, d_params: Vec, qual_name: Str) -> Self { + Self { + nd_params, + d_params, + qual_name, + } + } +} + #[allow(clippy::type_complexity)] #[derive(Clone)] pub struct GenConstSubr { name: Str, - subr: Arc EvalValueResult>, + data: ClosureData, + subr: fn(ClosureData, ValueArgs, &Context) -> EvalValueResult, sig_t: Type, as_type: Option, } -unsafe impl Send for GenConstSubr {} -unsafe impl Sync for GenConstSubr {} - impl std::fmt::Debug for GenConstSubr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("BuiltinConstSubr") @@ -167,20 +181,22 @@ impl fmt::Display for GenConstSubr { impl GenConstSubr { pub fn new>( name: S, - subr: impl Fn(ValueArgs, &Context) -> EvalValueResult + 'static, + data: ClosureData, + subr: fn(ClosureData, ValueArgs, &Context) -> EvalValueResult, sig_t: Type, as_type: Option, ) -> Self { Self { name: name.into(), - subr: Arc::new(subr), + data, + subr, sig_t, as_type, } } pub fn call(&self, args: ValueArgs, ctx: &Context) -> EvalValueResult { - (self.subr)(args, ctx) + (self.subr)(self.data.clone(), args, ctx) } }