erg_compiler/context/
register.rs

1use std::option::Option;
2use std::path::{Path, PathBuf};
3
4use erg_common::consts::{ERG_MODE, PYTHON_MODE};
5use erg_common::dict::Dict;
6use erg_common::env::is_pystd_main_module;
7use erg_common::erg_util::BUILTIN_ERG_MODS;
8use erg_common::levenshtein::get_similar_name;
9use erg_common::pathutil::{DirKind, FileKind, NormalizedPathBuf};
10use erg_common::python_util::BUILTIN_PYTHON_MODS;
11use erg_common::set::Set;
12use erg_common::traits::{Locational, Stream, StructuralEq};
13use erg_common::triple::Triple;
14use erg_common::{get_hash, log, set, unique_in_place, Str};
15
16use ast::{
17    ConstIdentifier, Decorator, DefId, Identifier, OperationKind, PolyTypeSpec, PreDeclTypeSpec,
18    VarName,
19};
20use erg_parser::ast::{self, ClassAttr, RecordAttrOrIdent, TypeSpecWithOp};
21
22use crate::ty::constructors::{
23    func, func0, func1, module, proc, py_module, ref_, ref_mut, str_dict_t, tp_enum,
24    unknown_len_list_t, v_enum,
25};
26use crate::ty::free::HasLevel;
27use crate::ty::typaram::TyParam;
28use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
29use crate::ty::{
30    CastTarget, Field, GuardType, HasType, ParamTy, SubrType, Type, Visibility, VisibilityModifier,
31};
32
33use crate::context::{ClassDefType, Context, ContextKind, DefaultInfo, RegistrationMode};
34use crate::error::{concat_result, readable_name, Failable};
35use crate::error::{
36    CompileError, CompileErrors, CompileResult, TyCheckError, TyCheckErrors, TyCheckResult,
37};
38use crate::hir::Literal;
39use crate::varinfo::{AbsLocation, AliasInfo, Mutability, VarInfo, VarKind};
40use crate::{feature_error, hir, unreachable_error};
41use Mutability::*;
42use RegistrationMode::*;
43
44use super::eval::Substituter;
45use super::instantiate::TyVarCache;
46use super::instantiate_spec::ParamKind;
47use super::{ControlKind, MethodContext, ParamSpec, TraitImpl, TypeContext};
48
49type ClassTrait<'c> = (Type, Option<(Type, &'c TypeSpecWithOp)>);
50type ClassTraitErrors<'c> = (
51    Option<Type>,
52    Option<(Type, &'c TypeSpecWithOp)>,
53    TyCheckErrors,
54);
55
56pub fn valid_mod_name(name: &str) -> bool {
57    !name.is_empty() && !name.starts_with('/') && name.trim() == name
58}
59
60const UBAR: &Str = &Str::ever("_");
61
62impl Context {
63    /// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
64    pub(crate) fn registered_info(
65        &self,
66        name: &str,
67        is_const: bool,
68    ) -> Option<(&VarName, &VarInfo)> {
69        if let Some((name, vi)) = self.params.iter().find(|(maybe_name, _)| {
70            maybe_name
71                .as_ref()
72                .map(|n| &n.inspect()[..] == name)
73                .unwrap_or(false)
74        }) {
75            return Some((name.as_ref().unwrap(), vi));
76        } else if let Some((name, vi)) = self.locals.get_key_value(name) {
77            return Some((name, vi));
78        }
79        if is_const {
80            let outer = self.get_outer_scope_or_builtins()?;
81            outer.registered_info(name, is_const)
82        } else {
83            None
84        }
85    }
86
87    fn declare_var(&mut self, ident: &Identifier, t_spec: &TypeSpecWithOp) -> Failable<()> {
88        if self.decls.get(&ident.name).is_some()
89            || self
90                .future_defined_locals
91                .get(&ident.name)
92                .is_some_and(|future| future.def_loc.loc < ident.loc())
93        {
94            return Ok(());
95        }
96        let mut errs = TyCheckErrors::empty();
97        let vis = match self.instantiate_vis_modifier(&ident.vis) {
98            Ok(vis) => vis,
99            Err(es) => {
100                errs.extend(es);
101                VisibilityModifier::Public
102            }
103        };
104        let kind = VarKind::Declared;
105        let sig_t = match self.instantiate_var_sig_t(Some(&t_spec.t_spec), PreRegister) {
106            Ok(t) => t,
107            Err((t, _es)) => {
108                // errs.extend(es);
109                t
110            }
111        };
112        let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind {
113            Some(Str::from(format!("::{}{}", self.name, ident)))
114        } else {
115            None
116        };
117        let vi = VarInfo::new(
118            sig_t,
119            Mutability::from(&ident.inspect()[..]),
120            Visibility::new(vis, self.name.clone()),
121            kind,
122            None,
123            self.kind.clone(),
124            py_name,
125            self.absolutize(ident.name.loc()),
126        );
127        // self.index().register(ident.inspect().clone(), &vi);
128        self.decls.insert(ident.name.clone(), vi);
129        if errs.is_empty() {
130            Ok(())
131        } else {
132            Err(((), errs))
133        }
134    }
135
136    fn pre_define_var(&mut self, sig: &ast::VarSignature, id: Option<DefId>) -> Failable<()> {
137        let mut errs = TyCheckErrors::empty();
138        let muty = Mutability::from(&sig.inspect().unwrap_or(UBAR)[..]);
139        let ident = match &sig.pat {
140            ast::VarPattern::Ident(ident) | ast::VarPattern::Phi(ident) => ident,
141            ast::VarPattern::Discard(_) | ast::VarPattern::Glob(_) => {
142                return Ok(());
143            }
144            other => unreachable!("{other}"),
145        };
146        let vis = match self.instantiate_vis_modifier(&ident.vis) {
147            Ok(vis) => vis,
148            Err(es) => {
149                errs.extend(es);
150                VisibilityModifier::Public
151            }
152        };
153        let kind = id.map_or(VarKind::Declared, VarKind::Defined);
154        let sig_t = match self
155            .instantiate_var_sig_t(sig.t_spec.as_ref().map(|ts| &ts.t_spec), PreRegister)
156        {
157            Ok(t) => t,
158            Err((t, _es)) => {
159                // errs.extend(es);
160                t
161            }
162        };
163        let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind {
164            Some(Str::from(format!("::{}{}", self.name, ident)))
165        } else {
166            None
167        };
168        if self.decls.get(&ident.name).is_some() {
169            let vi = VarInfo::new(
170                sig_t,
171                muty,
172                Visibility::new(vis, self.name.clone()),
173                kind,
174                None,
175                self.kind.clone(),
176                py_name,
177                self.absolutize(ident.name.loc()),
178            );
179            self.index().register(ident.inspect().clone(), &vi);
180            return Ok(());
181        }
182        // don't remove at this point
183        if self
184            .get_class_attr(ident.name.inspect())
185            .is_some_and(|(_, decl)| !decl.kind.is_auto())
186        {
187            errs.push(TyCheckError::duplicate_decl_error(
188                self.cfg.input.clone(),
189                line!() as usize,
190                sig.loc(),
191                self.caused_by(),
192                ident.name.inspect(),
193            ));
194            Err(((), errs))
195        } else {
196            let vi = VarInfo::new(
197                sig_t,
198                muty,
199                Visibility::new(vis, self.name.clone()),
200                kind,
201                None,
202                self.kind.clone(),
203                py_name,
204                self.absolutize(ident.name.loc()),
205            );
206            self.index().register(ident.inspect().clone(), &vi);
207            self.future_defined_locals.insert(ident.name.clone(), vi);
208            if errs.is_empty() {
209                Ok(())
210            } else {
211                Err(((), errs))
212            }
213        }
214    }
215
216    pub(crate) fn declare_sub(
217        &mut self,
218        sig: &ast::SubrSignature,
219        id: Option<DefId>,
220    ) -> TyCheckResult<()> {
221        let name = sig.ident.inspect();
222        let vis = self.instantiate_vis_modifier(&sig.ident.vis)?;
223        let muty = Mutability::from(&name[..]);
224        let kind = id.map_or(VarKind::Declared, VarKind::Defined);
225        let comptime_decos = sig
226            .decorators
227            .iter()
228            .filter_map(|deco| match &deco.0 {
229                ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
230                    Some(local.inspect().clone())
231                }
232                _ => None,
233            })
234            .collect::<Set<_>>();
235        let (errs, t) = match self.instantiate_sub_sig_t(sig, PreRegister) {
236            Ok(t) => (TyCheckErrors::empty(), t),
237            Err((t, errs)) => (errs, t),
238        };
239        let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind {
240            Some(Str::from(format!("::{}{}", self.name, sig.ident)))
241        } else {
242            None
243        };
244        let vi = VarInfo::new(
245            t,
246            muty,
247            Visibility::new(vis, self.name.clone()),
248            kind,
249            Some(comptime_decos),
250            self.kind.clone(),
251            py_name,
252            self.absolutize(sig.ident.name.loc()),
253        );
254        self.index().register(sig.ident.inspect().clone(), &vi);
255        self.decls.remove(name);
256        if self
257            .remove_class_attr(name)
258            .is_some_and(|(_, decl)| !decl.kind.is_auto())
259        {
260            Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error(
261                self.cfg.input.clone(),
262                line!() as usize,
263                sig.loc(),
264                self.caused_by(),
265                name,
266            )))
267        } else {
268            self.decls.insert(sig.ident.name.clone(), vi);
269            if errs.is_empty() {
270                Ok(())
271            } else {
272                Err(errs)
273            }
274        }
275    }
276
277    /// already validated
278    pub(crate) fn assign_var_sig(
279        &mut self,
280        sig: &ast::VarSignature,
281        body_t: &Type,
282        id: DefId,
283        expr: Option<&hir::Expr>,
284        py_name: Option<Str>,
285    ) -> TyCheckResult<VarInfo> {
286        let alias_of = if let Some((origin, name)) =
287            expr.and_then(|exp| exp.var_info().zip(exp.last_name()))
288        {
289            Some(AliasInfo::new(
290                name.inspect().clone(),
291                origin.def_loc.clone(),
292            ))
293        } else {
294            None
295        };
296        let ident = match &sig.pat {
297            ast::VarPattern::Ident(ident) | ast::VarPattern::Phi(ident) => ident,
298            ast::VarPattern::Discard(_) => {
299                return Ok(VarInfo {
300                    t: body_t.clone(),
301                    ctx: self.kind.clone(),
302                    def_loc: self.absolutize(sig.loc()),
303                    py_name,
304                    alias_of: alias_of.map(Box::new),
305                    ..VarInfo::const_default_private()
306                });
307            }
308            _ => unreachable!(),
309        };
310        if let Some(py_name) = &py_name {
311            self.erg_to_py_names
312                .insert(ident.inspect().clone(), py_name.clone());
313        }
314        let ident = if PYTHON_MODE && py_name.is_some() {
315            let mut symbol = ident.name.clone().into_token();
316            symbol.content = py_name.clone().unwrap();
317            Identifier::new(ident.vis.clone(), VarName::new(symbol))
318        } else {
319            ident.clone()
320        };
321        let vis = self.instantiate_vis_modifier(&ident.vis)?;
322        // already defined as const
323        if sig.is_const() {
324            let mut vi = self.decls.remove(ident.inspect()).unwrap_or_else(|| {
325                VarInfo::new(
326                    body_t.clone(),
327                    Mutability::Const,
328                    Visibility::new(vis, self.name.clone()),
329                    VarKind::Declared,
330                    None,
331                    self.kind.clone(),
332                    py_name.clone(),
333                    self.absolutize(ident.name.loc()),
334                )
335            });
336            if vi.py_name.is_none() {
337                vi.py_name = py_name;
338            }
339            if vi.alias_of.is_none() {
340                vi.alias_of = alias_of.map(Box::new);
341            }
342            self.locals.insert(ident.name.clone(), vi.clone());
343            if let Ok(value) = self.convert_singular_type_into_value(vi.t.clone()) {
344                self.consts.insert(ident.name.clone(), value);
345            }
346            return Ok(vi);
347        }
348        let muty = Mutability::from(&ident.inspect()[..]);
349        let opt_vi = self
350            .decls
351            .remove(ident.inspect())
352            .or_else(|| self.future_defined_locals.remove(ident.inspect()));
353        let py_name = opt_vi
354            .as_ref()
355            .and_then(|vi| vi.py_name.clone())
356            .or(py_name);
357        let kind = if id.0 == 0 {
358            VarKind::Declared
359        } else {
360            VarKind::Defined(id)
361        };
362        let t = sig.t_spec.as_ref().map_or(body_t.clone(), |ts| {
363            if ts.ascription_kind().is_force_cast() {
364                match self.instantiate_typespec(&ts.t_spec) {
365                    Ok(t) => t,
366                    Err((t, _)) => t,
367                }
368            } else {
369                body_t.clone()
370            }
371        });
372        let vi = VarInfo::maybe_alias(
373            t,
374            muty,
375            Visibility::new(vis, self.name.clone()),
376            kind,
377            None,
378            self.kind.clone(),
379            py_name,
380            self.absolutize(ident.name.loc()),
381            alias_of,
382        );
383        log!(info "Registered {}{}: {}", self.name, ident, vi);
384        self.locals.insert(ident.name.clone(), vi.clone());
385        if let Ok(value) = self.convert_singular_type_into_value(vi.t.clone()) {
386            self.consts.insert(ident.name.clone(), value);
387        }
388        Ok(vi)
389    }
390
391    fn type_self_param(
392        &self,
393        pat: &ast::ParamPattern,
394        name: &VarName,
395        spec_t: &Type,
396        sig_t: Option<&SubrType>,
397        errs: &mut TyCheckErrors,
398    ) {
399        if let Some(self_t) = self.rec_get_self_t() {
400            let self_t = match pat {
401                ast::ParamPattern::Ref(_) => ref_(self_t),
402                ast::ParamPattern::RefMut(_) => ref_mut(self_t, None),
403                _ => self_t,
404            };
405            // spec_t <: self_t
406            if let Err(es) = self.sub_unify(spec_t, &self_t, name, Some(name.inspect())) {
407                errs.extend(es);
408            }
409            if let Some(sig_t) = sig_t {
410                if sig_t.return_t.has_no_unbound_var() && !sig_t.return_t.contains_type(spec_t) {
411                    // spec_t == self_t
412                    if let Err(es) = self.sub_unify(&self_t, spec_t, name, Some(name.inspect())) {
413                        errs.extend(es);
414                    }
415                }
416            }
417        } else {
418            log!(err "self_t is None");
419        }
420    }
421
422    /// TODO: sig should be immutable
423    /// 宣言が既にある場合、opt_decl_tに宣言の型を渡す
424    fn assign_param(
425        &mut self,
426        sig: &mut hir::NonDefaultParamSignature,
427        opt_decl_t: Option<&ParamTy>,
428        sig_t: Option<&SubrType>,
429        tmp_tv_cache: &mut TyVarCache,
430        kind: ParamKind,
431    ) -> TyCheckResult<()> {
432        let vis = if PYTHON_MODE {
433            Visibility::BUILTIN_PUBLIC
434        } else {
435            Visibility::private(self.name.clone())
436        };
437        let default = kind.default_info();
438        let is_var_params = kind.is_var_params() || kind.is_kw_var_params();
439        match &sig.raw.pat {
440            // Literal patterns will be desugared to discard patterns
441            ast::ParamPattern::Lit(_) => unreachable!(),
442            ast::ParamPattern::Discard(token) => {
443                let (spec_t, errs) = match self.instantiate_param_sig_t(
444                    &sig.raw,
445                    opt_decl_t,
446                    tmp_tv_cache,
447                    Normal,
448                    kind,
449                    false,
450                ) {
451                    Ok(ty) => (ty, TyCheckErrors::empty()),
452                    Err((ty, errs)) => (ty, errs),
453                };
454                let def_id = DefId(get_hash(&(&self.name, "_")));
455                let kind = VarKind::parameter(def_id, is_var_params, DefaultInfo::NonDefault);
456                let vi = VarInfo::new(
457                    spec_t,
458                    Immutable,
459                    vis,
460                    kind,
461                    None,
462                    self.kind.clone(),
463                    None,
464                    self.absolutize(token.loc()),
465                );
466                sig.vi = vi.clone();
467                self.params.push((Some(VarName::from_static("_")), vi));
468                if errs.is_empty() {
469                    Ok(())
470                } else {
471                    Err(errs)
472                }
473            }
474            ast::ParamPattern::VarName(name) => {
475                if self
476                    .registered_info(name.inspect(), name.is_const())
477                    .is_some()
478                    && &name.inspect()[..] != "_"
479                {
480                    Err(TyCheckErrors::from(TyCheckError::reassign_error(
481                        self.cfg.input.clone(),
482                        line!() as usize,
483                        name.loc(),
484                        self.caused_by(),
485                        name.inspect(),
486                    )))
487                } else {
488                    // ok, not defined
489                    let (spec_t, mut errs) = match self.instantiate_param_sig_t(
490                        &sig.raw,
491                        opt_decl_t,
492                        tmp_tv_cache,
493                        Normal,
494                        kind.clone(),
495                        false,
496                    ) {
497                        Ok(ty) => (ty, TyCheckErrors::empty()),
498                        Err((ty, errs)) => (ty, errs),
499                    };
500                    let spec_t = match kind {
501                        ParamKind::VarParams => unknown_len_list_t(spec_t),
502                        ParamKind::KwVarParams => str_dict_t(spec_t),
503                        _ => spec_t,
504                    };
505                    if &name.inspect()[..] == "self" {
506                        self.type_self_param(&sig.raw.pat, name, &spec_t, sig_t, &mut errs);
507                    }
508                    let def_id = DefId(get_hash(&(&self.name, name)));
509                    let kind = VarKind::parameter(def_id, is_var_params, default);
510                    let muty = Mutability::from(&name.inspect()[..]);
511                    let vi = VarInfo::new(
512                        spec_t,
513                        muty,
514                        vis,
515                        kind,
516                        None,
517                        self.kind.clone(),
518                        None,
519                        self.absolutize(name.loc()),
520                    );
521                    self.index().register(name.inspect().clone(), &vi);
522                    sig.vi = vi.clone();
523                    self.params.push((Some(name.clone()), vi));
524                    if errs.is_empty() {
525                        Ok(())
526                    } else {
527                        Err(errs)
528                    }
529                }
530            }
531            ast::ParamPattern::Ref(name) => {
532                if self
533                    .registered_info(name.inspect(), name.is_const())
534                    .is_some()
535                {
536                    Err(TyCheckErrors::from(TyCheckError::reassign_error(
537                        self.cfg.input.clone(),
538                        line!() as usize,
539                        name.loc(),
540                        self.caused_by(),
541                        name.inspect(),
542                    )))
543                } else {
544                    // ok, not defined
545                    let (spec_t, mut errs) = match self.instantiate_param_sig_t(
546                        &sig.raw,
547                        opt_decl_t,
548                        tmp_tv_cache,
549                        Normal,
550                        kind,
551                        false,
552                    ) {
553                        Ok(ty @ Type::Ref(_)) => (ty, TyCheckErrors::empty()),
554                        Ok(ty) => (ty.into_ref(), TyCheckErrors::empty()),
555                        Err((ty, errs)) => (ty, errs),
556                    };
557                    if &name.inspect()[..] == "self" {
558                        self.type_self_param(&sig.raw.pat, name, &spec_t, sig_t, &mut errs);
559                    }
560                    let kind = VarKind::parameter(
561                        DefId(get_hash(&(&self.name, name))),
562                        is_var_params,
563                        default,
564                    );
565                    let vi = VarInfo::new(
566                        spec_t,
567                        Immutable,
568                        vis,
569                        kind,
570                        None,
571                        self.kind.clone(),
572                        None,
573                        self.absolutize(name.loc()),
574                    );
575                    sig.vi = vi.clone();
576                    self.params.push((Some(name.clone()), vi));
577                    if errs.is_empty() {
578                        Ok(())
579                    } else {
580                        Err(errs)
581                    }
582                }
583            }
584            ast::ParamPattern::RefMut(name) => {
585                if self
586                    .registered_info(name.inspect(), name.is_const())
587                    .is_some()
588                {
589                    Err(TyCheckErrors::from(TyCheckError::reassign_error(
590                        self.cfg.input.clone(),
591                        line!() as usize,
592                        name.loc(),
593                        self.caused_by(),
594                        name.inspect(),
595                    )))
596                } else {
597                    // ok, not defined
598                    let (spec_t, mut errs) = match self.instantiate_param_sig_t(
599                        &sig.raw,
600                        opt_decl_t,
601                        tmp_tv_cache,
602                        Normal,
603                        kind,
604                        false,
605                    ) {
606                        Ok(ty @ Type::RefMut { .. }) => (ty, TyCheckErrors::empty()),
607                        Ok(ty) => (ty.into_ref_mut(None), TyCheckErrors::empty()),
608                        Err((ty, errs)) => (ty, errs),
609                    };
610                    if &name.inspect()[..] == "self" {
611                        self.type_self_param(&sig.raw.pat, name, &spec_t, sig_t, &mut errs);
612                    }
613                    let kind = VarKind::parameter(
614                        DefId(get_hash(&(&self.name, name))),
615                        is_var_params,
616                        default,
617                    );
618                    let vi = VarInfo::new(
619                        spec_t,
620                        Immutable,
621                        vis,
622                        kind,
623                        None,
624                        self.kind.clone(),
625                        None,
626                        self.absolutize(name.loc()),
627                    );
628                    sig.vi = vi.clone();
629                    self.params.push((Some(name.clone()), vi));
630                    if errs.is_empty() {
631                        Ok(())
632                    } else {
633                        Err(errs)
634                    }
635                }
636            }
637            other => {
638                log!(err "{other}");
639                unreachable!("{other}")
640            }
641        }
642    }
643
644    pub(crate) fn assign_params(
645        &mut self,
646        params: &mut hir::Params,
647        tmp_tv_cache: &mut TyVarCache,
648        expect: Option<SubrType>,
649    ) -> TyCheckResult<()> {
650        let mut errs = TyCheckErrors::empty();
651        if let Some(subr_t) = expect {
652            if params.non_defaults.len() > subr_t.non_default_params.len() {
653                let excessive_params = params
654                    .non_defaults
655                    .iter()
656                    .skip(subr_t.non_default_params.len())
657                    .collect::<Vec<_>>();
658                errs.push(TyCheckError::too_many_args_error(
659                    self.cfg.input.clone(),
660                    line!() as usize,
661                    excessive_params.loc(),
662                    "<lambda>", // TODO:
663                    self.caused_by(),
664                    subr_t.non_default_params.len(),
665                    params.non_defaults.len(),
666                    params.defaults.len(),
667                ));
668            }
669            // debug_assert_eq!(params.defaults.len(), subr_t.default_params.len());
670            for (non_default, pt) in params
671                .non_defaults
672                .iter_mut()
673                .zip(subr_t.non_default_params.iter())
674            {
675                if let Err(es) = self.assign_param(
676                    non_default,
677                    Some(pt),
678                    Some(&subr_t),
679                    tmp_tv_cache,
680                    ParamKind::NonDefault,
681                ) {
682                    errs.extend(es);
683                }
684            }
685            if let Some(var_params) = &mut params.var_params {
686                if let Some(pt) = &subr_t.var_params {
687                    let pt = pt.clone().map_type(&mut unknown_len_list_t);
688                    if let Err(es) = self.assign_param(
689                        var_params,
690                        Some(&pt),
691                        Some(&subr_t),
692                        tmp_tv_cache,
693                        ParamKind::VarParams,
694                    ) {
695                        errs.extend(es);
696                    }
697                } else if let Err(es) = self.assign_param(
698                    var_params,
699                    None,
700                    Some(&subr_t),
701                    tmp_tv_cache,
702                    ParamKind::VarParams,
703                ) {
704                    errs.extend(es);
705                }
706            }
707            for (default, pt) in params.defaults.iter_mut().zip(subr_t.default_params.iter()) {
708                if let Err(es) = self.assign_param(
709                    &mut default.sig,
710                    Some(pt),
711                    Some(&subr_t),
712                    tmp_tv_cache,
713                    ParamKind::Default(default.default_val.t()),
714                ) {
715                    errs.extend(es);
716                }
717            }
718            if let Some(kw_var_params) = &mut params.kw_var_params {
719                if let Some(pt) = &subr_t.kw_var_params {
720                    let pt = pt.clone().map_type(&mut str_dict_t);
721                    if let Err(es) = self.assign_param(
722                        kw_var_params,
723                        Some(&pt),
724                        Some(&subr_t),
725                        tmp_tv_cache,
726                        ParamKind::KwVarParams,
727                    ) {
728                        errs.extend(es);
729                    }
730                } else if let Err(es) = self.assign_param(
731                    kw_var_params,
732                    None,
733                    Some(&subr_t),
734                    tmp_tv_cache,
735                    ParamKind::KwVarParams,
736                ) {
737                    errs.extend(es);
738                }
739            }
740        } else {
741            for non_default in params.non_defaults.iter_mut() {
742                if let Err(es) =
743                    self.assign_param(non_default, None, None, tmp_tv_cache, ParamKind::NonDefault)
744                {
745                    errs.extend(es);
746                }
747            }
748            if let Some(var_params) = &mut params.var_params {
749                if let Err(es) =
750                    self.assign_param(var_params, None, None, tmp_tv_cache, ParamKind::VarParams)
751                {
752                    errs.extend(es);
753                }
754            }
755            for default in params.defaults.iter_mut() {
756                if let Err(es) = self.assign_param(
757                    &mut default.sig,
758                    None,
759                    None,
760                    tmp_tv_cache,
761                    ParamKind::Default(default.default_val.t()),
762                ) {
763                    errs.extend(es);
764                }
765            }
766            if let Some(kw_var_params) = &mut params.kw_var_params {
767                if let Err(es) = self.assign_param(
768                    kw_var_params,
769                    None,
770                    None,
771                    tmp_tv_cache,
772                    ParamKind::KwVarParams,
773                ) {
774                    errs.extend(es);
775                }
776            }
777        }
778        if errs.is_empty() {
779            Ok(())
780        } else {
781            Err(errs)
782        }
783    }
784
785    fn unify_params_t(
786        &self,
787        sig: &ast::SubrSignature,
788        registered_t: &SubrType,
789        params: &hir::Params,
790        body_t: &Type,
791        body_loc: &impl Locational,
792    ) -> TyCheckResult<()> {
793        let name = &sig.ident.name;
794        let mut errs = TyCheckErrors::empty();
795        for (param, pt) in params
796            .non_defaults
797            .iter()
798            .zip(registered_t.non_default_params.iter())
799        {
800            pt.typ().lower();
801            if let Err(es) = self.force_sub_unify(&param.vi.t, pt.typ(), param, None) {
802                errs.extend(es);
803            }
804            pt.typ().lift();
805        }
806        // TODO: var_params: [Int; _], pt: Int
807        /*if let Some((var_params, pt)) = params.var_params.as_deref().zip(registered_t.var_params.as_ref()) {
808            pt.typ().lower();
809            if let Err(es) = self.force_sub_unify(&var_params.vi.t, pt.typ(), var_params, None) {
810                errs.extend(es);
811            }
812            pt.typ().lift();
813        }*/
814        for (param, pt) in params
815            .defaults
816            .iter()
817            .zip(registered_t.default_params.iter())
818        {
819            pt.typ().lower();
820            if let Err(es) = self.force_sub_unify(&param.sig.vi.t, pt.typ(), param, None) {
821                errs.extend(es);
822            }
823            pt.typ().lift();
824        }
825        let spec_ret_t = registered_t.return_t.as_ref();
826        // spec_ret_t.lower();
827        let unify_return_result = if let Some(t_spec) = sig.return_t_spec.as_deref() {
828            self.force_sub_unify(body_t, spec_ret_t, t_spec, None)
829        } else {
830            self.force_sub_unify(body_t, spec_ret_t, body_loc, None)
831        };
832        // spec_ret_t.lift();
833        if let Err(unify_errs) = unify_return_result {
834            let es = TyCheckErrors::new(
835                unify_errs
836                    .into_iter()
837                    .map(|e| {
838                        let expect = if cfg!(feature = "debug") {
839                            spec_ret_t.clone()
840                        } else {
841                            self.readable_type(spec_ret_t.clone())
842                        };
843                        let found = if cfg!(feature = "debug") {
844                            body_t.clone()
845                        } else {
846                            self.readable_type(body_t.clone())
847                        };
848                        TyCheckError::return_type_error(
849                            self.cfg.input.clone(),
850                            line!() as usize,
851                            e.core.get_loc_with_fallback(),
852                            e.caused_by,
853                            readable_name(name.inspect()),
854                            &expect,
855                            &found,
856                            // e.core.get_hint().map(|s| s.to_string()),
857                        )
858                    })
859                    .collect(),
860            );
861            errs.extend(es);
862        }
863        if errs.is_empty() {
864            Ok(())
865        } else {
866            Err(errs)
867        }
868    }
869
870    /// ## Errors
871    /// * TypeError: if `return_t` != typeof `body`
872    /// * AssignError: if `name` has already been registered
873    pub(crate) fn assign_subr(
874        &mut self,
875        sig: &ast::SubrSignature,
876        id: DefId,
877        params: &hir::Params,
878        body_t: &Type,
879        body_loc: &impl Locational,
880    ) -> Result<VarInfo, (TyCheckErrors, VarInfo)> {
881        let mut errs = TyCheckErrors::empty();
882        // already defined as const
883        if sig.ident.is_const() {
884            let vi = self.decls.remove(sig.ident.inspect()).unwrap();
885            self.locals.insert(sig.ident.name.clone(), vi.clone());
886            return Ok(vi);
887        }
888        let vis = match self.instantiate_vis_modifier(&sig.ident.vis) {
889            Ok(vis) => vis,
890            Err(es) => {
891                errs.extend(es);
892                VisibilityModifier::Private
893            }
894        };
895        let muty = if sig.ident.is_const() {
896            Mutability::Const
897        } else {
898            Mutability::Immutable
899        };
900        let name = &sig.ident.name;
901        // FIXME: constでない関数
902        let Some(subr_t) = self.get_current_scope_var(name).map(|vi| &vi.t) else {
903            let err = unreachable_error!(TyCheckErrors, TyCheckError, self);
904            return err.map_err(|e| (e, VarInfo::ILLEGAL));
905        };
906        let Ok(subr_t) = <&SubrType>::try_from(subr_t) else {
907            let err = unreachable_error!(TyCheckErrors, TyCheckError, self);
908            return err.map_err(|e| (e, VarInfo::ILLEGAL));
909        };
910        if let Err(es) = self.unify_params_t(sig, subr_t, params, body_t, body_loc) {
911            errs.extend(es);
912        }
913        // NOTE: not `body_t.clone()` because the body may contain `return`
914        let return_t = subr_t.return_t.as_ref().clone();
915        let sub_t = if sig.ident.is_procedural() {
916            proc(
917                subr_t.non_default_params.clone(),
918                subr_t.var_params.as_deref().cloned(),
919                subr_t.default_params.clone(),
920                subr_t.kw_var_params.as_deref().cloned(),
921                return_t,
922            )
923        } else {
924            func(
925                subr_t.non_default_params.clone(),
926                subr_t.var_params.as_deref().cloned(),
927                subr_t.default_params.clone(),
928                subr_t.kw_var_params.as_deref().cloned(),
929                return_t,
930            )
931        };
932        sub_t.lift();
933        let found_t = self.generalize_t(sub_t);
934        // let found_t = self.eliminate_needless_quant(found_t, crate::context::Variance::Covariant, sig)?;
935        let py_name = if let Some(vi) = self.decls.remove(name) {
936            if !self.supertype_of(&vi.t, &found_t) {
937                let err = TyCheckError::violate_decl_error(
938                    self.cfg.input.clone(),
939                    line!() as usize,
940                    sig.ident.loc(),
941                    self.caused_by(),
942                    name.inspect(),
943                    &vi.t,
944                    &found_t,
945                );
946                errs.push(err);
947            }
948            vi.py_name
949        } else {
950            None
951        };
952        let comptime_decos = sig
953            .decorators
954            .iter()
955            .filter_map(|deco| match &deco.0 {
956                ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
957                    Some(local.inspect().clone())
958                }
959                _ => None,
960            })
961            .collect();
962        let vi = VarInfo::new(
963            found_t,
964            muty,
965            Visibility::new(vis, self.name.clone()),
966            VarKind::Defined(id),
967            Some(comptime_decos),
968            self.kind.clone(),
969            py_name,
970            self.absolutize(name.loc()),
971        );
972        let vis = if vi.vis.is_private() { "::" } else { "." };
973        log!(info "Registered {}{}{name}: {}", self.name, vis, &vi.t);
974        self.locals.insert(name.clone(), vi.clone());
975        if errs.is_empty() {
976            Ok(vi)
977        } else {
978            Err((errs, vi))
979        }
980    }
981
982    pub(crate) fn fake_subr_assign(
983        &mut self,
984        ident: &Identifier,
985        decorators: &Set<Decorator>,
986        failure_t: Type,
987    ) -> TyCheckResult<()> {
988        // already defined as const
989        if ident.is_const() {
990            if let Some(vi) = self.decls.remove(ident.inspect()) {
991                self.locals.insert(ident.name.clone(), vi);
992            } else {
993                log!(err "not found: {}", ident.name);
994                return Ok(());
995            }
996        }
997        let vis = self.instantiate_vis_modifier(&ident.vis)?;
998        let muty = if ident.is_const() {
999            Mutability::Const
1000        } else {
1001            Mutability::Immutable
1002        };
1003        let name = &ident.name;
1004        self.decls.remove(name);
1005        let comptime_decos = decorators
1006            .iter()
1007            .filter_map(|deco| match &deco.0 {
1008                ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
1009                    Some(local.inspect().clone())
1010                }
1011                _ => None,
1012            })
1013            .collect();
1014        let vi = VarInfo::new(
1015            failure_t,
1016            muty,
1017            Visibility::new(vis, self.name.clone()),
1018            VarKind::DoesNotExist,
1019            Some(comptime_decos),
1020            self.kind.clone(),
1021            None,
1022            self.absolutize(name.loc()),
1023        );
1024        log!(info "Registered {}::{name}: {}", self.name, &vi.t);
1025        self.locals.insert(name.clone(), vi);
1026        Ok(())
1027    }
1028
1029    pub(crate) fn get_class_and_impl_trait<'c>(
1030        &mut self,
1031        class_spec: &'c ast::TypeSpec,
1032    ) -> Result<ClassTrait<'c>, ClassTraitErrors<'c>> {
1033        let mut errs = TyCheckErrors::empty();
1034        let mut dummy_tv_cache = TyVarCache::new(self.level, self);
1035        match class_spec {
1036            ast::TypeSpec::TypeApp { spec, args } => {
1037                match &args.args {
1038                    ast::TypeAppArgsKind::Args(args) => {
1039                        let (impl_trait, t_spec) = match &args.pos_args().first().unwrap().expr {
1040                            // TODO: check `tasc.op`
1041                            ast::Expr::TypeAscription(tasc) => {
1042                                let t = match self.instantiate_typespec_full(
1043                                    &tasc.t_spec.t_spec,
1044                                    None,
1045                                    &mut dummy_tv_cache,
1046                                    RegistrationMode::Normal,
1047                                    false,
1048                                ) {
1049                                    Ok(t) => t,
1050                                    Err((t, es)) => {
1051                                        errs.extend(es);
1052                                        t
1053                                    }
1054                                };
1055                                (t, &tasc.t_spec)
1056                            }
1057                            other => {
1058                                return Err((
1059                                    None,
1060                                    None,
1061                                    TyCheckErrors::from(TyCheckError::syntax_error(
1062                                        self.cfg.input.clone(),
1063                                        line!() as usize,
1064                                        other.loc(),
1065                                        self.caused_by(),
1066                                        format!(
1067                                            "expected type ascription, but found {}",
1068                                            other.name()
1069                                        ),
1070                                        None,
1071                                    )),
1072                                ))
1073                            }
1074                        };
1075                        let class = match self.instantiate_typespec_full(
1076                            spec,
1077                            None,
1078                            &mut dummy_tv_cache,
1079                            RegistrationMode::Normal,
1080                            false,
1081                        ) {
1082                            Ok(t) => t,
1083                            Err((t, es)) => {
1084                                errs.extend(es);
1085                                t
1086                            }
1087                        };
1088                        if errs.is_empty() {
1089                            Ok((class, Some((impl_trait, t_spec))))
1090                        } else {
1091                            Err((Some(class), Some((impl_trait, t_spec)), errs))
1092                        }
1093                    }
1094                    ast::TypeAppArgsKind::SubtypeOf(trait_spec) => {
1095                        let impl_trait = match self.instantiate_typespec_full(
1096                            &trait_spec.t_spec,
1097                            None,
1098                            &mut dummy_tv_cache,
1099                            RegistrationMode::Normal,
1100                            false,
1101                        ) {
1102                            Ok(t) => t,
1103                            Err((t, es)) => {
1104                                if !PYTHON_MODE {
1105                                    errs.extend(es);
1106                                }
1107                                t.replace(&Type::Failure, &Type::Never)
1108                            }
1109                        };
1110                        let class = match self.instantiate_typespec_full(
1111                            spec,
1112                            None,
1113                            &mut dummy_tv_cache,
1114                            RegistrationMode::Normal,
1115                            false,
1116                        ) {
1117                            Ok(t) => t,
1118                            Err((t, es)) => {
1119                                errs.extend(es);
1120                                t
1121                            }
1122                        };
1123                        if errs.is_empty() {
1124                            Ok((class, Some((impl_trait, trait_spec.as_ref()))))
1125                        } else {
1126                            Err((Some(class), Some((impl_trait, trait_spec.as_ref())), errs))
1127                        }
1128                    }
1129                }
1130            }
1131            other => {
1132                let t = match self.instantiate_typespec_full(
1133                    other,
1134                    None,
1135                    &mut dummy_tv_cache,
1136                    RegistrationMode::Normal,
1137                    false,
1138                ) {
1139                    Ok(t) => t,
1140                    Err((t, es)) => {
1141                        errs.extend(es);
1142                        t
1143                    }
1144                };
1145                if errs.is_empty() {
1146                    Ok((t, None))
1147                } else {
1148                    Err((Some(t), None, errs))
1149                }
1150            }
1151        }
1152    }
1153
1154    pub(crate) fn register_trait_impl(
1155        &mut self,
1156        class: &Type,
1157        trait_: &Type,
1158        trait_loc: &impl Locational,
1159    ) -> TyCheckResult<()> {
1160        // TODO: polymorphic trait
1161        let declared_in = NormalizedPathBuf::from(self.module_path());
1162        let declared_in = declared_in.exists().then_some(declared_in);
1163        if let Some(mut impls) = self.trait_impls().get_mut(&trait_.qual_name()) {
1164            impls.insert(TraitImpl::new(class.clone(), trait_.clone(), declared_in));
1165        } else {
1166            self.trait_impls().register(
1167                trait_.qual_name(),
1168                set! {TraitImpl::new(class.clone(), trait_.clone(), declared_in)},
1169            );
1170        }
1171        let trait_ctx = if let Some(trait_ctx) = self.get_nominal_type_ctx(trait_) {
1172            trait_ctx.clone()
1173        } else {
1174            // TODO: maybe parameters are wrong
1175            return Err(TyCheckErrors::from(TyCheckError::no_var_error(
1176                self.cfg.input.clone(),
1177                line!() as usize,
1178                trait_loc.loc(),
1179                self.caused_by(),
1180                &trait_.local_name(),
1181                None,
1182            )));
1183        };
1184        let Some(class_ctx) = self.get_mut_nominal_type_ctx(class) else {
1185            return Err(TyCheckErrors::from(TyCheckError::type_not_found(
1186                self.cfg.input.clone(),
1187                line!() as usize,
1188                trait_loc.loc(),
1189                self.caused_by(),
1190                class,
1191            )));
1192        };
1193        class_ctx.register_supertrait(trait_.clone(), &trait_ctx);
1194        Ok(())
1195    }
1196
1197    /// Registers type definitions of types and constants; unlike `register_const`, this does not evaluate terms.
1198    pub(crate) fn preregister_consts(&mut self, block: &ast::Block) -> TyCheckResult<()> {
1199        let mut total_errs = TyCheckErrors::empty();
1200        for expr in block.iter() {
1201            match expr {
1202                ast::Expr::Def(def) => {
1203                    if let Err(errs) = self.preregister_const_def(def) {
1204                        total_errs.extend(errs);
1205                    }
1206                }
1207                ast::Expr::ClassDef(class_def) => {
1208                    if let Err(errs) = self.preregister_const_def(&class_def.def) {
1209                        total_errs.extend(errs);
1210                    }
1211                }
1212                ast::Expr::PatchDef(patch_def) => {
1213                    if let Err(errs) = self.preregister_const_def(&patch_def.def) {
1214                        total_errs.extend(errs);
1215                    }
1216                }
1217                ast::Expr::Dummy(dummy) => {
1218                    if let Err(errs) = self.preregister_consts(&dummy.exprs) {
1219                        total_errs.extend(errs);
1220                    }
1221                }
1222                ast::Expr::Call(call) if PYTHON_MODE => {
1223                    if let Err(errs) = self.preregister_control_consts(call) {
1224                        total_errs.extend(errs);
1225                    }
1226                }
1227                _ => {}
1228            }
1229        }
1230        if total_errs.is_empty() {
1231            Ok(())
1232        } else {
1233            Err(total_errs)
1234        }
1235    }
1236
1237    fn preregister_control_consts(&mut self, call: &ast::Call) -> TyCheckResult<()> {
1238        match call
1239            .obj
1240            .get_name()
1241            .and_then(|s| ControlKind::try_from(&s[..]).ok())
1242        {
1243            Some(ControlKind::If) => {
1244                let Some(ast::Expr::Lambda(then)) = call.args.nth_or_key(1, "then") else {
1245                    return Ok(());
1246                };
1247                self.preregister_consts(&then.body)?;
1248                if let Some(ast::Expr::Lambda(else_)) = call.args.nth_or_key(2, "else") {
1249                    self.preregister_consts(&else_.body)?;
1250                }
1251            }
1252            Some(ControlKind::For) => {
1253                let Some(ast::Expr::Lambda(body)) = call.args.nth_or_key(1, "body") else {
1254                    return Ok(());
1255                };
1256                self.preregister_consts(&body.body)?;
1257            }
1258            Some(ControlKind::While) => {
1259                let Some(ast::Expr::Lambda(body)) = call.args.nth_or_key(1, "body") else {
1260                    return Ok(());
1261                };
1262                self.preregister_consts(&body.body)?;
1263            }
1264            Some(ControlKind::With) => {
1265                let Some(ast::Expr::Lambda(body)) = call.args.nth_or_key(1, "body") else {
1266                    return Ok(());
1267                };
1268                self.preregister_consts(&body.body)?;
1269            }
1270            _ => {}
1271        }
1272        Ok(())
1273    }
1274
1275    pub(crate) fn register_defs(&mut self, block: &ast::Block) -> TyCheckResult<()> {
1276        let mut total_errs = TyCheckErrors::empty();
1277        for expr in block.iter() {
1278            match expr {
1279                ast::Expr::Def(def) => {
1280                    if let Err(errs) = self.register_def(def) {
1281                        total_errs.extend(errs);
1282                    }
1283                    if def.def_kind().is_import() {
1284                        if let Err(errs) = self.pre_import(def) {
1285                            total_errs.extend(errs);
1286                        }
1287                    }
1288                }
1289                ast::Expr::ClassDef(class_def) => {
1290                    if let Err(errs) = self.register_def(&class_def.def) {
1291                        total_errs.extend(errs);
1292                    }
1293                    let vis = self
1294                        .instantiate_vis_modifier(class_def.def.sig.vis())
1295                        .unwrap_or(VisibilityModifier::Public);
1296                    for methods in class_def.methods_list.iter() {
1297                        let (class, impl_trait) =
1298                            match self.get_class_and_impl_trait(&methods.class) {
1299                                Ok(x) => x,
1300                                Err((class, trait_, errs)) => {
1301                                    total_errs.extend(errs);
1302                                    (class.unwrap_or(Type::Obj), trait_)
1303                                }
1304                            };
1305                        // assume the class has implemented the trait, regardless of whether the implementation is correct
1306                        if let Some((trait_, trait_loc)) = &impl_trait {
1307                            if let Err(errs) = self.register_trait_impl(&class, trait_, *trait_loc)
1308                            {
1309                                total_errs.extend(errs);
1310                            }
1311                        }
1312                        let kind =
1313                            ContextKind::MethodDefs(impl_trait.as_ref().map(|(t, _)| t.clone()));
1314                        self.grow(&class.local_name(), kind, vis.clone(), None);
1315                        for attr in methods.attrs.iter() {
1316                            match attr {
1317                                ClassAttr::Def(def) => {
1318                                    if let Err(errs) = self.register_def(def) {
1319                                        total_errs.extend(errs);
1320                                    }
1321                                }
1322                                ClassAttr::Decl(decl) => {
1323                                    if let Some(ident) = decl.expr.as_ident() {
1324                                        if let Err((_, errs)) =
1325                                            self.declare_var(ident, &decl.t_spec)
1326                                        {
1327                                            total_errs.extend(errs);
1328                                        }
1329                                    }
1330                                }
1331                                _ => {}
1332                            }
1333                        }
1334                        let ctx = self.pop();
1335                        let Some(class_root) = self.get_mut_nominal_type_ctx(&class) else {
1336                            log!(err "class not found: {class}");
1337                            continue;
1338                        };
1339                        let typ = if let Some((impl_trait, _)) = impl_trait {
1340                            ClassDefType::impl_trait(class, impl_trait)
1341                        } else {
1342                            ClassDefType::Simple(class)
1343                        };
1344                        class_root
1345                            .methods_list
1346                            .push(MethodContext::new(methods.id, typ, ctx));
1347                    }
1348                }
1349                ast::Expr::PatchDef(patch_def) => {
1350                    if let Err(errs) = self.register_def(&patch_def.def) {
1351                        total_errs.extend(errs);
1352                    }
1353                }
1354                ast::Expr::Dummy(dummy) => {
1355                    if let Err(errs) = self.register_defs(&dummy.exprs) {
1356                        total_errs.extend(errs);
1357                    }
1358                }
1359                ast::Expr::TypeAscription(tasc) => {
1360                    if !self.kind.is_module() {
1361                        continue;
1362                    }
1363                    if let Some(ident) = tasc.expr.as_ident() {
1364                        if let Err((_, errs)) = self.declare_var(ident, &tasc.t_spec) {
1365                            total_errs.extend(errs);
1366                        }
1367                    }
1368                }
1369                ast::Expr::Call(call) if PYTHON_MODE => {
1370                    if let Err(errs) = self.register_control_defs(call) {
1371                        total_errs.extend(errs);
1372                    }
1373                }
1374                _ => {}
1375            }
1376        }
1377        if total_errs.is_empty() {
1378            Ok(())
1379        } else {
1380            Err(total_errs)
1381        }
1382    }
1383
1384    fn register_control_defs(&mut self, call: &ast::Call) -> TyCheckResult<()> {
1385        match call
1386            .obj
1387            .get_name()
1388            .and_then(|s| ControlKind::try_from(&s[..]).ok())
1389        {
1390            Some(ControlKind::If) => {
1391                let Some(ast::Expr::Lambda(then)) = call.args.nth_or_key(1, "then") else {
1392                    return Ok(());
1393                };
1394                self.register_defs(&then.body)?;
1395                if let Some(ast::Expr::Lambda(else_)) = call.args.nth_or_key(2, "else") {
1396                    self.register_defs(&else_.body)?;
1397                }
1398            }
1399            Some(ControlKind::For) => {
1400                let Some(ast::Expr::Lambda(body)) = call.args.nth_or_key(1, "body") else {
1401                    return Ok(());
1402                };
1403                self.register_defs(&body.body)?;
1404            }
1405            Some(ControlKind::While) => {
1406                let Some(ast::Expr::Lambda(body)) = call.args.nth_or_key(1, "body") else {
1407                    return Ok(());
1408                };
1409                self.register_defs(&body.body)?;
1410            }
1411            Some(ControlKind::With) => {
1412                let Some(ast::Expr::Lambda(body)) = call.args.nth_or_key(1, "body") else {
1413                    return Ok(());
1414                };
1415                self.register_defs(&body.body)?;
1416            }
1417            _ => {}
1418        }
1419        Ok(())
1420    }
1421
1422    /// HACK: The constant expression evaluator can evaluate attributes when the type of the receiver is known.
1423    /// import/pyimport is not a constant function, but specially assumes that the type of the module is known in the eval phase.
1424    fn pre_import(&mut self, def: &ast::Def) -> TyCheckResult<()> {
1425        let Some(ast::Expr::Call(call)) = def.body.block.first() else {
1426            unreachable!()
1427        };
1428        let Some(ast::Expr::Literal(mod_name)) = call.args.get_left_or_key("Path") else {
1429            return Ok(());
1430        };
1431        let Ok(mod_name) = hir::Literal::try_from(mod_name.token.clone()) else {
1432            return Ok(());
1433        };
1434        let path = self.import_mod(call.additional_operation().unwrap(), &mod_name);
1435        let arg = if let Ok(path) = &path {
1436            TyParam::Value(ValueObj::Str(path.to_string_lossy().into()))
1437        } else {
1438            TyParam::Value(ValueObj::Str(
1439                mod_name.token.content.replace('\"', "").into(),
1440            ))
1441        };
1442        let res = path.map(|_path| ());
1443        let typ = if def.def_kind().is_erg_import() {
1444            module(arg)
1445        } else {
1446            py_module(arg)
1447        };
1448        let Some(ident) = def.sig.ident() else {
1449            return res;
1450        };
1451        let Some((_, vi)) = self.get_var_info(ident.inspect()) else {
1452            return res;
1453        };
1454        if let Some(_fv) = vi.t.as_free() {
1455            vi.t.destructive_link(&typ);
1456        }
1457        res
1458    }
1459
1460    fn preregister_const_def(&mut self, def: &ast::Def) -> TyCheckResult<()> {
1461        match &def.sig {
1462            ast::Signature::Var(var) if var.is_const() => {
1463                let Some(ast::Expr::Call(call)) = def.body.block.first() else {
1464                    return Ok(());
1465                };
1466                self.preregister_type(var, call)
1467            }
1468            _ => Ok(()),
1469        }
1470    }
1471
1472    fn preregister_type(&mut self, var: &ast::VarSignature, call: &ast::Call) -> TyCheckResult<()> {
1473        match call.obj.as_ref() {
1474            ast::Expr::Accessor(ast::Accessor::Ident(ident)) => match &ident.inspect()[..] {
1475                "Class" => {
1476                    let ident = var.ident().unwrap();
1477                    let t = Type::Mono(format!("{}{ident}", self.name).into());
1478                    let class = GenTypeObj::class(t, None, None, false);
1479                    let class = ValueObj::Type(TypeObj::Generated(class));
1480                    self.register_gen_const(ident, class, Some(call), false)
1481                }
1482                "Trait" => {
1483                    let ident = var.ident().unwrap();
1484                    let t = Type::Mono(format!("{}{ident}", self.name).into());
1485                    let trait_ =
1486                        GenTypeObj::trait_(t, TypeObj::builtin_type(Type::Failure), None, false);
1487                    let trait_ = ValueObj::Type(TypeObj::Generated(trait_));
1488                    self.register_gen_const(ident, trait_, Some(call), false)
1489                }
1490                _ => Ok(()),
1491            },
1492            _ => Ok(()),
1493        }
1494    }
1495
1496    pub(crate) fn register_def(&mut self, def: &ast::Def) -> TyCheckResult<()> {
1497        let id = Some(def.body.id);
1498        let __name__ = def.sig.ident().map(|i| i.inspect()).unwrap_or(UBAR);
1499        let call = if let Some(ast::Expr::Call(call)) = &def.body.block.first() {
1500            Some(call)
1501        } else {
1502            None
1503        };
1504        let mut errs = TyCheckErrors::empty();
1505        match &def.sig {
1506            ast::Signature::Subr(sig) => {
1507                if sig.is_const() {
1508                    let tv_cache = match self.instantiate_ty_bounds(&sig.bounds, PreRegister) {
1509                        Ok(tv_cache) => tv_cache,
1510                        Err((tv_cache, es)) => {
1511                            errs.extend(es);
1512                            tv_cache
1513                        }
1514                    };
1515                    let vis = self.instantiate_vis_modifier(sig.vis())?;
1516                    self.grow(__name__, ContextKind::Proc, vis, Some(tv_cache));
1517                    let (obj, const_t) = match self.eval_const_block(&def.body.block) {
1518                        Ok(obj) => (obj.clone(), v_enum(set! {obj})),
1519                        Err((obj, es)) => {
1520                            if PYTHON_MODE {
1521                                self.pop();
1522                                if let Err(es) = self.declare_sub(sig, id) {
1523                                    errs.extend(es);
1524                                }
1525                                if errs.is_empty() {
1526                                    return Ok(());
1527                                } else {
1528                                    return Err(errs);
1529                                }
1530                            }
1531                            errs.extend(es);
1532                            (obj.clone(), v_enum(set! {obj}))
1533                        }
1534                    };
1535                    if let Some(spec) = sig.return_t_spec.as_ref() {
1536                        let mut dummy_tv_cache = TyVarCache::new(self.level, self);
1537                        let spec_t = match self.instantiate_typespec_full(
1538                            &spec.t_spec,
1539                            None,
1540                            &mut dummy_tv_cache,
1541                            PreRegister,
1542                            false,
1543                        ) {
1544                            Ok(ty) => ty,
1545                            Err((ty, es)) => {
1546                                errs.extend(es);
1547                                ty
1548                            }
1549                        };
1550                        if let Err(es) = self.sub_unify(&const_t, &spec_t, &def.body, None) {
1551                            errs.extend(es);
1552                        }
1553                    }
1554                    self.pop();
1555                    if let Err(es) = self.register_gen_const(
1556                        def.sig.ident().unwrap(),
1557                        obj,
1558                        call,
1559                        def.def_kind().is_other(),
1560                    ) {
1561                        errs.extend(es);
1562                    }
1563                } else if let Err(es) = self.declare_sub(sig, id) {
1564                    errs.extend(es);
1565                }
1566            }
1567            ast::Signature::Var(sig) => {
1568                if sig.is_const() {
1569                    let kind = ContextKind::from(def);
1570                    let vis = self.instantiate_vis_modifier(sig.vis())?;
1571                    self.grow(__name__, kind, vis, None);
1572                    let (obj, const_t) = match self.eval_const_block(&def.body.block) {
1573                        Ok(obj) => (obj.clone(), v_enum(set! {obj})),
1574                        Err((obj, es)) => {
1575                            if PYTHON_MODE {
1576                                self.pop();
1577                                if let Err((_, es)) = self.pre_define_var(sig, id) {
1578                                    errs.extend(es);
1579                                }
1580                                if let Some(ident) = sig.ident() {
1581                                    let _ = self.register_gen_const(
1582                                        ident,
1583                                        obj,
1584                                        call,
1585                                        def.def_kind().is_other(),
1586                                    );
1587                                }
1588                                if errs.is_empty() {
1589                                    return Ok(());
1590                                } else {
1591                                    return Err(errs);
1592                                }
1593                            }
1594                            errs.extend(es);
1595                            (obj.clone(), v_enum(set! {obj}))
1596                        }
1597                    };
1598                    if let Some(spec) = sig.t_spec.as_ref() {
1599                        let mut dummy_tv_cache = TyVarCache::new(self.level, self);
1600                        let spec_t = match self.instantiate_typespec_full(
1601                            &spec.t_spec,
1602                            None,
1603                            &mut dummy_tv_cache,
1604                            PreRegister,
1605                            false,
1606                        ) {
1607                            Ok(ty) => ty,
1608                            Err((ty, es)) => {
1609                                errs.extend(es);
1610                                ty
1611                            }
1612                        };
1613                        if let Err(es) = self.sub_unify(&const_t, &spec_t, &def.body, None) {
1614                            errs.extend(es);
1615                        }
1616                    }
1617                    self.pop();
1618                    if let Some(ident) = sig.ident() {
1619                        if let Err(es) =
1620                            self.register_gen_const(ident, obj, call, def.def_kind().is_other())
1621                        {
1622                            errs.extend(es);
1623                        }
1624                    }
1625                } else if let Err((_, es)) = self.pre_define_var(sig, id) {
1626                    errs.extend(es);
1627                }
1628            }
1629        }
1630        if errs.is_empty() {
1631            Ok(())
1632        } else {
1633            Err(errs)
1634        }
1635    }
1636
1637    /// e.g. .new
1638    fn register_auto_impl(
1639        &mut self,
1640        name: &'static str,
1641        t: Type,
1642        muty: Mutability,
1643        vis: Visibility,
1644        py_name: Option<Str>,
1645    ) -> CompileResult<()> {
1646        let name = VarName::from_static(name);
1647        if self.locals.get(&name).is_some() {
1648            Err(CompileErrors::from(CompileError::reassign_error(
1649                self.cfg.input.clone(),
1650                line!() as usize,
1651                name.loc(),
1652                self.caused_by(),
1653                name.inspect(),
1654            )))
1655        } else {
1656            let vi = VarInfo::new(
1657                t,
1658                muty,
1659                vis,
1660                VarKind::Auto,
1661                None,
1662                self.kind.clone(),
1663                py_name,
1664                AbsLocation::unknown(),
1665            );
1666            self.locals.insert(name, vi);
1667            Ok(())
1668        }
1669    }
1670
1671    /// e.g. `::__call__`
1672    ///
1673    /// NOTE: this is same as `register_auto_impl` if `PYTHON_MODE` is true
1674    fn register_fixed_auto_impl(
1675        &mut self,
1676        name: &'static str,
1677        t: Type,
1678        muty: Mutability,
1679        vis: Visibility,
1680        py_name: Option<Str>,
1681    ) -> CompileResult<()> {
1682        let name = VarName::from_static(name);
1683        let kind = if PYTHON_MODE {
1684            VarKind::Auto
1685        } else {
1686            VarKind::FixedAuto
1687        };
1688        if self.locals.get(&name).is_some() {
1689            Err(CompileErrors::from(CompileError::reassign_error(
1690                self.cfg.input.clone(),
1691                line!() as usize,
1692                name.loc(),
1693                self.caused_by(),
1694                name.inspect(),
1695            )))
1696        } else {
1697            self.locals.insert(
1698                name,
1699                VarInfo::new(
1700                    t,
1701                    muty,
1702                    vis,
1703                    kind,
1704                    None,
1705                    self.kind.clone(),
1706                    py_name,
1707                    AbsLocation::unknown(),
1708                ),
1709            );
1710            Ok(())
1711        }
1712    }
1713
1714    fn _register_gen_decl(
1715        &mut self,
1716        name: VarName,
1717        t: Type,
1718        vis: Visibility,
1719        kind: ContextKind,
1720        py_name: Option<Str>,
1721    ) -> CompileResult<()> {
1722        if self.decls.get(&name).is_some() {
1723            Err(CompileErrors::from(CompileError::duplicate_decl_error(
1724                self.cfg.input.clone(),
1725                line!() as usize,
1726                name.loc(),
1727                self.caused_by(),
1728                name.inspect(),
1729            )))
1730        } else {
1731            let vi = VarInfo::new(
1732                t,
1733                Immutable,
1734                vis,
1735                VarKind::Declared,
1736                None,
1737                kind,
1738                py_name,
1739                self.absolutize(name.loc()),
1740            );
1741            self.decls.insert(name, vi);
1742            Ok(())
1743        }
1744    }
1745
1746    fn _register_gen_impl(
1747        &mut self,
1748        name: VarName,
1749        t: Type,
1750        muty: Mutability,
1751        vis: Visibility,
1752        kind: ContextKind,
1753        py_name: Option<Str>,
1754    ) -> CompileResult<()> {
1755        if self.locals.get(&name).is_some() {
1756            Err(CompileErrors::from(CompileError::reassign_error(
1757                self.cfg.input.clone(),
1758                line!() as usize,
1759                name.loc(),
1760                self.caused_by(),
1761                name.inspect(),
1762            )))
1763        } else {
1764            let id = DefId(get_hash(&(&self.name, &name)));
1765            let vi = VarInfo::new(
1766                t,
1767                muty,
1768                vis,
1769                VarKind::Defined(id),
1770                None,
1771                kind,
1772                py_name,
1773                self.absolutize(name.loc()),
1774            );
1775            self.locals.insert(name, vi);
1776            Ok(())
1777        }
1778    }
1779
1780    /// If the trait has super-traits, you should call `register_trait` after calling this method.
1781    pub(crate) fn register_trait_methods(&mut self, class: Type, methods: Self) {
1782        let trait_ = if let ContextKind::MethodDefs(Some(tr)) = &methods.kind {
1783            tr.clone()
1784        } else {
1785            unreachable!()
1786        };
1787        self.super_traits.push(trait_.clone());
1788        self.methods_list.push(MethodContext::new(
1789            DefId(0),
1790            ClassDefType::impl_trait(class, trait_),
1791            methods,
1792        ));
1793    }
1794
1795    /// Register that a class implements a trait and its super-traits.
1796    /// This does not register the class-trait relationship to `shared.trait_impls` (use `register_trait_impl`).
1797    pub(crate) fn register_trait(&mut self, ctx: &Self, trait_: Type) -> CompileResult<()> {
1798        let trait_ctx = ctx.get_nominal_type_ctx(&trait_).ok_or_else(|| {
1799            CompileError::type_not_found(
1800                self.cfg.input.clone(),
1801                line!() as usize,
1802                ().loc(),
1803                self.caused_by(),
1804                &trait_,
1805            )
1806        })?;
1807        if trait_ctx.typ.has_qvar() {
1808            let _substituter = Substituter::substitute_typarams(ctx, &trait_ctx.typ, &trait_)?;
1809            self.super_traits.push(trait_);
1810            let mut tv_cache = TyVarCache::new(ctx.level, ctx);
1811            let traits = trait_ctx.super_classes.iter().cloned().map(|ty| {
1812                if ty.has_undoable_linked_var() {
1813                    ctx.detach(ty, &mut tv_cache)
1814                } else {
1815                    ty
1816                }
1817            });
1818            self.super_traits.extend(traits);
1819            let traits = trait_ctx.super_traits.iter().cloned().map(|ty| {
1820                if ty.has_undoable_linked_var() {
1821                    ctx.detach(ty, &mut tv_cache)
1822                } else {
1823                    ty
1824                }
1825            });
1826            self.super_traits.extend(traits);
1827        } else {
1828            self.super_traits.push(trait_);
1829            let traits = trait_ctx.super_classes.clone();
1830            self.super_traits.extend(traits);
1831            let traits = trait_ctx.super_traits.clone();
1832            self.super_traits.extend(traits);
1833        }
1834        unique_in_place(&mut self.super_traits);
1835        Ok(())
1836    }
1837
1838    pub(crate) fn unregister_trait(&mut self, trait_: &Type) {
1839        self.super_traits.retain(|t| !t.structural_eq(trait_));
1840        // .retain(|t| !ctx.same_type_of(t, trait_));
1841    }
1842
1843    pub(crate) fn register_base_class(&mut self, ctx: &Self, class: Type) -> CompileResult<()> {
1844        let class_ctx = ctx.get_nominal_type_ctx(&class).ok_or_else(|| {
1845            CompileError::type_not_found(
1846                self.cfg.input.clone(),
1847                line!() as usize,
1848                ().loc(),
1849                self.caused_by(),
1850                &class,
1851            )
1852        })?;
1853        if class_ctx.typ.has_qvar() {
1854            let _substituter = Substituter::substitute_typarams(ctx, &class_ctx.typ, &class)?;
1855            self.super_classes.push(class);
1856            let mut tv_cache = TyVarCache::new(ctx.level, ctx);
1857            let classes = class_ctx.super_classes.iter().cloned().map(|ty| {
1858                if ty.has_undoable_linked_var() {
1859                    ctx.detach(ty, &mut tv_cache)
1860                } else {
1861                    ty
1862                }
1863            });
1864            self.super_classes.extend(classes);
1865            let traits = class_ctx.super_traits.iter().cloned().map(|ty| {
1866                if ty.has_undoable_linked_var() {
1867                    ctx.detach(ty, &mut tv_cache)
1868                } else {
1869                    ty
1870                }
1871            });
1872            self.super_traits.extend(traits);
1873        } else {
1874            self.super_classes.push(class);
1875            let classes = class_ctx.super_classes.clone();
1876            self.super_classes.extend(classes);
1877            let traits = class_ctx.super_traits.clone();
1878            self.super_traits.extend(traits);
1879        }
1880        unique_in_place(&mut self.super_classes);
1881        Ok(())
1882    }
1883
1884    pub(crate) fn register_gen_const(
1885        &mut self,
1886        ident: &Identifier,
1887        obj: ValueObj,
1888        call: Option<&ast::Call>,
1889        alias: bool,
1890    ) -> CompileResult<()> {
1891        let vis = self.instantiate_vis_modifier(&ident.vis)?;
1892        let inited = self
1893            .rec_get_const_obj(ident.inspect())
1894            .is_some_and(|v| v.is_inited());
1895        if inited && vis.is_private() {
1896            Err(CompileErrors::from(CompileError::reassign_error(
1897                self.cfg.input.clone(),
1898                line!() as usize,
1899                ident.loc(),
1900                self.caused_by(),
1901                ident.inspect(),
1902            )))
1903        } else {
1904            match obj {
1905                ValueObj::Type(t) => match t {
1906                    TypeObj::Generated(gen) if alias => {
1907                        let meta_t = gen.meta_type();
1908                        self.register_type_alias(ident, gen.into_typ(), meta_t)
1909                    }
1910                    TypeObj::Generated(gen) => self.register_gen_type(ident, gen, call),
1911                    TypeObj::Builtin { t, meta_t } => self.register_type_alias(ident, t, meta_t),
1912                },
1913                // TODO: not all value objects are comparable
1914                other => {
1915                    let id = DefId(get_hash(ident));
1916                    let vi = VarInfo::new(
1917                        v_enum(set! {other.clone()}),
1918                        Const,
1919                        Visibility::new(vis, self.name.clone()),
1920                        VarKind::Defined(id),
1921                        None,
1922                        self.kind.clone(),
1923                        None,
1924                        self.absolutize(ident.name.loc()),
1925                    );
1926                    self.index().register(ident.inspect().clone(), &vi);
1927                    self.decls.insert(ident.name.clone(), vi);
1928                    self.consts.insert(ident.name.clone(), other);
1929                    Ok(())
1930                }
1931            }
1932        }
1933    }
1934
1935    pub(crate) fn register_gen_type(
1936        &mut self,
1937        ident: &Identifier,
1938        gen: GenTypeObj,
1939        call: Option<&ast::Call>,
1940    ) -> CompileResult<()> {
1941        match gen {
1942            GenTypeObj::Class(_) => {
1943                if gen.typ().is_monomorphic() {
1944                    // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
1945                    let mut ctx = Self::mono_class(
1946                        gen.typ().qual_name(),
1947                        self.cfg.clone(),
1948                        self.shared.clone(),
1949                        2,
1950                        self.level,
1951                    );
1952                    let res = self.gen_class_new_method(&gen, call, &mut ctx);
1953                    let res2 = self.register_gen_mono_type(ident, gen, ctx, Const);
1954                    concat_result(res, res2)
1955                } else {
1956                    let params = gen
1957                        .typ()
1958                        .typarams()
1959                        .into_iter()
1960                        .map(|tp| {
1961                            let name = tp.qual_name().unwrap_or(Str::ever("_"));
1962                            ParamSpec::named_nd(name, self.get_tp_t(&tp).unwrap_or(Type::Obj))
1963                        })
1964                        .collect();
1965                    let mut ctx = Self::poly_class(
1966                        gen.typ().qual_name(),
1967                        params,
1968                        self.cfg.clone(),
1969                        self.shared.clone(),
1970                        2,
1971                        self.level,
1972                    );
1973                    let res = self.gen_class_new_method(&gen, call, &mut ctx);
1974                    let res2 = self.register_gen_poly_type(ident, gen, ctx, Const);
1975                    concat_result(res, res2)
1976                }
1977            }
1978            GenTypeObj::Subclass(_) => self.register_gen_subclass(ident, gen, call),
1979            GenTypeObj::Trait(_) => {
1980                if gen.typ().is_monomorphic() {
1981                    let mut ctx = Self::mono_trait(
1982                        gen.typ().qual_name(),
1983                        self.cfg.clone(),
1984                        self.shared.clone(),
1985                        2,
1986                        self.level,
1987                    );
1988                    let res = if let Some(TypeObj::Builtin {
1989                        t: Type::Record(req),
1990                        ..
1991                    }) = gen.base_or_sup()
1992                    {
1993                        self.register_instance_attrs(&mut ctx, req, call)
1994                    } else {
1995                        Ok(())
1996                    };
1997                    let res2 = self.register_gen_mono_type(ident, gen, ctx, Const);
1998                    concat_result(res, res2)
1999                } else {
2000                    feature_error!(
2001                        CompileErrors,
2002                        CompileError,
2003                        self,
2004                        ident.loc(),
2005                        "polymorphic trait definition"
2006                    )
2007                }
2008            }
2009            GenTypeObj::Subtrait(_) => {
2010                if gen.typ().is_monomorphic() {
2011                    let super_classes = gen.base_or_sup().map_or(vec![], |t| vec![t.typ().clone()]);
2012                    // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
2013                    let mut ctx = Self::mono_trait(
2014                        gen.typ().qual_name(),
2015                        self.cfg.clone(),
2016                        self.shared.clone(),
2017                        2,
2018                        self.level,
2019                    );
2020                    let additional = if let Some(TypeObj::Builtin {
2021                        t: Type::Record(additional),
2022                        ..
2023                    }) = gen.additional()
2024                    {
2025                        Some(additional)
2026                    } else {
2027                        None
2028                    };
2029                    let res = if let Some(additional) = additional {
2030                        self.register_instance_attrs(&mut ctx, additional, call)
2031                    } else {
2032                        Ok(())
2033                    };
2034                    for sup in super_classes.into_iter() {
2035                        if let Some(sup_ctx) = self.get_nominal_type_ctx(&sup) {
2036                            ctx.register_supertrait(sup, sup_ctx);
2037                        } else {
2038                            log!(err "{sup} not found");
2039                        }
2040                    }
2041                    let res2 = self.register_gen_mono_type(ident, gen, ctx, Const);
2042                    concat_result(res, res2)
2043                } else {
2044                    feature_error!(
2045                        CompileErrors,
2046                        CompileError,
2047                        self,
2048                        ident.loc(),
2049                        "polymorphic trait definition"
2050                    )
2051                }
2052            }
2053            GenTypeObj::Patch(_) => {
2054                if gen.typ().is_monomorphic() {
2055                    let Some(TypeObj::Builtin { t: base, .. }) = gen.base_or_sup() else {
2056                        todo!("{gen}")
2057                    };
2058                    let ctx = Self::mono_patch(
2059                        gen.typ().qual_name(),
2060                        base.clone(),
2061                        self.cfg.clone(),
2062                        self.shared.clone(),
2063                        2,
2064                        self.level,
2065                    );
2066                    self.register_gen_mono_patch(ident, gen, ctx, Const)
2067                } else {
2068                    feature_error!(
2069                        CompileErrors,
2070                        CompileError,
2071                        self,
2072                        ident.loc(),
2073                        "polymorphic patch definition"
2074                    )
2075                }
2076            }
2077            other => feature_error!(
2078                CompileErrors,
2079                CompileError,
2080                self,
2081                ident.loc(),
2082                &format!("{other} definition")
2083            ),
2084        }
2085    }
2086
2087    fn register_gen_subclass(
2088        &mut self,
2089        ident: &Identifier,
2090        gen: GenTypeObj,
2091        call: Option<&ast::Call>,
2092    ) -> CompileResult<()> {
2093        let mut errs = CompileErrors::empty();
2094        if gen.typ().is_monomorphic() {
2095            let super_classes = gen.base_or_sup().map_or(vec![], |t| vec![t.typ().clone()]);
2096            // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect();
2097            let mut ctx = Self::mono_class(
2098                gen.typ().qual_name(),
2099                self.cfg.clone(),
2100                self.shared.clone(),
2101                2,
2102                self.level,
2103            );
2104            for sup in super_classes.into_iter() {
2105                if sup.is_failure() {
2106                    continue;
2107                }
2108                let sup_ctx = match self.get_nominal_type_ctx(&sup).ok_or_else(|| {
2109                    TyCheckErrors::from(TyCheckError::type_not_found(
2110                        self.cfg.input.clone(),
2111                        line!() as usize,
2112                        ident.loc(),
2113                        self.caused_by(),
2114                        &sup,
2115                    ))
2116                }) {
2117                    Ok(ctx) => ctx,
2118                    Err(es) => {
2119                        errs.extend(es);
2120                        continue;
2121                    }
2122                };
2123                ctx.register_superclass(sup, sup_ctx);
2124            }
2125            let mut methods =
2126                Self::methods(None, self.cfg.clone(), self.shared.clone(), 2, self.level);
2127            if let Some(sup) = gen.base_or_sup() {
2128                let param_t = match sup {
2129                    TypeObj::Builtin { t, .. } => Some(t),
2130                    TypeObj::Generated(t) => t.base_or_sup().map(|t| t.typ()),
2131                };
2132                let invalid_fields = if let Some(TypeObj::Builtin {
2133                    t: Type::Record(rec),
2134                    ..
2135                }) = gen.additional()
2136                {
2137                    if let Err((fields, es)) =
2138                        self.check_subtype_instance_attrs(sup.typ(), rec, call)
2139                    {
2140                        errs.extend(es);
2141                        fields
2142                    } else {
2143                        Set::new()
2144                    }
2145                } else {
2146                    Set::new()
2147                };
2148                // `Super.Requirement := {x = Int}` and `Self.Additional := {y = Int}`
2149                // => `Self.Requirement := {x = Int; y = Int}`
2150                let call_t = {
2151                    let (nd_params, var_params, d_params, kw_var_params) =
2152                        if let Some(additional) = gen.additional() {
2153                            if let TypeObj::Builtin {
2154                                t: Type::Record(rec),
2155                                ..
2156                            } = additional
2157                            {
2158                                if let Err(es) = self.register_instance_attrs(&mut ctx, rec, call) {
2159                                    errs.extend(es);
2160                                }
2161                            }
2162                            let param_t = if let Some(Type::Record(rec)) = param_t {
2163                                let mut rec = rec.clone();
2164                                rec.remove_entries(&invalid_fields);
2165                                Some(Type::Record(rec))
2166                            } else {
2167                                param_t.cloned()
2168                            };
2169                            let nd_params = param_t
2170                                .map(|pt| self.intersection(&pt, additional.typ()))
2171                                .or(Some(additional.typ().clone()))
2172                                .map_or(vec![], |t| vec![ParamTy::Pos(t)]);
2173                            (nd_params, None, vec![], None)
2174                        } else {
2175                            self.get_nominal_type_ctx(sup.typ())
2176                                .and_then(|ctx| {
2177                                    ctx.get_class_member(&VarName::from_static("__call__"), ctx)
2178                                })
2179                                .and_then(|vi| {
2180                                    Some((
2181                                        vi.t.non_default_params()?.clone(),
2182                                        vi.t.var_params().cloned(),
2183                                        vi.t.default_params()?.clone(),
2184                                        vi.t.kw_var_params().cloned(),
2185                                    ))
2186                                })
2187                                .unwrap_or((vec![], None, vec![], None))
2188                        };
2189                    func(
2190                        nd_params,
2191                        var_params,
2192                        d_params,
2193                        kw_var_params,
2194                        gen.typ().clone(),
2195                    )
2196                };
2197                let new_t = {
2198                    let (nd_params, var_params, d_params, kw_var_params) = if let Some(additional) =
2199                        gen.additional()
2200                    {
2201                        let param_t = if let Some(Type::Record(rec)) = param_t {
2202                            let mut rec = rec.clone();
2203                            rec.remove_entries(&invalid_fields);
2204                            Some(Type::Record(rec))
2205                        } else {
2206                            param_t.cloned()
2207                        };
2208                        let nd_params = param_t
2209                            .map(|pt| self.intersection(&pt, additional.typ()))
2210                            .or(Some(additional.typ().clone()))
2211                            .map_or(vec![], |t| vec![ParamTy::Pos(t)]);
2212                        (nd_params, None, vec![], None)
2213                    } else {
2214                        self.get_nominal_type_ctx(sup.typ())
2215                            .and_then(|ctx| {
2216                                ctx.get_class_member(&VarName::from_static("new"), ctx)
2217                                    .or_else(|| {
2218                                        ctx.get_class_member(&VarName::from_static("__call__"), ctx)
2219                                    })
2220                            })
2221                            .and_then(|vi| {
2222                                Some((
2223                                    vi.t.non_default_params()?.clone(),
2224                                    vi.t.var_params().cloned(),
2225                                    vi.t.default_params()?.clone(),
2226                                    vi.t.kw_var_params().cloned(),
2227                                ))
2228                            })
2229                            .unwrap_or((vec![], None, vec![], None))
2230                    };
2231                    func(
2232                        nd_params,
2233                        var_params,
2234                        d_params,
2235                        kw_var_params,
2236                        gen.typ().clone(),
2237                    )
2238                };
2239                if PYTHON_MODE {
2240                    if let Err(es) = methods.register_auto_impl(
2241                        "__call__",
2242                        call_t,
2243                        Immutable,
2244                        Visibility::private(ctx.name.clone()),
2245                        None,
2246                    ) {
2247                        errs.extend(es);
2248                    }
2249                } else {
2250                    if let Err(es) = methods.register_fixed_auto_impl(
2251                        "__call__",
2252                        call_t,
2253                        Immutable,
2254                        Visibility::private(ctx.name.clone()),
2255                        None,
2256                    ) {
2257                        errs.extend(es);
2258                    }
2259                    // 必要なら、ユーザーが独自に上書きする
2260                    if let Err(es) = methods.register_auto_impl(
2261                        "new",
2262                        new_t,
2263                        Immutable,
2264                        Visibility::public(ctx.name.clone()),
2265                        None,
2266                    ) {
2267                        errs.extend(es);
2268                    }
2269                }
2270                ctx.methods_list.push(MethodContext::new(
2271                    DefId(0),
2272                    ClassDefType::Simple(gen.typ().clone()),
2273                    methods,
2274                ));
2275                if let Err(es) = self.register_gen_mono_type(ident, gen, ctx, Const) {
2276                    errs.extend(es);
2277                }
2278                if errs.is_empty() {
2279                    Ok(())
2280                } else {
2281                    Err(errs)
2282                }
2283            } else {
2284                let class_name = gen
2285                    .base_or_sup()
2286                    .map(|t| t.typ().local_name())
2287                    .unwrap_or(Str::from("?"));
2288                Err(CompileErrors::from(CompileError::no_type_error(
2289                    self.cfg.input.clone(),
2290                    line!() as usize,
2291                    ident.loc(),
2292                    self.caused_by(),
2293                    &class_name,
2294                    self.get_similar_name(&class_name),
2295                )))
2296            }
2297        } else {
2298            feature_error!(
2299                CompileErrors,
2300                CompileError,
2301                self,
2302                ident.loc(),
2303                "polymorphic class definition"
2304            )
2305        }
2306    }
2307
2308    fn check_subtype_instance_attrs(
2309        &self,
2310        sup: &Type,
2311        rec: &Dict<Field, Type>,
2312        call: Option<&ast::Call>,
2313    ) -> Result<(), (Set<Field>, CompileErrors)> {
2314        let mut errs = CompileErrors::empty();
2315        let mut invalid_fields = Set::new();
2316        let sup_ctx = self.get_nominal_type_ctx(sup);
2317        let additional = call.and_then(|call| {
2318            if let Some(ast::Expr::Record(record)) = call.args.get_with_key("Additional") {
2319                Some(record)
2320            } else {
2321                None
2322            }
2323        });
2324        for (field, sub_t) in rec.iter() {
2325            let loc = additional
2326                .as_ref()
2327                .and_then(|record| {
2328                    record
2329                        .keys()
2330                        .iter()
2331                        .find(|id| id.inspect() == &field.symbol)
2332                        .map(|name| name.loc())
2333                })
2334                .unwrap_or_default();
2335            let varname = VarName::from_str(field.symbol.clone());
2336            if let Some(sup_ctx) = sup_ctx {
2337                if let Some(sup_vi) = sup_ctx.decls.get(&varname) {
2338                    if !self.subtype_of(sub_t, &sup_vi.t) {
2339                        invalid_fields.insert(field.clone());
2340                        errs.push(CompileError::type_mismatch_error(
2341                            self.cfg.input.clone(),
2342                            line!() as usize,
2343                            loc,
2344                            self.caused_by(),
2345                            &field.symbol,
2346                            None,
2347                            &sup_vi.t,
2348                            sub_t,
2349                            None,
2350                            None,
2351                        ));
2352                    }
2353                }
2354            }
2355        }
2356        if errs.is_empty() {
2357            Ok(())
2358        } else {
2359            Err((invalid_fields, errs))
2360        }
2361    }
2362
2363    fn register_instance_attrs(
2364        &self,
2365        ctx: &mut Context,
2366        rec: &Dict<Field, Type>,
2367        call: Option<&ast::Call>,
2368    ) -> CompileResult<()> {
2369        let mut errs = CompileErrors::empty();
2370        let record = call.and_then(|call| {
2371            if let Some(ast::Expr::Record(record)) = call
2372                .args
2373                .get_left_or_key("Base")
2374                .or_else(|| call.args.get_left_or_key("Requirement"))
2375                .or_else(|| call.args.get_left_or_key("Super"))
2376            {
2377                Some(record)
2378            } else {
2379                None
2380            }
2381        });
2382        for (field, t) in rec.iter() {
2383            let loc = record
2384                .as_ref()
2385                .and_then(|record| {
2386                    record
2387                        .keys()
2388                        .iter()
2389                        .find(|id| id.inspect() == &field.symbol)
2390                        .map(|name| self.absolutize(name.loc()))
2391                })
2392                .unwrap_or(AbsLocation::unknown());
2393            let varname = VarName::from_str(field.symbol.clone());
2394            let vi = VarInfo::instance_attr(
2395                field.clone(),
2396                t.clone(),
2397                self.kind.clone(),
2398                ctx.name.clone(),
2399                loc,
2400            );
2401            // self.index().register(&vi);
2402            if let Some(_ent) = ctx.decls.insert(varname.clone(), vi) {
2403                errs.push(CompileError::duplicate_decl_error(
2404                    self.cfg.input.clone(),
2405                    line!() as usize,
2406                    varname.loc(),
2407                    self.caused_by(),
2408                    varname.inspect(),
2409                ));
2410            }
2411        }
2412        if errs.is_empty() {
2413            Ok(())
2414        } else {
2415            Err(errs)
2416        }
2417    }
2418
2419    fn gen_class_new_method(
2420        &self,
2421        gen: &GenTypeObj,
2422        call: Option<&ast::Call>,
2423        ctx: &mut Context,
2424    ) -> CompileResult<()> {
2425        let mut methods = Self::methods(None, self.cfg.clone(), self.shared.clone(), 2, self.level);
2426        let new_t = if let Some(base) = gen.base_or_sup() {
2427            match base {
2428                TypeObj::Builtin {
2429                    t: Type::Record(rec),
2430                    ..
2431                } => {
2432                    self.register_instance_attrs(ctx, rec, call)?;
2433                }
2434                other => {
2435                    methods.register_fixed_auto_impl(
2436                        "base",
2437                        other.typ().clone(),
2438                        Immutable,
2439                        Visibility::BUILTIN_PRIVATE,
2440                        None,
2441                    )?;
2442                }
2443            }
2444            func1(base.typ().clone(), gen.typ().clone())
2445        } else {
2446            func0(gen.typ().clone())
2447        };
2448        if ERG_MODE {
2449            methods.register_fixed_auto_impl(
2450                "__call__",
2451                new_t.clone(),
2452                Immutable,
2453                Visibility::private(ctx.name.clone()),
2454                Some("__call__".into()),
2455            )?;
2456            // users can override this if necessary
2457            methods.register_auto_impl(
2458                "new",
2459                new_t,
2460                Immutable,
2461                Visibility::public(ctx.name.clone()),
2462                None,
2463            )?;
2464        } else {
2465            methods.register_auto_impl(
2466                "__call__",
2467                new_t,
2468                Immutable,
2469                Visibility::public(ctx.name.clone()),
2470                Some("__call__".into()),
2471            )?;
2472        }
2473        ctx.methods_list.push(MethodContext::new(
2474            DefId(0),
2475            ClassDefType::Simple(gen.typ().clone()),
2476            methods,
2477        ));
2478        Ok(())
2479    }
2480
2481    pub(crate) fn register_type_alias(
2482        &mut self,
2483        ident: &Identifier,
2484        t: Type,
2485        meta_t: Type,
2486    ) -> CompileResult<()> {
2487        let vis = self.instantiate_vis_modifier(&ident.vis)?;
2488        let inited = self
2489            .rec_get_const_obj(ident.inspect())
2490            .is_some_and(|v| v.is_inited());
2491        if inited && vis.is_private() {
2492            // TODO: display where defined
2493            Err(CompileErrors::from(CompileError::reassign_error(
2494                self.cfg.input.clone(),
2495                line!() as usize,
2496                ident.loc(),
2497                self.caused_by(),
2498                ident.inspect(),
2499            )))
2500        } else {
2501            let name = &ident.name;
2502            let muty = Mutability::from(&ident.inspect()[..]);
2503            let id = DefId(get_hash(&(&self.name, &name)));
2504            let val = ValueObj::Type(TypeObj::Builtin { t, meta_t });
2505            let vi = VarInfo::new(
2506                v_enum(set! { val.clone() }),
2507                muty,
2508                Visibility::new(vis, self.name.clone()),
2509                VarKind::Defined(id),
2510                None,
2511                self.kind.clone(),
2512                None,
2513                self.absolutize(name.loc()),
2514            );
2515            self.index().register(name.inspect().clone(), &vi);
2516            self.decls.insert(name.clone(), vi);
2517            self.consts.insert(name.clone(), val);
2518            Ok(())
2519        }
2520    }
2521
2522    fn register_gen_mono_type(
2523        &mut self,
2524        ident: &Identifier,
2525        gen: GenTypeObj,
2526        ctx: Self,
2527        muty: Mutability,
2528    ) -> CompileResult<()> {
2529        let vis = self.instantiate_vis_modifier(&ident.vis)?;
2530        let inited = self
2531            .rec_get_const_obj(ident.inspect())
2532            .is_some_and(|v| v.is_inited());
2533        let vi = self.rec_get_var_info(ident, crate::AccessKind::Name, &self.cfg.input, self);
2534        if inited && vi.is_ok_and(|vi| vi.def_loc != self.absolutize(ident.loc())) {
2535            Err(CompileErrors::from(CompileError::reassign_error(
2536                self.cfg.input.clone(),
2537                line!() as usize,
2538                ident.loc(),
2539                self.caused_by(),
2540                ident.inspect(),
2541            )))
2542        } else {
2543            let t = gen.typ().clone();
2544            let val = ValueObj::Type(TypeObj::Generated(gen));
2545            let meta_t = v_enum(set! { val.clone() });
2546            let name = &ident.name;
2547            let id = DefId(get_hash(&(&self.name, &name)));
2548            let vi = VarInfo::new(
2549                meta_t,
2550                muty,
2551                Visibility::new(vis, self.name.clone()),
2552                VarKind::Defined(id),
2553                None,
2554                self.kind.clone(),
2555                None,
2556                self.absolutize(name.loc()),
2557            );
2558            self.index().register(name.inspect().clone(), &vi);
2559            self.decls.insert(name.clone(), vi);
2560            self.consts.insert(name.clone(), val);
2561            self.register_methods(&t, &ctx);
2562            self.mono_types
2563                .insert(name.clone(), TypeContext::new(t, ctx));
2564            Ok(())
2565        }
2566    }
2567
2568    fn register_gen_poly_type(
2569        &mut self,
2570        ident: &Identifier,
2571        gen: GenTypeObj,
2572        ctx: Self,
2573        muty: Mutability,
2574    ) -> CompileResult<()> {
2575        let vis = self.instantiate_vis_modifier(&ident.vis)?;
2576        let inited = self
2577            .rec_get_const_obj(ident.inspect())
2578            .is_some_and(|v| v.is_inited());
2579        if inited && vis.is_private() {
2580            Err(CompileErrors::from(CompileError::reassign_error(
2581                self.cfg.input.clone(),
2582                line!() as usize,
2583                ident.loc(),
2584                self.caused_by(),
2585                ident.inspect(),
2586            )))
2587        } else {
2588            let t = gen.typ().clone();
2589            let val = ValueObj::Type(TypeObj::Generated(gen));
2590            let params = t
2591                .typarams()
2592                .into_iter()
2593                .map(|tp| {
2594                    ParamTy::Pos(tp_enum(
2595                        self.get_tp_t(&tp).unwrap_or(Type::Obj),
2596                        set! { tp },
2597                    ))
2598                })
2599                .collect();
2600            let meta_t = func(params, None, vec![], None, v_enum(set! { val.clone() })).quantify();
2601            let name = &ident.name;
2602            let id = DefId(get_hash(&(&self.name, &name)));
2603            let vi = VarInfo::new(
2604                meta_t,
2605                muty,
2606                Visibility::new(vis, self.name.clone()),
2607                VarKind::Defined(id),
2608                None,
2609                self.kind.clone(),
2610                None,
2611                self.absolutize(name.loc()),
2612            );
2613            self.index().register(name.inspect().clone(), &vi);
2614            self.decls.insert(name.clone(), vi);
2615            self.consts.insert(name.clone(), val);
2616            self.register_methods(&t, &ctx);
2617            self.poly_types
2618                .insert(name.clone(), TypeContext::new(t, ctx));
2619            Ok(())
2620        }
2621    }
2622
2623    fn register_gen_mono_patch(
2624        &mut self,
2625        ident: &Identifier,
2626        gen: GenTypeObj,
2627        ctx: Self,
2628        muty: Mutability,
2629    ) -> CompileResult<()> {
2630        let vis = self.instantiate_vis_modifier(&ident.vis)?;
2631        // FIXME: recursive search
2632        if self.patches.contains_key(ident.inspect()) {
2633            Err(CompileErrors::from(CompileError::reassign_error(
2634                self.cfg.input.clone(),
2635                line!() as usize,
2636                ident.loc(),
2637                self.caused_by(),
2638                ident.inspect(),
2639            )))
2640        } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() {
2641            Err(CompileErrors::from(CompileError::reassign_error(
2642                self.cfg.input.clone(),
2643                line!() as usize,
2644                ident.loc(),
2645                self.caused_by(),
2646                ident.inspect(),
2647            )))
2648        } else {
2649            let t = gen.typ().clone();
2650            let meta_t = gen.meta_type();
2651            let name = &ident.name;
2652            let id = DefId(get_hash(&(&self.name, &name)));
2653            self.decls.insert(
2654                name.clone(),
2655                VarInfo::new(
2656                    meta_t,
2657                    muty,
2658                    Visibility::new(vis, self.name.clone()),
2659                    VarKind::Defined(id),
2660                    None,
2661                    self.kind.clone(),
2662                    None,
2663                    self.absolutize(name.loc()),
2664                ),
2665            );
2666            self.consts
2667                .insert(name.clone(), ValueObj::Type(TypeObj::Generated(gen)));
2668            self.register_methods(&t, &ctx);
2669            self.patches.insert(name.clone(), ctx);
2670            Ok(())
2671        }
2672    }
2673
2674    pub(crate) fn import_mod(
2675        &mut self,
2676        kind: OperationKind,
2677        mod_name: &Literal,
2678    ) -> CompileResult<PathBuf> {
2679        let ValueObj::Str(__name__) = &mod_name.value else {
2680            let name = if kind.is_erg_import() {
2681                "import"
2682            } else {
2683                "pyimport"
2684            };
2685            return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error(
2686                self.cfg.input.clone(),
2687                line!() as usize,
2688                mod_name.loc(),
2689                self.caused_by(),
2690                name,
2691                Some(1),
2692                &Type::Str,
2693                &mod_name.t(),
2694                None,
2695                None,
2696            )));
2697        };
2698        if !valid_mod_name(__name__) {
2699            return Err(TyCheckErrors::from(TyCheckError::syntax_error(
2700                self.cfg.input.clone(),
2701                line!() as usize,
2702                mod_name.loc(),
2703                self.caused_by(),
2704                format!("{__name__} is not a valid module name"),
2705                None,
2706            )));
2707        }
2708        if kind.is_erg_import() {
2709            self.import_erg_mod(__name__, mod_name)
2710        } else {
2711            self.import_py_mod(__name__, mod_name)
2712        }
2713    }
2714
2715    fn import_err(&self, line: u32, __name__: &Str, loc: &impl Locational) -> TyCheckErrors {
2716        let mod_cache = self.mod_cache();
2717        let py_mod_cache = self.py_mod_cache();
2718        TyCheckErrors::from(TyCheckError::import_error(
2719            self.cfg.input.clone(),
2720            line as usize,
2721            format!("module {__name__} not found"),
2722            loc.loc(),
2723            self.caused_by(),
2724            self.similar_builtin_erg_mod_name(__name__)
2725                .or_else(|| mod_cache.get_similar_name(__name__)),
2726            self.similar_builtin_py_mod_name(__name__)
2727                .or_else(|| py_mod_cache.get_similar_name(__name__)),
2728        ))
2729    }
2730
2731    fn import_erg_mod(&self, __name__: &Str, loc: &impl Locational) -> CompileResult<PathBuf> {
2732        let path = match self
2733            .cfg
2734            .input
2735            .resolve_real_path(Path::new(&__name__[..]), &self.cfg)
2736        {
2737            Some(path) => path,
2738            None => {
2739                return Err(self.import_err(line!(), __name__, loc));
2740            }
2741        };
2742        if ERG_MODE {
2743            self.check_mod_vis(path.as_path(), __name__, loc)?;
2744        }
2745        Ok(path)
2746    }
2747
2748    /// If the path is like `foo/bar`, check if `bar` is a public module (the definition is in `foo/__init__.er`)
2749    fn check_mod_vis(
2750        &self,
2751        path: &Path,
2752        __name__: &Str,
2753        loc: &impl Locational,
2754    ) -> CompileResult<()> {
2755        let file_kind = FileKind::from(path);
2756        let parent = if file_kind.is_init_er() {
2757            path.parent().and_then(|p| p.parent())
2758        } else {
2759            path.parent()
2760        };
2761        if let Some(parent) = parent {
2762            if DirKind::from(parent).is_erg_module() {
2763                let parent = parent.join("__init__.er");
2764                let parent_module = if let Some(parent) = self.get_mod_with_path(&parent) {
2765                    Some(parent)
2766                } else {
2767                    self.get_mod_with_path(&parent)
2768                };
2769                if let Some(parent_module) = parent_module {
2770                    let import_err = |line| {
2771                        TyCheckErrors::from(TyCheckError::import_error(
2772                            self.cfg.input.clone(),
2773                            line as usize,
2774                            format!("module `{__name__}` is not public"),
2775                            loc.loc(),
2776                            self.caused_by(),
2777                            None,
2778                            None,
2779                        ))
2780                    };
2781                    let file_stem = if file_kind.is_init_er() {
2782                        path.parent().and_then(|p| p.file_stem())
2783                    } else {
2784                        path.file_stem()
2785                    };
2786                    let mod_name = file_stem.unwrap_or_default().to_string_lossy();
2787                    if let Some((_, vi)) = parent_module.get_var_info(&mod_name) {
2788                        if !vi.vis.compatible(&ast::AccessModifier::Public, self) {
2789                            return Err(import_err(line!()));
2790                        }
2791                    } else {
2792                        return Err(import_err(line!()));
2793                    }
2794                }
2795            }
2796        }
2797        Ok(())
2798    }
2799
2800    fn similar_builtin_py_mod_name(&self, name: &Str) -> Option<Str> {
2801        get_similar_name(BUILTIN_PYTHON_MODS.into_iter(), name).map(Str::rc)
2802    }
2803
2804    fn similar_builtin_erg_mod_name(&self, name: &Str) -> Option<Str> {
2805        get_similar_name(BUILTIN_ERG_MODS.into_iter(), name).map(Str::rc)
2806    }
2807
2808    fn get_decl_path(&self, __name__: &Str, loc: &impl Locational) -> CompileResult<PathBuf> {
2809        match self
2810            .cfg
2811            .input
2812            .resolve_decl_path(Path::new(&__name__[..]), &self.cfg)
2813        {
2814            Some(path) => {
2815                if self.cfg.input.decl_file_is(&path) {
2816                    return Ok(path);
2817                }
2818                if is_pystd_main_module(path.as_path())
2819                    && !BUILTIN_PYTHON_MODS.contains(&&__name__[..])
2820                {
2821                    let err = TyCheckError::module_env_error(
2822                        self.cfg.input.clone(),
2823                        line!() as usize,
2824                        __name__,
2825                        loc.loc(),
2826                        self.caused_by(),
2827                    );
2828                    return Err(TyCheckErrors::from(err));
2829                }
2830                Ok(path)
2831            }
2832            None => {
2833                let err = TyCheckError::import_error(
2834                    self.cfg.input.clone(),
2835                    line!() as usize,
2836                    format!("module {__name__} not found"),
2837                    loc.loc(),
2838                    self.caused_by(),
2839                    self.similar_builtin_erg_mod_name(__name__)
2840                        .or_else(|| self.mod_cache().get_similar_name(__name__)),
2841                    self.similar_builtin_py_mod_name(__name__)
2842                        .or_else(|| self.py_mod_cache().get_similar_name(__name__)),
2843                );
2844                Err(TyCheckErrors::from(err))
2845            }
2846        }
2847    }
2848
2849    fn import_py_mod(&self, __name__: &Str, loc: &impl Locational) -> CompileResult<PathBuf> {
2850        let path = self.get_decl_path(__name__, loc)?;
2851        // module itself
2852        if self.cfg.input.path() == path.as_path() {
2853            return Ok(path);
2854        }
2855        if self.py_mod_cache().get(&path).is_some() {
2856            return Ok(path);
2857        }
2858        Ok(path)
2859    }
2860
2861    pub fn del(&mut self, ident: &hir::Identifier) -> CompileResult<()> {
2862        let is_const = self
2863            .rec_get_var_info(&ident.raw, crate::AccessKind::Name, &self.cfg.input, self)
2864            .map_ok_or(false, |vi| vi.muty.is_const());
2865        let is_builtin = self
2866            .get_builtins()
2867            .unwrap()
2868            .get_var_kv(ident.inspect())
2869            .is_some();
2870        if is_const || is_builtin {
2871            Err(TyCheckErrors::from(TyCheckError::del_error(
2872                self.cfg.input.clone(),
2873                line!() as usize,
2874                ident,
2875                is_const,
2876                self.caused_by(),
2877            )))
2878        } else if self.locals.get(ident.inspect()).is_some() {
2879            let vi = self.locals.remove(ident.inspect()).unwrap();
2880            self.deleted_locals.insert(ident.raw.name.clone(), vi);
2881            Ok(())
2882        } else {
2883            Err(TyCheckErrors::from(TyCheckError::no_var_error(
2884                self.cfg.input.clone(),
2885                line!() as usize,
2886                ident.loc(),
2887                self.caused_by(),
2888                ident.inspect(),
2889                self.get_similar_name(ident.inspect()),
2890            )))
2891        }
2892    }
2893
2894    pub(crate) fn get_casted_type(&self, expr: &ast::Expr) -> Option<Type> {
2895        for guard in self.rec_get_guards() {
2896            if !self.name.starts_with(&guard.namespace[..]) {
2897                continue;
2898            }
2899            if let CastTarget::Expr(target) = guard.target.as_ref() {
2900                if expr == target {
2901                    return Some(*guard.to.clone());
2902                }
2903                // { r.x in Int } =>  { r in Structural { .x = Int } }
2904                else if let ast::Expr::Accessor(ast::Accessor::Attr(attr)) = target {
2905                    if attr.obj.as_ref() == expr {
2906                        let mut rec = Dict::new();
2907                        let vis = self.instantiate_vis_modifier(&attr.ident.vis).ok()?;
2908                        let field = Field::new(vis, attr.ident.inspect().clone());
2909                        rec.insert(field, *guard.to.clone());
2910                        return Some(Type::Record(rec).structuralize());
2911                    }
2912                }
2913            }
2914        }
2915        None
2916    }
2917
2918    pub(crate) fn cast(
2919        &mut self,
2920        guard: GuardType,
2921        args: Option<&hir::Args>,
2922        overwritten: &mut Vec<(VarName, VarInfo)>,
2923    ) -> TyCheckResult<()> {
2924        match guard.target.as_ref() {
2925            CastTarget::Var { name, .. } => {
2926                if !self.name.starts_with(&guard.namespace[..]) {
2927                    return Ok(());
2928                }
2929                let vi = if let Some((name, vi)) = self.locals.remove_entry(name) {
2930                    overwritten.push((name, vi.clone()));
2931                    vi
2932                } else if let Some((n, vi)) = self.get_var_kv(name) {
2933                    overwritten.push((n.clone(), vi.clone()));
2934                    vi.clone()
2935                } else {
2936                    VarInfo::nd_parameter(
2937                        *guard.to.clone(),
2938                        self.absolutize(().loc()),
2939                        self.name.clone(),
2940                    )
2941                };
2942                match self.recover_typarams(&vi.t, &guard) {
2943                    Ok(t) => {
2944                        self.locals
2945                            .insert(VarName::from_str(name.clone()), VarInfo { t, ..vi });
2946                    }
2947                    Err(errs) => {
2948                        self.locals.insert(VarName::from_str(name.clone()), vi);
2949                        return Err(errs);
2950                    }
2951                }
2952                Ok(())
2953            }
2954            // ```
2955            // i: Obj
2956            // is_int: (x: Obj) -> {x in Int} # change the 0th arg type to Int
2957            // assert is_int i
2958            // i: Int
2959            // ```
2960            CastTarget::Arg { nth, name, loc } => {
2961                if let Some(name) = args
2962                    .and_then(|args| args.get(*nth))
2963                    .and_then(|ex| ex.local_name())
2964                {
2965                    let vi = if let Some((name, vi)) = self.locals.remove_entry(name) {
2966                        overwritten.push((name, vi.clone()));
2967                        vi
2968                    } else if let Some((n, vi)) = self.get_var_kv(name) {
2969                        overwritten.push((n.clone(), vi.clone()));
2970                        vi.clone()
2971                    } else {
2972                        VarInfo::nd_parameter(
2973                            *guard.to.clone(),
2974                            self.absolutize(().loc()),
2975                            self.name.clone(),
2976                        )
2977                    };
2978                    match self.recover_typarams(&vi.t, &guard) {
2979                        Ok(t) => {
2980                            self.locals
2981                                .insert(VarName::from_str(Str::rc(name)), VarInfo { t, ..vi });
2982                        }
2983                        Err(errs) => {
2984                            self.locals.insert(VarName::from_str(Str::rc(name)), vi);
2985                            return Err(errs);
2986                        }
2987                    }
2988                    Ok(())
2989                } else {
2990                    let target = CastTarget::Var {
2991                        name: name.clone(),
2992                        loc: *loc,
2993                    };
2994                    let guard = GuardType::new(guard.namespace, target, *guard.to);
2995                    self.cast(guard, args, overwritten)
2996                }
2997            }
2998            CastTarget::Expr(_) => {
2999                self.guards.push(guard);
3000                Ok(())
3001            }
3002        }
3003    }
3004
3005    pub(crate) fn inc_ref<L: Locational>(
3006        &self,
3007        name: &Str,
3008        vi: &VarInfo,
3009        loc: &L,
3010        namespace: &Context,
3011    ) {
3012        if let Some(index) = self.opt_index() {
3013            index.inc_ref(name, vi, namespace.absolutize(loc.loc()));
3014        }
3015    }
3016
3017    pub(crate) fn inc_ref_acc(
3018        &self,
3019        acc: &ast::Accessor,
3020        namespace: &Context,
3021        tmp_tv_cache: &TyVarCache,
3022    ) -> bool {
3023        match acc {
3024            ast::Accessor::Ident(ident) => self.inc_ref_local(ident, namespace, tmp_tv_cache),
3025            ast::Accessor::Attr(attr) => {
3026                self.inc_ref_expr(&attr.obj, namespace, tmp_tv_cache);
3027                if let Ok(ctxs) = self.get_singular_ctxs(&attr.obj, self) {
3028                    for ctx in ctxs {
3029                        if ctx.inc_ref_local(&attr.ident, namespace, tmp_tv_cache) {
3030                            return true;
3031                        }
3032                    }
3033                }
3034                false
3035            }
3036            other => {
3037                log!(err "inc_ref_acc: {other}");
3038                false
3039            }
3040        }
3041    }
3042
3043    pub(crate) fn inc_ref_predecl_typespec(
3044        &self,
3045        predecl: &PreDeclTypeSpec,
3046        namespace: &Context,
3047        tmp_tv_cache: &TyVarCache,
3048    ) -> bool {
3049        match predecl {
3050            PreDeclTypeSpec::Mono(mono) => {
3051                self.inc_ref_mono_typespec(mono, namespace, tmp_tv_cache)
3052            }
3053            PreDeclTypeSpec::Poly(poly) => {
3054                self.inc_ref_poly_typespec(poly, namespace, tmp_tv_cache)
3055            }
3056            PreDeclTypeSpec::Attr { namespace: obj, t } => {
3057                self.inc_ref_expr(obj, namespace, tmp_tv_cache);
3058                if let Ok(ctxs) = self.get_singular_ctxs(obj, self) {
3059                    for ctx in ctxs {
3060                        if ctx.inc_ref_mono_typespec(t, namespace, tmp_tv_cache) {
3061                            return true;
3062                        }
3063                    }
3064                }
3065                false
3066            }
3067            // TODO:
3068            PreDeclTypeSpec::Subscr { namespace: ns, .. } => {
3069                self.inc_ref_expr(ns, namespace, tmp_tv_cache)
3070            }
3071        }
3072    }
3073
3074    fn inc_ref_mono_typespec(
3075        &self,
3076        ident: &Identifier,
3077        namespace: &Context,
3078        tmp_tv_cache: &TyVarCache,
3079    ) -> bool {
3080        if let Triple::Ok(vi) = self.rec_get_var_info(
3081            ident,
3082            crate::compile::AccessKind::Name,
3083            &self.cfg.input,
3084            self,
3085        ) {
3086            self.inc_ref(ident.inspect(), &vi, &ident.name, namespace);
3087            true
3088        } else if let Some(vi) = tmp_tv_cache.var_infos.get(&ident.name) {
3089            self.inc_ref(ident.inspect(), vi, &ident.name, namespace);
3090            true
3091        } else {
3092            false
3093        }
3094    }
3095
3096    fn inc_ref_poly_typespec(
3097        &self,
3098        poly: &PolyTypeSpec,
3099        namespace: &Context,
3100        tmp_tv_cache: &TyVarCache,
3101    ) -> bool {
3102        for arg in poly.args.pos_args() {
3103            self.inc_ref_expr(&arg.expr.clone().downgrade(), namespace, tmp_tv_cache);
3104        }
3105        if let Some(arg) = poly.args.var_args.as_ref() {
3106            self.inc_ref_expr(&arg.expr.clone().downgrade(), namespace, tmp_tv_cache);
3107        }
3108        for arg in poly.args.kw_args() {
3109            self.inc_ref_expr(&arg.expr.clone().downgrade(), namespace, tmp_tv_cache);
3110        }
3111        if let Some(arg) = poly.args.kw_var.as_ref() {
3112            self.inc_ref_expr(&arg.expr.clone().downgrade(), namespace, tmp_tv_cache);
3113        }
3114        self.inc_ref_acc(&poly.acc.clone().downgrade(), namespace, tmp_tv_cache)
3115    }
3116
3117    pub(crate) fn inc_ref_local(
3118        &self,
3119        local: &ConstIdentifier,
3120        namespace: &Context,
3121        tmp_tv_cache: &TyVarCache,
3122    ) -> bool {
3123        if let Triple::Ok(vi) = self.rec_get_var_info(
3124            local,
3125            crate::compile::AccessKind::Name,
3126            &self.cfg.input,
3127            self,
3128        ) {
3129            self.inc_ref(local.inspect(), &vi, &local.name, namespace);
3130            true
3131        } else if let Some(vi) = tmp_tv_cache.var_infos.get(&local.name) {
3132            self.inc_ref(local.inspect(), vi, &local.name, namespace);
3133            true
3134        } else {
3135            &local.inspect()[..] == "module" || &local.inspect()[..] == "global"
3136        }
3137    }
3138
3139    fn inc_ref_block(
3140        &self,
3141        block: &ast::Block,
3142        namespace: &Context,
3143        tmp_tv_cache: &TyVarCache,
3144    ) -> bool {
3145        let mut res = false;
3146        for expr in block.iter() {
3147            if self.inc_ref_expr(expr, namespace, tmp_tv_cache) {
3148                res = true;
3149            }
3150        }
3151        res
3152    }
3153
3154    fn inc_ref_params(
3155        &self,
3156        params: &ast::Params,
3157        namespace: &Context,
3158        tmp_tv_cache: &TyVarCache,
3159    ) -> bool {
3160        let mut res = false;
3161        for param in params.non_defaults.iter() {
3162            if let Some(expr) = param.t_spec.as_ref().map(|ts| &ts.t_spec_as_expr) {
3163                if self.inc_ref_expr(expr, namespace, tmp_tv_cache) {
3164                    res = true;
3165                }
3166            }
3167        }
3168        if let Some(expr) = params
3169            .var_params
3170            .as_ref()
3171            .and_then(|p| p.t_spec.as_ref().map(|ts| &ts.t_spec_as_expr))
3172        {
3173            if self.inc_ref_expr(expr, namespace, tmp_tv_cache) {
3174                res = true;
3175            }
3176        }
3177        for param in params.defaults.iter() {
3178            if let Some(expr) = param.sig.t_spec.as_ref().map(|ts| &ts.t_spec_as_expr) {
3179                if self.inc_ref_expr(expr, namespace, tmp_tv_cache) {
3180                    res = true;
3181                }
3182            }
3183            if self.inc_ref_expr(&param.default_val, namespace, tmp_tv_cache) {
3184                res = true;
3185            }
3186        }
3187        if let Some(expr) = params
3188            .kw_var_params
3189            .as_ref()
3190            .and_then(|p| p.t_spec.as_ref().map(|ts| &ts.t_spec_as_expr))
3191        {
3192            if self.inc_ref_expr(expr, namespace, tmp_tv_cache) {
3193                res = true;
3194            }
3195        }
3196        res
3197    }
3198
3199    fn inc_ref_expr(
3200        &self,
3201        expr: &ast::Expr,
3202        namespace: &Context,
3203        tmp_tv_cache: &TyVarCache,
3204    ) -> bool {
3205        match expr {
3206            ast::Expr::Literal(_) => false,
3207            ast::Expr::Accessor(acc) => self.inc_ref_acc(acc, namespace, tmp_tv_cache),
3208            ast::Expr::BinOp(bin) => {
3209                self.inc_ref_expr(&bin.args[0], namespace, tmp_tv_cache)
3210                    || self.inc_ref_expr(&bin.args[1], namespace, tmp_tv_cache)
3211            }
3212            ast::Expr::UnaryOp(unary) => self.inc_ref_expr(&unary.value(), namespace, tmp_tv_cache),
3213            ast::Expr::Call(call) => {
3214                let mut res = self.inc_ref_expr(&call.obj, namespace, tmp_tv_cache);
3215                for arg in call.args.pos_args() {
3216                    if self.inc_ref_expr(&arg.expr, namespace, tmp_tv_cache) {
3217                        res = true;
3218                    }
3219                }
3220                if let Some(arg) = call.args.var_args() {
3221                    if self.inc_ref_expr(&arg.expr, namespace, tmp_tv_cache) {
3222                        res = true;
3223                    }
3224                }
3225                for arg in call.args.kw_args() {
3226                    if self.inc_ref_expr(&arg.expr, namespace, tmp_tv_cache) {
3227                        res = true;
3228                    }
3229                }
3230                res
3231            }
3232            ast::Expr::Record(ast::Record::Normal(rec)) => {
3233                let mut res = false;
3234                for val in rec.attrs.iter() {
3235                    if self.inc_ref_block(&val.body.block, namespace, tmp_tv_cache) {
3236                        res = true;
3237                    }
3238                }
3239                res
3240            }
3241            ast::Expr::Record(ast::Record::Mixed(rec)) => {
3242                let mut res = false;
3243                for val in rec.attrs.iter() {
3244                    match val {
3245                        RecordAttrOrIdent::Attr(attr) => {
3246                            if self.inc_ref_block(&attr.body.block, namespace, tmp_tv_cache) {
3247                                res = true;
3248                            }
3249                        }
3250                        RecordAttrOrIdent::Ident(ident) => {
3251                            if self.inc_ref_local(ident, namespace, tmp_tv_cache) {
3252                                res = true;
3253                            }
3254                        }
3255                    }
3256                }
3257                res
3258            }
3259            ast::Expr::List(ast::List::Normal(lis)) => {
3260                let mut res = false;
3261                for val in lis.elems.pos_args().iter() {
3262                    if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
3263                        res = true;
3264                    }
3265                }
3266                res
3267            }
3268            ast::Expr::Tuple(ast::Tuple::Normal(tup)) => {
3269                let mut res = false;
3270                for val in tup.elems.pos_args().iter() {
3271                    if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
3272                        res = true;
3273                    }
3274                }
3275                res
3276            }
3277            ast::Expr::Set(ast::Set::Normal(set)) => {
3278                let mut res = false;
3279                for val in set.elems.pos_args().iter() {
3280                    if self.inc_ref_expr(&val.expr, namespace, tmp_tv_cache) {
3281                        res = true;
3282                    }
3283                }
3284                res
3285            }
3286            ast::Expr::Set(ast::Set::Comprehension(comp)) => {
3287                let mut res = false;
3288                for (_, gen) in comp.generators.iter() {
3289                    if self.inc_ref_expr(gen, namespace, tmp_tv_cache) {
3290                        res = true;
3291                    }
3292                }
3293                if let Some(guard) = &comp.guard {
3294                    if self.inc_ref_expr(guard, namespace, tmp_tv_cache) {
3295                        res = true;
3296                    }
3297                }
3298                res
3299            }
3300            ast::Expr::Dict(ast::Dict::Normal(dict)) => {
3301                let mut res = false;
3302                for ast::KeyValue { key, value } in dict.kvs.iter() {
3303                    if self.inc_ref_expr(key, namespace, tmp_tv_cache) {
3304                        res = true;
3305                    }
3306                    if self.inc_ref_expr(value, namespace, tmp_tv_cache) {
3307                        res = true;
3308                    }
3309                }
3310                res
3311            }
3312            ast::Expr::Dict(ast::Dict::Comprehension(comp)) => {
3313                let mut res = false;
3314                for (_, gen) in comp.generators.iter() {
3315                    if self.inc_ref_expr(gen, namespace, tmp_tv_cache) {
3316                        res = true;
3317                    }
3318                }
3319                if let Some(guard) = &comp.guard {
3320                    if self.inc_ref_expr(guard, namespace, tmp_tv_cache) {
3321                        res = true;
3322                    }
3323                }
3324                res
3325            }
3326            ast::Expr::TypeAscription(ascription) => {
3327                self.inc_ref_expr(&ascription.expr, namespace, tmp_tv_cache)
3328            }
3329            ast::Expr::Compound(comp) => {
3330                let mut res = false;
3331                for expr in comp.exprs.iter() {
3332                    if self.inc_ref_expr(expr, namespace, tmp_tv_cache) {
3333                        res = true;
3334                    }
3335                }
3336                res
3337            }
3338            ast::Expr::Lambda(lambda) => {
3339                let mut res = false;
3340                // FIXME: assign params
3341                if self.inc_ref_params(&lambda.sig.params, namespace, tmp_tv_cache) {
3342                    res = true;
3343                }
3344                if self.inc_ref_block(&lambda.body, namespace, tmp_tv_cache) {
3345                    res = true;
3346                }
3347                res
3348            }
3349            other => {
3350                log!(err "inc_ref_expr: {other}");
3351                false
3352            }
3353        }
3354    }
3355}