erg_compiler/
lower.rs

1//! implements `ASTLowerer`.
2//!
3//! ASTLowerer(ASTからHIRへの変換器)を実装
4use std::marker::PhantomData;
5use std::mem;
6
7use erg_common::config::{ErgConfig, ErgMode};
8use erg_common::consts::{ELS, ERG_MODE, PYTHON_MODE};
9use erg_common::dict;
10use erg_common::dict::Dict;
11use erg_common::error::{ErrorDisplay, ErrorKind};
12use erg_common::error::{Location, MultiErrorDisplay};
13use erg_common::fresh::FreshNameGenerator;
14use erg_common::pathutil::{mod_name, NormalizedPathBuf};
15use erg_common::set;
16use erg_common::set::Set;
17use erg_common::traits::BlockKind;
18use erg_common::traits::New;
19use erg_common::traits::OptionalTranspose;
20use erg_common::traits::{ExitStatus, Locational, NoTypeDisplay, Runnable, Stream};
21use erg_common::triple::Triple;
22use erg_common::{fmt_option, fn_name, log, switch_lang, Str};
23
24use erg_parser::ast::{self, AscriptionKind, DefId, InlineModule, VisModifierSpec};
25use erg_parser::ast::{OperationKind, TypeSpecWithOp, VarName, AST};
26use erg_parser::build_ast::{ASTBuildable, ASTBuilder as DefaultASTBuilder};
27use erg_parser::desugar::Desugarer;
28use erg_parser::token::{Token, TokenKind};
29use erg_parser::Parser;
30use erg_parser::ParserRunner;
31
32use crate::artifact::{BuildRunnable, Buildable, CompleteArtifact, IncompleteArtifact};
33use crate::build_package::CheckStatus;
34use crate::module::SharedCompilerResource;
35use crate::ty::constructors::{
36    free_var, from_str, func, guard, list_t, mono, poly, proc, refinement, set_t, singleton, ty_tp,
37    unsized_list_t, v_enum,
38};
39use crate::ty::free::Constraint;
40use crate::ty::typaram::TyParam;
41use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
42use crate::ty::{
43    CastTarget, Field, GuardType, HasType, ParamTy, Predicate, SubrType, Type, VisibilityModifier,
44};
45
46use crate::context::{
47    ClassDefType, Context, ContextKind, ContextProvider, ControlKind, MethodContext, ModuleContext,
48    RegistrationMode, TypeContext,
49};
50use crate::error::{
51    CompileError, CompileErrors, CompileWarning, Failable, FailableOption, LowerError, LowerErrors,
52    LowerResult, LowerWarning, LowerWarnings, SingleLowerResult,
53};
54use crate::hir;
55use crate::hir::HIR;
56use crate::link_ast::ASTLinker;
57use crate::varinfo::{VarInfo, VarKind};
58use crate::{feature_error, unreachable_error};
59use crate::{AccessKind, GenericHIRBuilder};
60
61use VisibilityModifier::*;
62
63/// Checks & infers types of an AST, and convert (lower) it into a HIR
64#[derive(Debug)]
65pub struct GenericASTLowerer<ASTBuilder: ASTBuildable = DefaultASTBuilder> {
66    pub(crate) cfg: ErgConfig,
67    pub(crate) module: ModuleContext,
68    pub(crate) errs: LowerErrors,
69    pub(crate) warns: LowerWarnings,
70    fresh_gen: FreshNameGenerator,
71    _parser: PhantomData<fn() -> ASTBuilder>,
72}
73
74pub type ASTLowerer = GenericASTLowerer<DefaultASTBuilder>;
75
76impl<A: ASTBuildable> Default for GenericASTLowerer<A> {
77    fn default() -> Self {
78        Self::new_with_cache(
79            ErgConfig::default(),
80            Str::ever("<module>"),
81            SharedCompilerResource::default(),
82        )
83    }
84}
85
86impl<A: ASTBuildable> New for GenericASTLowerer<A> {
87    fn new(cfg: ErgConfig) -> Self {
88        Self::new_with_cache(
89            cfg.copy(),
90            Str::ever("<module>"),
91            SharedCompilerResource::new(cfg),
92        )
93    }
94}
95
96impl<ASTBuilder: ASTBuildable> Runnable for GenericASTLowerer<ASTBuilder> {
97    type Err = CompileError;
98    type Errs = CompileErrors;
99    const NAME: &'static str = "Erg lowerer";
100
101    #[inline]
102    fn cfg(&self) -> &ErgConfig {
103        &self.cfg
104    }
105    #[inline]
106    fn cfg_mut(&mut self) -> &mut ErgConfig {
107        &mut self.cfg
108    }
109
110    fn set_input(&mut self, input: erg_common::io::Input) {
111        self.module.context.cfg.input = input.clone();
112        self.cfg.input = input;
113    }
114
115    #[inline]
116    fn finish(&mut self) {}
117
118    fn initialize(&mut self) {
119        self.module.context.initialize();
120        self.errs.clear();
121        self.warns.clear();
122    }
123
124    fn clear(&mut self) {
125        self.errs.clear();
126        self.warns.clear();
127    }
128
129    fn exec(&mut self) -> Result<ExitStatus, Self::Errs> {
130        let mut ast_builder = ASTBuilder::new(self.cfg.copy());
131        let artifact = ast_builder
132            .build_ast(self.cfg.input.read())
133            .map_err(|artifact| artifact.errors)?;
134        artifact.warns.write_all_to(&mut self.cfg.output);
135        let artifact = self
136            .lower(artifact.ast, "exec")
137            .map_err(|artifact| artifact.errors)?;
138        artifact.warns.write_all_to(&mut self.cfg.output);
139        use std::io::Write;
140        write!(self.cfg.output, "{}", artifact.object).unwrap();
141        Ok(ExitStatus::compile_passed(artifact.warns.len()))
142    }
143
144    fn eval(&mut self, src: String) -> Result<String, Self::Errs> {
145        let mut ast_builder = ASTBuilder::new(self.cfg.copy());
146        let artifact = ast_builder
147            .build_ast(src)
148            .map_err(|artifact| artifact.errors)?;
149        artifact.warns.write_all_stderr();
150        let artifact = self
151            .lower(artifact.ast, "eval")
152            .map_err(|artifact| artifact.errors)?;
153        artifact.warns.write_all_stderr();
154        Ok(format!("{}", artifact.object))
155    }
156
157    fn expect_block(&self, src: &str) -> BlockKind {
158        let mut parser = ParserRunner::new(self.cfg().clone());
159        match parser.eval(src.to_string()) {
160            Err(errs) => {
161                let kind = errs
162                    .iter()
163                    .filter(|e| e.core().kind == ErrorKind::ExpectNextLine)
164                    .map(|e| {
165                        let msg = e.core().sub_messages.last().unwrap();
166                        // ExpectNextLine error must have msg otherwise it's a bug
167                        msg.get_msg().first().unwrap().to_owned()
168                    })
169                    .next();
170                if let Some(kind) = kind {
171                    return BlockKind::from(kind.as_str());
172                }
173                if errs
174                    .iter()
175                    .any(|err| err.core.main_message.contains("\"\"\""))
176                {
177                    return BlockKind::MultiLineStr;
178                }
179                BlockKind::Error
180            }
181            Ok(_) => {
182                if src.contains("Class") {
183                    return BlockKind::ClassDef;
184                }
185                BlockKind::None
186            }
187        }
188    }
189}
190
191impl<A: ASTBuildable> ContextProvider for GenericASTLowerer<A> {
192    fn dir(&self) -> Dict<&VarName, &VarInfo> {
193        self.module.context.dir()
194    }
195
196    fn get_receiver_ctx(&self, receiver_name: &str) -> Option<&Context> {
197        self.module.context.get_receiver_ctx(receiver_name)
198    }
199
200    fn get_var_info(&self, name: &str) -> Option<(&VarName, &VarInfo)> {
201        self.module.context.get_var_info(name)
202    }
203}
204
205impl<ASTBuilder: ASTBuildable> Buildable for GenericASTLowerer<ASTBuilder> {
206    fn inherit(cfg: ErgConfig, shared: SharedCompilerResource) -> Self {
207        let mod_name = Str::from(cfg.input.file_stem());
208        Self::new_with_cache(cfg, mod_name, shared)
209    }
210
211    fn inherit_with_name(cfg: ErgConfig, mod_name: Str, shared: SharedCompilerResource) -> Self {
212        Self::new_with_cache(cfg, mod_name, shared)
213    }
214
215    fn build(
216        &mut self,
217        src: String,
218        mode: &str,
219    ) -> Result<CompleteArtifact<HIR>, IncompleteArtifact<HIR>> {
220        let mut ast_builder = ASTBuilder::new(self.cfg.copy());
221        let artifact = ast_builder.build_ast(src).map_err(|artifact| {
222            IncompleteArtifact::new(None, artifact.errors.into(), artifact.warns.into())
223        })?;
224        self.lower(artifact.ast, mode)
225    }
226
227    fn build_from_ast(
228        &mut self,
229        ast: AST,
230        mode: &str,
231    ) -> Result<CompleteArtifact<HIR>, IncompleteArtifact<HIR>> {
232        self.lower(ast, mode)
233    }
234
235    fn pop_context(&mut self) -> Option<ModuleContext> {
236        self.pop_mod_ctx()
237    }
238    fn get_context(&self) -> Option<&ModuleContext> {
239        Some(self.get_mod_ctx())
240    }
241}
242
243impl<A: ASTBuildable + 'static> BuildRunnable for GenericASTLowerer<A> {}
244
245impl<ASTBuilder: ASTBuildable> GenericASTLowerer<ASTBuilder> {
246    pub fn new(cfg: ErgConfig) -> Self {
247        New::new(cfg)
248    }
249
250    pub fn new_with_cache<S: Into<Str>>(
251        cfg: ErgConfig,
252        mod_name: S,
253        shared: SharedCompilerResource,
254    ) -> Self {
255        let toplevel = Context::new_module(mod_name, cfg.clone(), shared);
256        let module = ModuleContext::new(toplevel, dict! {});
257        Self {
258            module,
259            cfg,
260            errs: LowerErrors::empty(),
261            warns: LowerWarnings::empty(),
262            fresh_gen: FreshNameGenerator::new("lower"),
263            _parser: PhantomData,
264        }
265    }
266
267    pub fn new_with_ctx(module: ModuleContext) -> Self {
268        Self {
269            cfg: module.get_top_cfg(),
270            module,
271            errs: LowerErrors::empty(),
272            warns: LowerWarnings::empty(),
273            fresh_gen: FreshNameGenerator::new("lower"),
274            _parser: PhantomData,
275        }
276    }
277
278    fn pop_append_errs(&mut self) {
279        let (ctx, errs) = self.module.context.check_decls_and_pop();
280        if self.cfg.mode == ErgMode::LanguageServer && !ctx.dir().is_empty() {
281            self.module.scope.insert(ctx.name.clone(), ctx);
282        }
283        self.errs.extend(errs);
284    }
285
286    pub fn pop_mod_ctx(&mut self) -> Option<ModuleContext> {
287        let opt_module = self.module.context.pop_mod();
288        opt_module.map(|module| ModuleContext::new(module, mem::take(&mut self.module.scope)))
289    }
290
291    pub fn pop_mod_ctx_or_default(&mut self) -> ModuleContext {
292        std::mem::take(&mut self.module)
293    }
294
295    pub fn get_mod_ctx(&self) -> &ModuleContext {
296        &self.module
297    }
298
299    pub fn dir(&self) -> Dict<&VarName, &VarInfo> {
300        ContextProvider::dir(self)
301    }
302
303    pub fn get_receiver_ctx(&self, receiver_name: &str) -> Option<&Context> {
304        ContextProvider::get_receiver_ctx(self, receiver_name)
305    }
306
307    pub fn get_var_info(&self, name: &str) -> Option<(&VarName, &VarInfo)> {
308        ContextProvider::get_var_info(self, name)
309    }
310
311    pub fn clear(&mut self) {
312        Runnable::clear(self);
313    }
314
315    pub fn unregister(&mut self, name: &str) -> Option<VarInfo> {
316        self.module.context.unregister(name)
317    }
318}
319
320impl<A: ASTBuildable> GenericASTLowerer<A> {
321    pub(crate) fn lower_literal(
322        &mut self,
323        lit: ast::Literal,
324        expect: Option<&Type>,
325    ) -> LowerResult<hir::Literal> {
326        let loc = lit.loc();
327        let lit = hir::Literal::try_from(lit.token).map_err(|_| {
328            LowerError::invalid_literal(
329                self.cfg.input.clone(),
330                line!() as usize,
331                loc,
332                self.module.context.caused_by(),
333            )
334        })?;
335        if let Some(expect) = expect {
336            if let Err(_errs) = self.module.context.sub_unify(&lit.t(), expect, &loc, None) {
337                // self.errs.extend(errs);
338            }
339        }
340        Ok(lit)
341    }
342
343    fn lower_list(&mut self, list: ast::List, expect: Option<&Type>) -> FailableOption<hir::List> {
344        log!(info "entered {}({list})", fn_name!());
345        match list {
346            ast::List::Normal(lis) => Ok(hir::List::Normal(
347                self.lower_normal_list(lis, expect)
348                    .map_err(|(lis, es)| (Some(hir::List::Normal(lis)), es))?,
349            )),
350            ast::List::WithLength(lis) => Ok(hir::List::WithLength(
351                self.lower_list_with_length(lis, expect)
352                    .map_err(|(lis, es)| (Some(hir::List::WithLength(lis)), es))?,
353            )),
354            other => feature_error!(
355                LowerErrors,
356                LowerError,
357                self.module.context,
358                other.loc(),
359                "list comprehension"
360            )
361            .map_err(|es| (None, es)),
362        }
363    }
364
365    fn elem_err(&self, union: Type, elem: &hir::Expr) -> LowerErrors {
366        let elem_disp_notype = elem.to_string_notype();
367        let union = self.module.context.readable_type(union);
368        LowerErrors::from(LowerError::syntax_error(
369            self.cfg.input.clone(),
370            line!() as usize,
371            elem.loc(),
372            String::from(&self.module.context.name[..]),
373            switch_lang!(
374                "japanese" => "リストの要素は全て同じ型である必要があります",
375                "simplified_chinese" => "数组元素必须全部是相同类型",
376                "traditional_chinese" => "數組元素必須全部是相同類型",
377                "english" => "all elements of a list must be of the same type",
378            )
379            .to_owned(),
380            Some(switch_lang!(
381                "japanese" => format!("[..., {elem_disp_notype}: {union}]など明示的に型を指定してください"),
382                "simplified_chinese" => format!("请明确指定类型,例如: [..., {elem_disp_notype}: {union}]"),
383                "traditional_chinese" => format!("請明確指定類型,例如: [..., {elem_disp_notype}: {union}]"),
384                "english" => format!("please specify the type explicitly, e.g. [..., {elem_disp_notype}: {union}]"),
385            )),
386        ))
387    }
388
389    fn lower_normal_list(
390        &mut self,
391        list: ast::NormalList,
392        expect: Option<&Type>,
393    ) -> Failable<hir::NormalList> {
394        log!(info "entered {}({list})", fn_name!());
395        let mut errors = LowerErrors::empty();
396        let mut new_list = vec![];
397        let eval_result = self.module.context.eval_const_normal_list(&list);
398        let (elems, ..) = list.elems.deconstruct();
399        let expect_elem = expect.and_then(|t| {
400            // REVIEW: are these all?
401            if !(t.is_list() || t.is_list_mut() || t.is_iterable()) {
402                return None;
403            }
404            self.module
405                .context
406                .convert_tp_into_type(t.typarams().first()?.clone())
407                .ok()
408        });
409        let mut union = Type::Never;
410        for elem in elems.into_iter() {
411            let elem = match self.lower_expr(elem.expr, expect_elem.as_ref()) {
412                Ok(elem) => elem,
413                Err((expr, errs)) => {
414                    errors.extend(errs);
415                    expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
416                }
417            };
418            let union_ = self.module.context.union(&union, elem.ref_t());
419            if let Err(es) = self.homogeneity_check(expect_elem.as_ref(), &union_, &union, &elem) {
420                errors.extend(es);
421            }
422            union = union_;
423            new_list.push(elem);
424        }
425        let elem_t = if union == Type::Never {
426            free_var(
427                self.module.context.level,
428                Constraint::new_type_of(Type::Type),
429            )
430        } else {
431            union
432        };
433        let elems = hir::Args::values(new_list, None);
434        let t = list_t(elem_t, TyParam::value(elems.len()));
435        let t = if let Ok(value) = eval_result {
436            singleton(t, TyParam::Value(value))
437        } else {
438            t
439        };
440        let list = hir::NormalList::new(list.l_sqbr, list.r_sqbr, t, elems);
441        if errors.is_empty() {
442            Ok(list)
443        } else {
444            Err((list, errors))
445        }
446    }
447
448    fn homogeneity_check(
449        &self,
450        expect_elem: Option<&Type>,
451        union_: &Type,
452        union: &Type,
453        elem: &hir::Expr,
454    ) -> LowerResult<()> {
455        if ERG_MODE && expect_elem.is_none() && union_.union_size() > 1 {
456            if let hir::Expr::TypeAsc(type_asc) = elem {
457                // e.g. [1, "a": Str or NoneType]
458                if !self
459                    .module
460                    .context
461                    .supertype_of(&type_asc.spec.spec_t, union)
462                {
463                    return Err(self.elem_err(union_.clone(), elem));
464                } // else(OK): e.g. [1, "a": Str or Int]
465            }
466            // OK: ?T(:> {"a"}) or ?U(:> {"b"}) or {"c", "d"} => {"a", "b", "c", "d"} <: Str
467            else if self
468                .module
469                .context
470                .coerce(union_.derefine(), &())
471                .map_or(true, |coerced| coerced.union_pair().is_some())
472            {
473                return Err(self.elem_err(union_.clone(), elem));
474            }
475        }
476        Ok(())
477    }
478
479    fn lower_list_with_length(
480        &mut self,
481        list: ast::ListWithLength,
482        expect: Option<&Type>,
483    ) -> Failable<hir::ListWithLength> {
484        log!(info "entered {}({list})", fn_name!());
485        let mut errors = LowerErrors::empty();
486        let expect_elem = expect.and_then(|t| {
487            if !(t.is_list() || t.is_list_mut() || t.is_iterable()) {
488                return None;
489            }
490            self.module
491                .context
492                .convert_tp_into_type(t.typarams().first()?.clone())
493                .ok()
494        });
495        let elem = match self.lower_expr(list.elem.expr, expect_elem.as_ref()) {
496            Ok(elem) => elem,
497            Err((expr, errs)) => {
498                errors.extend(errs);
499                expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
500            }
501        };
502        let list_t = self.gen_list_with_length_type(&elem, &list.len);
503        let len = match *list.len {
504            ast::Expr::Accessor(ast::Accessor::Ident(ident)) if ident.is_discarded() => None,
505            len => match self.lower_expr(len, Some(&Type::Nat)) {
506                Ok(len) => Some(len),
507                Err((expr, errs)) => {
508                    errors.extend(errs);
509                    expr
510                }
511            },
512        };
513        let hir_list = hir::ListWithLength::new(list.l_sqbr, list.r_sqbr, list_t, elem, len);
514        if errors.is_empty() {
515            Ok(hir_list)
516        } else {
517            Err((hir_list, errors))
518        }
519    }
520
521    fn gen_list_with_length_type(&self, elem: &hir::Expr, len: &ast::Expr) -> Type {
522        match len {
523            ast::Expr::Accessor(ast::Accessor::Ident(ident)) if ident.is_discarded() => {
524                return unsized_list_t(elem.t());
525            }
526            _ => {}
527        }
528        let maybe_len = self.module.context.eval_const_expr(len);
529        match maybe_len {
530            Ok(v @ ValueObj::Nat(_)) => list_t(elem.t(), TyParam::Value(v)),
531            Ok(other) => todo!("{other} is not a Nat object"),
532            Err((_, err)) => todo!("{err}"),
533        }
534    }
535
536    fn lower_tuple(&mut self, tuple: ast::Tuple, expect: Option<&Type>) -> Failable<hir::Tuple> {
537        log!(info "entered {}({tuple})", fn_name!());
538        match tuple {
539            ast::Tuple::Normal(tup) => Ok(hir::Tuple::Normal(
540                self.lower_normal_tuple(tup, expect)
541                    .map_err(|(tup, errs)| (hir::Tuple::Normal(tup), errs))?,
542            )),
543        }
544    }
545
546    fn lower_normal_tuple(
547        &mut self,
548        tuple: ast::NormalTuple,
549        expect: Option<&Type>,
550    ) -> Failable<hir::NormalTuple> {
551        log!(info "entered {}({tuple})", fn_name!());
552        let expect = expect.and_then(|exp| {
553            if !exp.is_tuple() {
554                return None;
555            }
556            self.module
557                .context
558                .convert_type_to_tuple_type(exp.clone())
559                .ok()
560        });
561        let mut errors = LowerErrors::empty();
562        let mut new_tuple = vec![];
563        let (elems, .., paren) = tuple.elems.deconstruct();
564        let expect_ts = expect.transpose(elems.len());
565        for (elem, expect) in elems
566            .into_iter()
567            .zip(expect_ts.into_iter().chain(std::iter::repeat(None)))
568        {
569            match self.lower_expr(elem.expr, expect.as_ref()) {
570                Ok(elem) => new_tuple.push(elem),
571                Err((expr, errs)) => {
572                    errors.extend(errs);
573                    new_tuple.push(expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty())));
574                }
575            }
576        }
577        let tuple = hir::NormalTuple::new(hir::Args::values(new_tuple, paren));
578        if errors.is_empty() {
579            Ok(tuple)
580        } else {
581            Err((tuple, errors))
582        }
583    }
584
585    fn lower_record(
586        &mut self,
587        record: ast::Record,
588        expect: Option<&Type>,
589    ) -> Failable<hir::Record> {
590        log!(info "entered {}({record})", fn_name!());
591        match record {
592            ast::Record::Normal(rec) => self.lower_normal_record(rec, expect),
593            ast::Record::Mixed(mixed) => {
594                self.lower_normal_record(Desugarer::desugar_shortened_record_inner(mixed), None)
595            }
596        }
597    }
598
599    fn lower_normal_record(
600        &mut self,
601        record: ast::NormalRecord,
602        expect: Option<&Type>,
603    ) -> Failable<hir::Record> {
604        log!(info "entered {}({record})", fn_name!());
605        let expect_record = expect.and_then(|t| {
606            if let Type::Record(rec) = t {
607                Some(rec)
608            } else {
609                None
610            }
611        });
612        let mut hir_record =
613            hir::Record::new(record.l_brace, record.r_brace, hir::RecordAttrs::empty());
614        let mut errs = LowerErrors::empty();
615        self.module
616            .context
617            .grow("<record>", ContextKind::Dummy, Private, None);
618        for attr in record.attrs.iter() {
619            if attr.sig.is_const() {
620                if let Err(es) = self.module.context.register_def(attr) {
621                    errs.extend(es);
622                }
623            }
624        }
625        for attr in record.attrs.into_iter() {
626            let expect =
627                expect_record.and_then(|rec| attr.sig.ident().and_then(|id| rec.get(id.inspect())));
628            let attr = match self.lower_def(attr, expect) {
629                Ok(def) => def,
630                Err((Some(def), es)) => {
631                    errs.extend(es);
632                    def
633                }
634                Err((None, es)) => {
635                    errs.extend(es);
636                    continue;
637                }
638            };
639            hir_record.push(attr);
640        }
641        self.pop_append_errs();
642        if errs.is_empty() {
643            Ok(hir_record)
644        } else {
645            Err((hir_record, errs))
646        }
647    }
648
649    fn lower_set(&mut self, set: ast::Set, expect: Option<&Type>) -> FailableOption<hir::Set> {
650        log!(info "enter {}({set})", fn_name!());
651        match set {
652            ast::Set::Normal(set) => Ok(hir::Set::Normal(
653                self.lower_normal_set(set, expect)
654                    .map_err(|(set, es)| (Some(hir::Set::Normal(set)), es))?,
655            )),
656            ast::Set::WithLength(set) => Ok(hir::Set::WithLength(
657                self.lower_set_with_length(set, expect)
658                    .map_err(|(set, es)| (Some(hir::Set::WithLength(set)), es))?,
659            )),
660            ast::Set::Comprehension(set) => feature_error!(
661                LowerErrors,
662                LowerError,
663                self.module.context,
664                set.loc(),
665                "set comprehension"
666            )
667            .map_err(|es| (None, es)),
668        }
669    }
670
671    fn lower_normal_set(
672        &mut self,
673        set: ast::NormalSet,
674        expect: Option<&Type>,
675    ) -> Failable<hir::NormalSet> {
676        log!(info "entered {}({set})", fn_name!());
677        let mut errors = LowerErrors::empty();
678        let (elems, ..) = set.elems.deconstruct();
679        let expect_elem = expect.and_then(|t| {
680            if !t.is_set() {
681                return None;
682            }
683            self.module
684                .context
685                .convert_tp_into_type(t.typarams().first()?.clone())
686                .ok()
687        });
688        let mut union = Type::Never;
689        let mut new_set = vec![];
690        for elem in elems {
691            let elem = match self.lower_expr(elem.expr, expect_elem.as_ref()) {
692                Ok(elem) => elem,
693                Err((expr, errs)) => {
694                    errors.extend(errs);
695                    expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
696                }
697            };
698            union = self.module.context.union(&union, elem.ref_t());
699            if ERG_MODE && union.is_union_type() {
700                let err = LowerError::set_homogeneity_error(
701                    self.cfg.input.clone(),
702                    line!() as usize,
703                    elem.loc(),
704                    self.module.context.caused_by(),
705                );
706                errors.push(err);
707            }
708            new_set.push(elem);
709        }
710        let elem_t = if union == Type::Never {
711            free_var(
712                self.module.context.level,
713                Constraint::new_type_of(Type::Type),
714            )
715        } else {
716            union
717        };
718        // TODO: lint
719        /*
720        if is_duplicated {
721            self.warns.push(LowerWarning::syntax_error(
722                self.cfg.input.clone(),
723                line!() as usize,
724                normal_set.loc(),
725                String::arc(&self.ctx.name[..]),
726                switch_lang!(
727                    "japanese" => "要素が重複しています",
728                    "simplified_chinese" => "元素重复",
729                    "traditional_chinese" => "元素重複",
730                    "english" => "Elements are duplicated",
731                ),
732                None,
733            ));
734        }
735        Ok(normal_set)
736        */
737        let elems = hir::Args::values(new_set, None);
738        // check if elem_t is Eq and Hash
739        let eq_hash = mono("Eq") & mono("Hash");
740        if let Err(errs) = self
741            .module
742            .context
743            .sub_unify(&elem_t, &eq_hash, &elems, None)
744        {
745            errors.extend(errs);
746        }
747        let set = hir::NormalSet::new(set.l_brace, set.r_brace, elem_t, elems);
748        if errors.is_empty() {
749            Ok(set)
750        } else {
751            Err((set, errors))
752        }
753    }
754
755    /// This (e.g. {"a"; 3}) is meaningless as an object, but makes sense as a type (e.g. {Int; 3}).
756    fn lower_set_with_length(
757        &mut self,
758        set: ast::SetWithLength,
759        expect: Option<&Type>,
760    ) -> Failable<hir::SetWithLength> {
761        log!("entered {}({set})", fn_name!());
762        let mut errors = LowerErrors::empty();
763        let expect_elem = expect.and_then(|t| {
764            if !t.is_set() {
765                return None;
766            }
767            self.module
768                .context
769                .convert_tp_into_type(t.typarams().first()?.clone())
770                .ok()
771        });
772        let elem = match self.lower_expr(set.elem.expr, expect_elem.as_ref()) {
773            Ok(elem) => elem,
774            Err((expr, errs)) => {
775                errors.extend(errs);
776                expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
777            }
778        };
779        let set_t = self.gen_set_with_length_type(&elem, &set.len);
780        let len = match self.lower_expr(*set.len, Some(&Type::Nat)) {
781            Ok(len) => len,
782            Err((expr, errs)) => {
783                errors.extend(errs);
784                expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
785            }
786        };
787        let hir_set = hir::SetWithLength::new(set.l_brace, set.r_brace, set_t, elem, len);
788        if errors.is_empty() {
789            Ok(hir_set)
790        } else {
791            Err((hir_set, errors))
792        }
793    }
794
795    fn gen_set_with_length_type(&mut self, elem: &hir::Expr, len: &ast::Expr) -> Type {
796        let maybe_len = self.module.context.eval_const_expr(len);
797        match maybe_len {
798            Ok(v @ ValueObj::Nat(_)) => {
799                if self.module.context.subtype_of(&elem.t(), &Type::Type) {
800                    poly("SetType", vec![TyParam::t(elem.t()), TyParam::Value(v)])
801                } else {
802                    set_t(elem.t(), TyParam::Value(v))
803                }
804            }
805            Ok(other) => todo!("{other} is not a Nat object"),
806            Err(_e) => set_t(elem.t(), TyParam::erased(Type::Nat)),
807        }
808    }
809
810    fn lower_dict(&mut self, dict: ast::Dict, expect: Option<&Type>) -> FailableOption<hir::Dict> {
811        log!(info "enter {}({dict})", fn_name!());
812        match dict {
813            ast::Dict::Normal(set) => Ok(hir::Dict::Normal(
814                self.lower_normal_dict(set, expect)
815                    .map_err(|(set, es)| (Some(hir::Dict::Normal(set)), es))?,
816            )),
817            other => feature_error!(
818                LowerErrors,
819                LowerError,
820                self.module.context,
821                other.loc(),
822                "dict comprehension"
823            )
824            .map_err(|es| (None, es)),
825            // ast::Dict::WithLength(set) => Ok(hir::Dict::WithLength(self.lower_dict_with_length(set, expect)?)),
826        }
827    }
828
829    fn lower_normal_dict(
830        &mut self,
831        dict: ast::NormalDict,
832        expect: Option<&Type>,
833    ) -> Failable<hir::NormalDict> {
834        log!(info "enter {}({dict})", fn_name!());
835        let mut errors = LowerErrors::empty();
836        let mut union = dict! {};
837        let mut new_kvs = vec![];
838        let expect = expect
839            .and_then(|exp| {
840                if !(exp.is_dict() || exp.is_dict_mut()) {
841                    return None;
842                }
843                self.module
844                    .context
845                    .convert_type_to_dict_type(exp.clone())
846                    .ok()
847            })
848            .and_then(|dict| (dict.len() == 1).then_some(dict));
849        for kv in dict.kvs.into_iter() {
850            let expect_key = expect.as_ref().and_then(|dict| dict.keys().next());
851            let expect_value = expect.as_ref().and_then(|dict| dict.values().next());
852            let key = match self.lower_expr(kv.key, expect_key) {
853                Ok(key) => key,
854                Err((expr, errs)) => {
855                    errors.extend(errs);
856                    expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
857                }
858            };
859            let value = match self.lower_expr(kv.value, expect_value) {
860                Ok(value) => value,
861                Err((expr, errs)) => {
862                    errors.extend(errs);
863                    expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
864                }
865            };
866            if let Some(popped_val_t) = union.insert(key.t(), value.t()) {
867                if PYTHON_MODE {
868                    if let Some(val_t) = union.linear_get_mut(key.ref_t()) {
869                        *val_t = self.module.context.union(&mem::take(val_t), &popped_val_t);
870                    }
871                } else {
872                    let err = LowerError::syntax_error(
873                        self.cfg.input.clone(),
874                        line!() as usize,
875                        Location::concat(&key, &value),
876                        String::from(&self.module.context.name[..]),
877                        switch_lang!(
878                            "japanese" => "Dictの値は全て同じ型である必要があります",
879                            "simplified_chinese" => "Dict的值必须是同一类型",
880                            "traditional_chinese" => "Dict的值必須是同一類型",
881                            "english" => "Values of Dict must be the same type",
882                        )
883                        .to_owned(),
884                        Some(
885                            switch_lang!(
886                                "japanese" => "Int or Strなど明示的に型を指定してください",
887                                "simplified_chinese" => "明确指定类型,例如: Int or Str",
888                                "traditional_chinese" => "明確指定類型,例如: Int or Str",
889                                "english" => "please specify the type explicitly, e.g. Int or Str",
890                            )
891                            .to_owned(),
892                        ),
893                    );
894                    errors.push(err);
895                }
896            }
897            new_kvs.push(hir::KeyValue::new(key, value));
898        }
899        for key_t in union.keys() {
900            let loc = &(&dict.l_brace, &dict.r_brace);
901            // check if key_t is Eq and Hash
902            let eq_hash = mono("Eq") & mono("Hash");
903            if let Err(errs) = self.module.context.sub_unify(key_t, &eq_hash, loc, None) {
904                errors.extend(errs);
905            }
906        }
907        let kv_ts = if union.is_empty() {
908            dict! {
909                ty_tp(free_var(self.module.context.level, Constraint::new_type_of(Type::Type))) =>
910                    ty_tp(free_var(self.module.context.level, Constraint::new_type_of(Type::Type)))
911            }
912        } else {
913            union
914                .into_iter()
915                .map(|(k, v)| (TyParam::t(k), TyParam::t(v)))
916                .collect()
917        };
918        // TODO: lint
919        /*
920        if is_duplicated {
921            self.warns.push(LowerWarning::syntax_error(
922                self.cfg.input.clone(),
923                line!() as usize,
924                normal_set.loc(),
925                String::arc(&self.ctx.name[..]),
926                switch_lang!(
927                    "japanese" => "要素が重複しています",
928                    "simplified_chinese" => "元素重复",
929                    "traditional_chinese" => "元素重複",
930                    "english" => "Elements are duplicated",
931                ),
932                None,
933            ));
934        }
935        Ok(normal_set)
936        */
937        let dict = hir::NormalDict::new(dict.l_brace, dict.r_brace, kv_ts, new_kvs);
938        if errors.is_empty() {
939            Ok(dict)
940        } else {
941            Err((dict, errors))
942        }
943    }
944
945    pub(crate) fn lower_acc(
946        &mut self,
947        acc: ast::Accessor,
948        expect: Option<&Type>,
949    ) -> Failable<hir::Accessor> {
950        log!(info "entered {}({acc})", fn_name!());
951        let mut errors = LowerErrors::empty();
952        match acc {
953            ast::Accessor::Ident(ident) => {
954                let ident = match self.lower_ident(ident, expect) {
955                    Ok(ident) => ident,
956                    Err((ident, errs)) => {
957                        errors.extend(errs);
958                        ident
959                    }
960                };
961                let acc = hir::Accessor::Ident(ident);
962                // debug_assert!(acc.ref_t().has_no_qvar(), "{acc} has qvar");
963                if errors.is_empty() {
964                    Ok(acc)
965                } else {
966                    Err((acc, errors))
967                }
968            }
969            ast::Accessor::Attr(attr) => {
970                let obj = match self.lower_expr(*attr.obj, None) {
971                    Ok(obj) => obj,
972                    Err((expr, errs)) => {
973                        errors.extend(errs);
974                        expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
975                    }
976                };
977                let vi = match self.module.context.get_attr_info(
978                    &obj,
979                    &attr.ident,
980                    &self.cfg.input,
981                    &self.module.context,
982                    expect,
983                ) {
984                    Triple::Ok(vi) => {
985                        self.inc_ref(attr.ident.inspect(), &vi, &attr.ident.name);
986                        vi
987                    }
988                    Triple::Err(errs) => {
989                        errors.push(errs);
990                        VarInfo::ILLEGAL
991                    }
992                    Triple::None => {
993                        let self_t = obj.t();
994                        let (similar_info, similar_name) = self
995                            .module
996                            .context
997                            .get_similar_attr_and_info(&self_t, attr.ident.inspect())
998                            .unzip();
999                        let err = LowerError::detailed_no_attr_error(
1000                            self.cfg.input.clone(),
1001                            line!() as usize,
1002                            attr.ident.loc(),
1003                            self.module.context.caused_by(),
1004                            &self_t,
1005                            attr.ident.inspect(),
1006                            similar_name,
1007                            similar_info,
1008                        );
1009                        errors.push(err);
1010                        VarInfo::ILLEGAL
1011                    }
1012                };
1013                if let Some(expect) = expect {
1014                    if let Err(_errs) =
1015                        self.module
1016                            .context
1017                            .sub_unify(&vi.t, expect, &attr.ident.loc(), None)
1018                    {
1019                        // self.errs.extend(errs);
1020                    }
1021                }
1022                let ident = hir::Identifier::new(attr.ident, None, vi);
1023                let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident));
1024                // debug_assert!(acc.ref_t().has_no_qvar(), "{acc} has qvar");
1025                if errors.is_empty() {
1026                    Ok(acc)
1027                } else {
1028                    Err((acc, errors))
1029                }
1030            }
1031            ast::Accessor::TypeApp(t_app) => feature_error!(
1032                LowerErrors,
1033                LowerError,
1034                self.module.context,
1035                t_app.loc(),
1036                "type application"
1037            )
1038            .map_err(|errs| (hir::Accessor::public_with_line("<todo>".into(), 0), errs)),
1039            // TupleAttr, Subscr are desugared
1040            _ => unreachable_error!(LowerErrors, LowerError, self.module.context).map_err(|errs| {
1041                (
1042                    hir::Accessor::public_with_line("<unreachable>".into(), 0),
1043                    errs,
1044                )
1045            }),
1046        }
1047    }
1048
1049    fn lower_ident(
1050        &mut self,
1051        ident: ast::Identifier,
1052        expect: Option<&Type>,
1053    ) -> Failable<hir::Identifier> {
1054        let mut errors = LowerErrors::empty();
1055        // `match` is a special form, typing is magic
1056        let (vi, __name__) = if ident.vis.is_private()
1057            && (&ident.inspect()[..] == "match" || &ident.inspect()[..] == "match!")
1058        {
1059            (
1060                VarInfo {
1061                    t: mono("Subroutine"),
1062                    ..VarInfo::default()
1063                },
1064                None,
1065            )
1066        } else {
1067            let res = match self.module.context.rec_get_var_info(
1068                &ident,
1069                AccessKind::Name,
1070                &self.cfg.input,
1071                &self.module.context,
1072            ) {
1073                Triple::Ok(vi) => vi,
1074                Triple::Err(err) => {
1075                    errors.push(err);
1076                    VarInfo::ILLEGAL
1077                }
1078                Triple::None => {
1079                    let (similar_info, similar_name) = self
1080                        .module
1081                        .context
1082                        .get_similar_name_and_info(ident.inspect())
1083                        .unzip();
1084                    let err = LowerError::detailed_no_var_error(
1085                        self.cfg.input.clone(),
1086                        line!() as usize,
1087                        ident.loc(),
1088                        self.module.context.caused_by(),
1089                        ident.inspect(),
1090                        similar_name,
1091                        similar_info,
1092                    );
1093                    errors.push(err);
1094                    VarInfo::ILLEGAL
1095                }
1096            };
1097            (
1098                res,
1099                self.module
1100                    .context
1101                    .get_singular_ctxs_by_ident(&ident, &self.module.context)
1102                    .ok()
1103                    .and_then(|ctxs| ctxs.first().map(|ctx| ctx.name.clone())),
1104            )
1105        };
1106        self.inc_ref(ident.inspect(), &vi, &ident.name);
1107        if let Some(expect) = expect {
1108            if let Err(_errs) = self
1109                .module
1110                .context
1111                .sub_unify(&vi.t, expect, &ident.loc(), None)
1112            {
1113                // self.errs.extend(errs);
1114            }
1115        }
1116        let ident = hir::Identifier::new(ident, __name__, vi);
1117        if !ident.vi.is_toplevel()
1118            && ident.vi.def_namespace() != &self.module.context.name
1119            && ident.vi.kind.can_capture()
1120            && self.module.context.current_true_function_ctx().is_some()
1121        {
1122            self.module.context.captured_names.push(ident.clone());
1123        }
1124        if errors.is_empty() {
1125            Ok(ident)
1126        } else {
1127            Err((ident, errors))
1128        }
1129    }
1130
1131    fn get_guard_type(&self, expr: &ast::Expr) -> Option<Type> {
1132        match expr {
1133            ast::Expr::BinOp(bin) => {
1134                let lhs = &bin.args[0];
1135                let rhs = &bin.args[1];
1136                self.get_bin_guard_type(&bin.op, lhs, rhs)
1137            }
1138            ast::Expr::Call(call) => self.get_call_guard_type(call),
1139            _ => None,
1140        }
1141    }
1142
1143    fn get_call_guard_type(&self, call: &ast::Call) -> Option<Type> {
1144        match (
1145            call.obj.as_ref(),
1146            &call.attr_name,
1147            &call.args.nth_or_key(0, "object"),
1148            &call.args.nth_or_key(1, "classinfo"),
1149        ) {
1150            (ast::Expr::Accessor(ast::Accessor::Ident(ident)), None, Some(lhs), Some(rhs)) => {
1151                match &ident.inspect()[..] {
1152                    "isinstance" | "issubclass" => {
1153                        self.get_bin_guard_type(ident.name.token(), lhs, rhs)
1154                    }
1155                    "hasattr" => {
1156                        let ast::Expr::Literal(lit) = rhs else {
1157                            return None;
1158                        };
1159                        if !lit.is(TokenKind::StrLit) {
1160                            return None;
1161                        }
1162                        let name = lit.token.content.trim_matches('\"');
1163                        let target = self.expr_to_cast_target(lhs);
1164                        let rec = dict! {
1165                            Field::new(VisibilityModifier::Public, Str::rc(name)) => Type::Obj,
1166                        };
1167                        let to = Type::Record(rec).structuralize();
1168                        Some(guard(self.module.context.name.clone(), target, to))
1169                    }
1170                    _ => None,
1171                }
1172            }
1173            (ast::Expr::Accessor(ast::Accessor::Ident(ident)), None, Some(arg), None) => {
1174                match &ident.inspect()[..] {
1175                    "not" => {
1176                        let arg = self.get_guard_type(arg)?;
1177                        Some(self.module.context.complement(&arg))
1178                    }
1179                    _ => None,
1180                }
1181            }
1182            _ => None,
1183        }
1184    }
1185
1186    pub fn expr_to_cast_target(&self, expr: &ast::Expr) -> CastTarget {
1187        match expr {
1188            ast::Expr::Accessor(ast::Accessor::Ident(ident)) => {
1189                if let Some(nth) = self
1190                    .module
1191                    .context
1192                    .params
1193                    .iter()
1194                    .position(|(name, _)| name.as_ref() == Some(&ident.name))
1195                {
1196                    CastTarget::Arg {
1197                        nth,
1198                        name: ident.inspect().clone(),
1199                        loc: ident.loc(),
1200                    }
1201                } else {
1202                    CastTarget::Var {
1203                        name: ident.inspect().clone(),
1204                        loc: ident.loc(),
1205                    }
1206                }
1207            }
1208            _ => CastTarget::expr(expr.clone()),
1209        }
1210    }
1211
1212    fn get_bin_guard_type(&self, op: &Token, lhs: &ast::Expr, rhs: &ast::Expr) -> Option<Type> {
1213        match op.kind {
1214            TokenKind::AndOp => {
1215                let lhs = self.get_guard_type(lhs)?;
1216                let rhs = self.get_guard_type(rhs)?;
1217                return Some(self.module.context.intersection(&lhs, &rhs));
1218            }
1219            TokenKind::OrOp => {
1220                let lhs = self.get_guard_type(lhs)?;
1221                let rhs = self.get_guard_type(rhs)?;
1222                return Some(self.module.context.union(&lhs, &rhs));
1223            }
1224            _ => {}
1225        }
1226        let target = if op.kind == TokenKind::ContainsOp {
1227            self.expr_to_cast_target(rhs)
1228        } else {
1229            self.expr_to_cast_target(lhs)
1230        };
1231        let namespace = self.module.context.name.clone();
1232        match op.kind {
1233            // l in T -> T contains l
1234            TokenKind::ContainsOp => {
1235                let to = self.module.context.expr_to_type(lhs.clone()).ok()?;
1236                Some(guard(namespace, target, to))
1237            }
1238            TokenKind::Symbol if &op.content[..] == "isinstance" => {
1239                // isinstance(x, (T, U)) => x: T or U
1240                let to = if let ast::Expr::Tuple(ast::Tuple::Normal(tys)) = rhs {
1241                    tys.elems.pos_args.iter().fold(Type::Never, |acc, ex| {
1242                        let Ok(ty) = self.module.context.expr_to_type(ex.expr.clone()) else {
1243                            return acc;
1244                        };
1245                        self.module.context.union(&acc, &ty)
1246                    })
1247                } else {
1248                    self.module.context.expr_to_type(rhs.clone()).ok()?
1249                };
1250                Some(guard(namespace, target, to))
1251            }
1252            TokenKind::IsOp | TokenKind::DblEq => {
1253                let rhs = self.module.context.expr_to_value(rhs.clone()).ok()?;
1254                Some(guard(namespace, target, v_enum(set! { rhs })))
1255            }
1256            TokenKind::IsNotOp | TokenKind::NotEq => {
1257                let rhs = self.module.context.expr_to_value(rhs.clone()).ok()?;
1258                let ty = guard(namespace, target, v_enum(set! { rhs }));
1259                Some(self.module.context.complement(&ty))
1260            }
1261            TokenKind::Gre => {
1262                let rhs = self.module.context.expr_to_tp(rhs.clone()).ok()?;
1263                let t = self.module.context.get_tp_t(&rhs).unwrap_or(Type::Obj);
1264                let varname = self.fresh_gen.fresh_varname();
1265                let pred = Predicate::gt(varname.clone(), rhs);
1266                let refine = refinement(varname, t, pred);
1267                Some(guard(namespace, target, refine))
1268            }
1269            TokenKind::GreEq => {
1270                let rhs = self.module.context.expr_to_tp(rhs.clone()).ok()?;
1271                let t = self.module.context.get_tp_t(&rhs).unwrap_or(Type::Obj);
1272                let varname = self.fresh_gen.fresh_varname();
1273                let pred = Predicate::ge(varname.clone(), rhs);
1274                let refine = refinement(varname, t, pred);
1275                Some(guard(namespace, target, refine))
1276            }
1277            TokenKind::Less => {
1278                let rhs = self.module.context.expr_to_tp(rhs.clone()).ok()?;
1279                let t = self.module.context.get_tp_t(&rhs).unwrap_or(Type::Obj);
1280                let varname = self.fresh_gen.fresh_varname();
1281                let pred = Predicate::lt(varname.clone(), rhs);
1282                let refine = refinement(varname, t, pred);
1283                Some(guard(namespace, target, refine))
1284            }
1285            TokenKind::LessEq => {
1286                let rhs = self.module.context.expr_to_tp(rhs.clone()).ok()?;
1287                let t = self.module.context.get_tp_t(&rhs).unwrap_or(Type::Obj);
1288                let varname = self.fresh_gen.fresh_varname();
1289                let pred = Predicate::le(varname.clone(), rhs);
1290                let refine = refinement(varname, t, pred);
1291                Some(guard(namespace, target, refine))
1292            }
1293            _ => None,
1294        }
1295    }
1296
1297    fn lower_bin(&mut self, bin: ast::BinOp, expect: Option<&Type>) -> Failable<hir::BinOp> {
1298        log!(info "entered {}({bin})", fn_name!());
1299        let mut errors = LowerErrors::empty();
1300        let mut args = bin.args.into_iter();
1301        let lhs = *args.next().unwrap();
1302        let rhs = *args.next().unwrap();
1303        let guard = self.get_bin_guard_type(&bin.op, &lhs, &rhs);
1304        let lhs = self.lower_expr(lhs, None).unwrap_or_else(|(expr, errs)| {
1305            errors.extend(errs);
1306            expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::new(vec![])))
1307        });
1308        let lhs = hir::PosArg::new(lhs);
1309        let rhs = self.lower_expr(rhs, None).unwrap_or_else(|(expr, errs)| {
1310            errors.extend(errs);
1311            expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::new(vec![])))
1312        });
1313        let rhs = hir::PosArg::new(rhs);
1314        let mut args = [lhs, rhs];
1315        let mut vi = self
1316            .module
1317            .context
1318            .get_binop_t(&bin.op, &mut args, &self.cfg.input, &self.module.context)
1319            .unwrap_or_else(|errs| {
1320                errors.extend(errs);
1321                VarInfo::ILLEGAL
1322            });
1323        if let Some(guard) = guard {
1324            if let Some(return_t) = vi.t.mut_return_t() {
1325                debug_assert!(
1326                    self.module.context.subtype_of(return_t, &Type::Bool),
1327                    "{return_t} is not a subtype of Bool"
1328                );
1329                *return_t = guard;
1330            } else if let Some(mut return_t) = vi.t.tyvar_mut_return_t() {
1331                debug_assert!(
1332                    self.module.context.subtype_of(&return_t, &Type::Bool),
1333                    "{return_t} is not a subtype of Bool"
1334                );
1335                *return_t = guard;
1336            }
1337        }
1338        if let Some(expect) = expect {
1339            if let Err(_errs) =
1340                self.module
1341                    .context
1342                    .sub_unify(vi.t.return_t().unwrap(), expect, &args, None)
1343            {
1344                // self.errs.extend(errs);
1345            }
1346        }
1347        let mut args = args.into_iter();
1348        let lhs = args.next().unwrap().expr;
1349        let rhs = args.next().unwrap().expr;
1350        let bin = hir::BinOp::new(bin.op, lhs, rhs, vi);
1351        if errors.is_empty() {
1352            Ok(bin)
1353        } else {
1354            Err((bin, errors))
1355        }
1356    }
1357
1358    fn lower_unary(
1359        &mut self,
1360        unary: ast::UnaryOp,
1361        expect: Option<&Type>,
1362    ) -> Failable<hir::UnaryOp> {
1363        log!(info "entered {}({unary})", fn_name!());
1364        let mut errors = LowerErrors::empty();
1365        let mut args = unary.args.into_iter();
1366        let arg = self
1367            .lower_expr(*args.next().unwrap(), None)
1368            .unwrap_or_else(|(expr, errs)| {
1369                errors.extend(errs);
1370                expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::new(vec![])))
1371            });
1372        let mut args = [hir::PosArg::new(arg)];
1373        let vi = self
1374            .module
1375            .context
1376            .get_unaryop_t(&unary.op, &mut args, &self.cfg.input, &self.module.context)
1377            .unwrap_or_else(|errs| {
1378                errors.extend(errs);
1379                VarInfo::ILLEGAL
1380            });
1381        if let Some(expect) = expect {
1382            if let Err(_errs) =
1383                self.module
1384                    .context
1385                    .sub_unify(vi.t.return_t().unwrap(), expect, &args, None)
1386            {
1387                // self.errs.extend(errs);
1388            }
1389        }
1390        let mut args = args.into_iter();
1391        let expr = args.next().unwrap().expr;
1392        let unary = hir::UnaryOp::new(unary.op, expr, vi);
1393        if errors.is_empty() {
1394            Ok(unary)
1395        } else {
1396            Err((unary, errors))
1397        }
1398    }
1399
1400    fn lower_args(
1401        &mut self,
1402        args: ast::Args,
1403        expect: Option<&SubrType>,
1404        errs: &mut LowerErrors,
1405    ) -> hir::Args {
1406        let (pos_args, var_args, kw_args, kw_var, paren) = args.deconstruct();
1407        let mut hir_args = hir::Args::new(
1408            Vec::with_capacity(pos_args.len()),
1409            None,
1410            Vec::with_capacity(kw_args.len()),
1411            None,
1412            paren,
1413        );
1414        let pos_params = expect
1415            .as_ref()
1416            .map(|subr| subr.pos_params().map(|p| Some(p.typ())))
1417            .map_or(vec![None; pos_args.len()], |params| {
1418                params.take(pos_args.len()).collect()
1419            });
1420        let mut pos_args = pos_args
1421            .into_iter()
1422            .zip(pos_params)
1423            .enumerate()
1424            .collect::<Vec<_>>();
1425        // `if` may perform assert casting, so don't sort args
1426        if self
1427            .module
1428            .context
1429            .current_control_flow()
1430            .is_none_or(|kind| !kind.is_if())
1431            && expect.is_some_and(|subr| !subr.essential_qnames().is_empty())
1432        {
1433            pos_args
1434                .sort_by(|(_, (l, _)), (_, (r, _))| l.expr.complexity().cmp(&r.expr.complexity()));
1435        }
1436        let mut hir_pos_args =
1437            vec![hir::PosArg::new(hir::Expr::Dummy(hir::Dummy::empty())); pos_args.len()];
1438        for (nth, (arg, param)) in pos_args {
1439            match self.lower_expr(arg.expr, param) {
1440                Ok(expr) => {
1441                    // e.g. `if not isinstance(x, Int)`
1442                    // push {x in not Int}, not {x in Int}
1443                    if let Some(kind) = self.module.context.current_control_flow() {
1444                        self.push_guard(nth, kind, expr.ref_t());
1445                    }
1446                    hir_pos_args[nth] = hir::PosArg::new(expr);
1447                }
1448                Err((expr, es)) => {
1449                    if let Some(expr) = expr {
1450                        hir_pos_args[nth] = hir::PosArg::new(expr);
1451                    }
1452                    errs.extend(es);
1453                }
1454            }
1455        }
1456        hir_args.pos_args = hir_pos_args;
1457        // TODO: expect var_args
1458        if let Some(var_args) = var_args {
1459            match self.lower_expr(var_args.expr, None) {
1460                Ok(expr) => hir_args.var_args = Some(Box::new(hir::PosArg::new(expr))),
1461                Err((expr, es)) => {
1462                    errs.extend(es);
1463                    let dummy = expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()));
1464                    hir_args.var_args = Some(Box::new(hir::PosArg::new(dummy)));
1465                }
1466            }
1467        }
1468        for arg in kw_args.into_iter() {
1469            let kw_param = expect.as_ref().and_then(|subr| {
1470                subr.non_var_params()
1471                    .find(|pt| pt.name().is_some_and(|n| n == &arg.keyword.content))
1472                    .map(|pt| pt.typ())
1473            });
1474            match self.lower_expr(arg.expr, kw_param) {
1475                Ok(expr) => hir_args.push_kw(hir::KwArg::new(arg.keyword, expr)),
1476                Err((expr, es)) => {
1477                    errs.extend(es);
1478                    hir_args.push_kw(hir::KwArg::new(
1479                        arg.keyword,
1480                        expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty())),
1481                    ));
1482                }
1483            }
1484        }
1485        if let Some(kw_var) = kw_var {
1486            match self.lower_expr(kw_var.expr, None) {
1487                Ok(expr) => hir_args.kw_var = Some(Box::new(hir::PosArg::new(expr))),
1488                Err((expr, es)) => {
1489                    errs.extend(es);
1490                    let dummy = expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()));
1491                    hir_args.kw_var = Some(Box::new(hir::PosArg::new(dummy)));
1492                }
1493            }
1494        }
1495        hir_args
1496    }
1497
1498    /// ```erg
1499    /// x: Int or NoneType
1500    /// if x != None:
1501    ///     do: ... # x: Int (x != None)
1502    ///     do: ... # x: NoneType (complement(x != None))
1503    /// ```
1504    fn push_guard(&mut self, nth: usize, kind: ControlKind, t: &Type) {
1505        match t {
1506            Type::Guard(guard) => match nth {
1507                0 if kind.is_conditional() => {
1508                    self.replace_or_push_guard(guard.clone());
1509                }
1510                1 if kind.is_if() => {
1511                    let guard = GuardType::new(
1512                        guard.namespace.clone(),
1513                        *guard.target.clone(),
1514                        self.module.context.complement(&guard.to),
1515                    );
1516                    self.replace_or_push_guard(guard);
1517                }
1518                _ => {}
1519            },
1520            Type::And(tys, _) => {
1521                for ty in tys {
1522                    self.push_guard(nth, kind, ty);
1523                }
1524            }
1525            _ => {}
1526        }
1527    }
1528
1529    fn replace_or_push_guard(&mut self, guard: GuardType) {
1530        if let Some(idx) = self.module.context.guards.iter().position(|existing| {
1531            existing.namespace == guard.namespace
1532                && existing.target == guard.target
1533                && self.module.context.supertype_of(&existing.to, &guard.to)
1534        }) {
1535            self.module.context.guards[idx] = guard;
1536        } else {
1537            self.module.context.guards.push(guard);
1538        }
1539    }
1540
1541    pub(crate) fn lower_call(
1542        &mut self,
1543        call: ast::Call,
1544        expect: Option<&Type>,
1545    ) -> Failable<hir::Call> {
1546        log!(info "entered {}({}{}(...))", fn_name!(), call.obj, fmt_option!(call.attr_name));
1547        let pushed = if let (Some(name), None) = (call.obj.get_name(), &call.attr_name) {
1548            self.module.context.higher_order_caller.push(name.clone());
1549            true
1550        } else {
1551            false
1552        };
1553        let mut errs = LowerErrors::empty();
1554        let guard = self.get_call_guard_type(&call);
1555        let mut obj = match self.lower_expr(*call.obj, None) {
1556            Ok(obj) => obj,
1557            Err((obj, es)) => {
1558                if pushed {
1559                    self.module.context.higher_order_caller.pop();
1560                }
1561                errs.extend(es);
1562                obj.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
1563            }
1564        };
1565        let opt_vi = self.module.context.get_call_t_without_args(
1566            &obj,
1567            &call.attr_name,
1568            &self.cfg.input,
1569            expect,
1570            &self.module.context,
1571        );
1572        let expect_subr = opt_vi
1573            .as_ref()
1574            .ok()
1575            .and_then(|vi| <&SubrType>::try_from(&vi.t).ok());
1576        if let Some((subr_return_t, expect)) =
1577            expect_subr.map(|subr| subr.return_t.as_ref()).zip(expect)
1578        {
1579            if let Err(_errs) = self
1580                .module
1581                .context
1582                .sub_unify(subr_return_t, expect, &(), None)
1583            {
1584                // self.errs.extend(errs);
1585            }
1586        }
1587        let mut hir_args = self.lower_args(call.args, expect_subr, &mut errs);
1588        let mut vi = match self.module.context.get_call_t(
1589            &obj,
1590            &call.attr_name,
1591            &mut hir_args.pos_args,
1592            &hir_args.kw_args,
1593            (hir_args.var_args.as_deref(), hir_args.kw_var.as_deref()),
1594            &self.cfg.input,
1595            &self.module.context,
1596        ) {
1597            Ok(vi) => vi,
1598            Err((vi, es)) => {
1599                if pushed {
1600                    self.module.context.higher_order_caller.pop();
1601                }
1602                errs.extend(es);
1603                vi.unwrap_or(VarInfo::ILLEGAL)
1604            }
1605        };
1606        if let Err(es) = self.module.context.propagate(&mut vi.t, &obj) {
1607            errs.extend(es);
1608        }
1609        if let Some((guard, ret)) = guard.zip(vi.t.return_t()) {
1610            debug_assert!(
1611                self.module.context.subtype_of(ret, &Type::Bool),
1612                "{ret} is not a subtype of Bool",
1613            );
1614            if let Some(ret_t) = vi.t.mut_return_t() {
1615                *ret_t = guard;
1616            } else if let Some(mut ref_t) = vi.t.tyvar_mut_return_t() {
1617                *ref_t = guard;
1618            }
1619        }
1620        let attr_name = if let Some(attr_name) = call.attr_name {
1621            self.inc_ref(attr_name.inspect(), &vi, &attr_name.name);
1622            Some(hir::Identifier::new(attr_name, None, vi))
1623        } else {
1624            if let hir::Expr::Call(call) = &obj {
1625                if call.return_t().is_some() {
1626                    if let Some(ref_mut_t) = obj.ref_mut_t() {
1627                        *ref_mut_t = vi.t;
1628                    }
1629                }
1630            } else if let Some(ref_mut_t) = obj.ref_mut_t() {
1631                *ref_mut_t = vi.t;
1632            }
1633            None
1634        };
1635        let mut call = hir::Call::new(obj, attr_name, hir_args);
1636        if let Some((found, expect)) = call
1637            .signature_t()
1638            .and_then(|sig| sig.return_t())
1639            .zip(expect)
1640        {
1641            if let Err(_errs) = self.module.context.sub_unify(found, expect, &call, None) {
1642                // self.errs.extend(errs);
1643            }
1644        }
1645        if pushed {
1646            self.module.context.higher_order_caller.pop();
1647        }
1648        if errs.is_empty() {
1649            if let Err(es) = self.exec_additional_op(&mut call) {
1650                errs.extend(es);
1651            }
1652        }
1653        if errs.is_empty() {
1654            Ok(call)
1655        } else {
1656            Err((call, errs))
1657        }
1658    }
1659
1660    /// importing is done in [preregister](https://github.com/erg-lang/erg/blob/ffd33015d540ff5a0b853b28c01370e46e0fcc52/crates/erg_compiler/context/register.rs#L819)
1661    fn exec_additional_op(&mut self, call: &mut hir::Call) -> LowerResult<()> {
1662        match call.additional_operation() {
1663            Some(OperationKind::Del) => match call.args.get_left_or_key("obj") {
1664                Some(hir::Expr::Accessor(hir::Accessor::Ident(ident))) => {
1665                    self.module.context.del(ident)?;
1666                    Ok(())
1667                }
1668                other => {
1669                    let expr = other.map_or("nothing", |expr| expr.name());
1670                    Err(LowerErrors::from(LowerError::syntax_error(
1671                        self.input().clone(),
1672                        line!() as usize,
1673                        other.loc(),
1674                        self.module.context.caused_by(),
1675                        format!("expected identifier, but found {expr}"),
1676                        None,
1677                    )))
1678                }
1679            },
1680            Some(OperationKind::Return | OperationKind::Yield) => {
1681                // (f: ?T -> ?U).return: (self: Subroutine, arg: Obj) -> Never
1682                let callable_t = call.obj.ref_t();
1683                let ret_t = match callable_t {
1684                    Type::Subr(subr) => *subr.return_t.clone(),
1685                    Type::FreeVar(fv) if fv.get_sub().is_some() => {
1686                        fv.get_sub().unwrap().return_t().unwrap().clone()
1687                    }
1688                    other => {
1689                        log!(err "todo: {other}");
1690                        return unreachable_error!(LowerErrors, LowerError, self.module.context);
1691                    }
1692                };
1693                let arg_t = call.args.get(0).unwrap().ref_t();
1694                self.module.context.sub_unify(arg_t, &ret_t, call, None)?;
1695                Ok(())
1696            }
1697            Some(OperationKind::Assert) => {
1698                if let Some(Type::Guard(guard)) =
1699                    call.args.get_left_or_key("test").map(|exp| exp.ref_t())
1700                {
1701                    let test = call.args.get_left_or_key("test");
1702                    let test_args = if let Some(hir::Expr::Call(call)) = test {
1703                        Some(&call.args)
1704                    } else {
1705                        None
1706                    };
1707                    self.module
1708                        .context
1709                        .cast(guard.clone(), test_args, &mut vec![])?;
1710                }
1711                Ok(())
1712            }
1713            Some(OperationKind::Cast) => {
1714                self.warns.push(LowerWarning::use_cast_warning(
1715                    self.input().clone(),
1716                    line!() as usize,
1717                    call.loc(),
1718                    self.module.context.caused_by(),
1719                ));
1720                Ok(())
1721            }
1722            _ => Ok(()),
1723        }
1724    }
1725
1726    fn lower_pack(&mut self, pack: ast::DataPack, _expect: Option<&Type>) -> Failable<hir::Call> {
1727        log!(info "entered {}({pack})", fn_name!());
1728        let mut errors = LowerErrors::empty();
1729        let class = match self.lower_expr(*pack.class, None) {
1730            Ok(class) => class,
1731            Err((class, es)) => {
1732                errors.extend(es);
1733                class.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
1734            }
1735        };
1736        let args = match self.lower_record(pack.args, None) {
1737            Ok(args) => args,
1738            Err((args, es)) => {
1739                errors.extend(es);
1740                args
1741            }
1742        };
1743        let mut args = vec![hir::PosArg::new(hir::Expr::Record(args))];
1744        let attr_name = ast::Identifier::new(
1745            VisModifierSpec::Public(
1746                Token::new(
1747                    TokenKind::Dot,
1748                    Str::ever("."),
1749                    pack.connector.ln_begin().unwrap_or(0),
1750                    pack.connector.col_begin().unwrap_or(0),
1751                )
1752                .loc(),
1753            ),
1754            ast::VarName::new(Token::new(
1755                TokenKind::Symbol,
1756                Str::ever("new"),
1757                pack.connector.ln_begin().unwrap_or(0),
1758                pack.connector.col_begin().unwrap_or(0),
1759            )),
1760        );
1761        let vi = match self.module.context.get_call_t(
1762            &class,
1763            &Some(attr_name.clone()),
1764            &mut args,
1765            &[],
1766            (None, None),
1767            &self.cfg.input,
1768            &self.module.context,
1769        ) {
1770            Ok(vi) => vi,
1771            Err((vi, errs)) => {
1772                errors.extend(errs);
1773                vi.unwrap_or(VarInfo::ILLEGAL)
1774            }
1775        };
1776        let args = hir::Args::pos_only(args, None);
1777        let attr_name = hir::Identifier::new(attr_name, None, vi);
1778        let call = hir::Call::new(class, Some(attr_name), args);
1779        if errors.is_empty() {
1780            Ok(call)
1781        } else {
1782            Err((call, errors))
1783        }
1784    }
1785
1786    fn lower_non_default_param(
1787        &mut self,
1788        non_default: ast::NonDefaultParamSignature,
1789    ) -> LowerResult<hir::NonDefaultParamSignature> {
1790        let t_spec_as_expr = non_default
1791            .t_spec
1792            .as_ref()
1793            .map(|t_spec_op| self.fake_lower_expr(*t_spec_op.t_spec_as_expr.clone()))
1794            .transpose()?;
1795        // TODO: define here (not assign_params)
1796        let vi = VarInfo::default();
1797        let sig = hir::NonDefaultParamSignature::new(non_default, vi, t_spec_as_expr);
1798        Ok(sig)
1799    }
1800
1801    fn lower_type_spec_with_op(
1802        &mut self,
1803        type_spec_with_op: ast::TypeSpecWithOp,
1804        spec_t: Type,
1805    ) -> Failable<hir::TypeSpecWithOp> {
1806        match self.fake_lower_expr(*type_spec_with_op.t_spec_as_expr.clone()) {
1807            Ok(expr) => Ok(hir::TypeSpecWithOp::new(type_spec_with_op, expr, spec_t)),
1808            Err(es) => {
1809                let expr = hir::Expr::Dummy(hir::Dummy::empty());
1810                let t_spec = hir::TypeSpecWithOp::new(type_spec_with_op, expr, spec_t);
1811                Err((t_spec, es))
1812            }
1813        }
1814    }
1815
1816    /// lower and assign params
1817    fn lower_params(
1818        &mut self,
1819        params: ast::Params,
1820        bounds: ast::TypeBoundSpecs,
1821        expect: Option<&SubrType>,
1822    ) -> Failable<hir::Params> {
1823        log!(info "entered {}({})", fn_name!(), params);
1824        let mut errs = LowerErrors::empty();
1825        let mut tmp_tv_ctx = match self
1826            .module
1827            .context
1828            .instantiate_ty_bounds(&bounds, RegistrationMode::Normal)
1829        {
1830            Ok(tv_ctx) => tv_ctx,
1831            Err((tv_ctx, es)) => {
1832                errs.extend(es);
1833                tv_ctx
1834            }
1835        };
1836        let mut hir_non_defaults = vec![];
1837        for non_default in params.non_defaults.into_iter() {
1838            match self.lower_non_default_param(non_default) {
1839                Ok(sig) => hir_non_defaults.push(sig),
1840                Err(es) => errs.extend(es),
1841            }
1842        }
1843        let hir_var_params = match params.var_params {
1844            Some(var_params) => match self.lower_non_default_param(*var_params) {
1845                Ok(sig) => Some(Box::new(sig)),
1846                Err(es) => {
1847                    errs.extend(es);
1848                    None
1849                }
1850            },
1851            None => None,
1852        };
1853        let mut hir_defaults = vec![];
1854        for (n, default) in params.defaults.into_iter().enumerate() {
1855            let default_t =
1856                expect.and_then(|subr| subr.default_params.get(n).and_then(|pt| pt.default_typ()));
1857            match self.lower_expr(default.default_val, default_t) {
1858                Ok(default_val) => {
1859                    let sig = match self.lower_non_default_param(default.sig) {
1860                        Ok(sig) => sig,
1861                        Err(es) => {
1862                            errs.extend(es);
1863                            continue;
1864                        }
1865                    };
1866                    if let Some(expect) = expect.and_then(|subr| subr.default_params.get(n)) {
1867                        if !self
1868                            .module
1869                            .context
1870                            .subtype_of(default_val.ref_t(), expect.typ())
1871                        {
1872                            let err = LowerError::type_mismatch_error(
1873                                self.cfg.input.clone(),
1874                                line!() as usize,
1875                                default_val.loc(),
1876                                self.module.context.caused_by(),
1877                                sig.inspect().unwrap_or(&"_".into()),
1878                                None,
1879                                expect.typ(),
1880                                default_val.ref_t(),
1881                                None,
1882                                None,
1883                            );
1884                            errs.push(err);
1885                        }
1886                    }
1887                    hir_defaults.push(hir::DefaultParamSignature::new(sig, default_val));
1888                }
1889                Err((_default, es)) => errs.extend(es),
1890            }
1891        }
1892        let hir_kw_var_params = match params.kw_var_params {
1893            Some(kw_var_params) => match self.lower_non_default_param(*kw_var_params) {
1894                Ok(sig) => Some(Box::new(sig)),
1895                Err(es) => {
1896                    errs.extend(es);
1897                    None
1898                }
1899            },
1900            None => None,
1901        };
1902        let mut hir_params = hir::Params::new(
1903            hir_non_defaults,
1904            hir_var_params,
1905            hir_defaults,
1906            hir_kw_var_params,
1907            vec![],
1908            params.parens,
1909        );
1910        if let Err(es) =
1911            self.module
1912                .context
1913                .assign_params(&mut hir_params, &mut tmp_tv_ctx, expect.cloned())
1914        {
1915            errs.extend(es);
1916        }
1917        for guard in params.guards.into_iter() {
1918            let lowered = match guard {
1919                ast::GuardClause::Bind(bind) => self
1920                    .lower_def(bind, None)
1921                    .map(hir::GuardClause::Bind)
1922                    .map_err(|(def, es)| (def.map(hir::GuardClause::Bind), es)),
1923                // TODO: no fake
1924                ast::GuardClause::Condition(cond) => self
1925                    .fake_lower_expr(cond)
1926                    .map(hir::GuardClause::Condition)
1927                    .map_err(|es| (None, es)),
1928            };
1929            match lowered {
1930                Ok(guard) => {
1931                    if hir_params.guards.contains(&guard) {
1932                        log!(err "duplicate guard: {guard}");
1933                        continue;
1934                    }
1935                    hir_params.guards.push(guard)
1936                }
1937                Err((guard, es)) => {
1938                    if let Some(guard) = guard {
1939                        hir_params.guards.push(guard);
1940                    }
1941                    errs.extend(es)
1942                }
1943            }
1944        }
1945        if !errs.is_empty() {
1946            Err((hir_params, errs))
1947        } else {
1948            Ok(hir_params)
1949        }
1950    }
1951
1952    fn lower_lambda(
1953        &mut self,
1954        lambda: ast::Lambda,
1955        expect: Option<&Type>,
1956    ) -> Failable<hir::Lambda> {
1957        let mut errors = LowerErrors::empty();
1958        let expect = expect.and_then(|t| <&SubrType>::try_from(t).ok());
1959        let return_t = expect.map(|subr| subr.return_t.as_ref());
1960        log!(info "entered {}({lambda})", fn_name!());
1961        let in_statement = PYTHON_MODE
1962            && self
1963                .module
1964                .context
1965                .control_kind()
1966                .is_some_and(|k| k.makes_scope());
1967        let is_procedural = lambda.is_procedural();
1968        let id = lambda.id.0;
1969        let name = format!("<lambda_{id}>");
1970        let kind = if is_procedural {
1971            ContextKind::LambdaProc(self.module.context.control_kind())
1972        } else {
1973            ContextKind::LambdaFunc(self.module.context.control_kind())
1974        };
1975        let tv_cache = match self
1976            .module
1977            .context
1978            .instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)
1979        {
1980            Ok(tv_cache) => tv_cache,
1981            Err((tv_cache, es)) => {
1982                errors.extend(es);
1983                tv_cache
1984            }
1985        };
1986        if !in_statement {
1987            self.module
1988                .context
1989                .grow(&name, kind, Private, Some(tv_cache));
1990        }
1991        let params = match self.lower_params(lambda.sig.params, lambda.sig.bounds, expect) {
1992            Ok(params) => params,
1993            Err((params, es)) => {
1994                errors.extend(es);
1995                params
1996            }
1997        };
1998        let overwritten = {
1999            let mut overwritten = vec![];
2000            let guards = if in_statement {
2001                mem::take(&mut self.module.context.guards)
2002            } else {
2003                mem::take(&mut self.module.context.get_mut_outer().unwrap().guards)
2004            };
2005            for guard in guards.into_iter() {
2006                if let Err(errs) = self.module.context.cast(guard, None, &mut overwritten) {
2007                    errors.extend(errs);
2008                }
2009            }
2010            overwritten
2011        };
2012        if let Err(errs) = self.module.context.register_defs(&lambda.body) {
2013            errors.extend(errs);
2014        }
2015        let body = match self.lower_block(lambda.body, return_t) {
2016            Ok(body) => body,
2017            Err((body, es)) => {
2018                errors.extend(es);
2019                body
2020            }
2021        };
2022        if in_statement {
2023            for (var, vi) in overwritten.into_iter() {
2024                if vi.kind.is_parameter() {
2025                    // removed from `locals` and remains in `params`
2026                    self.module.context.locals.remove(&var);
2027                } else {
2028                    self.module.context.locals.insert(var, vi);
2029                }
2030            }
2031        }
2032        // suppress warns of lambda types, e.g. `(x: Int, y: Int) -> Int`
2033        if self.module.context.subtype_of(body.ref_t(), &Type::Type) {
2034            for param in params.non_defaults.iter() {
2035                self.inc_ref(param.inspect().unwrap_or(&"_".into()), &param.vi, param);
2036            }
2037            if let Some(var_param) = params.var_params.as_deref() {
2038                self.inc_ref(
2039                    var_param.inspect().unwrap_or(&"_".into()),
2040                    &var_param.vi,
2041                    var_param,
2042                );
2043            }
2044            for default in params.defaults.iter() {
2045                self.inc_ref(
2046                    default.sig.inspect().unwrap_or(&"_".into()),
2047                    &default.sig.vi,
2048                    &default.sig,
2049                );
2050            }
2051            if let Some(kw_var_param) = params.kw_var_params.as_deref() {
2052                self.inc_ref(
2053                    kw_var_param.inspect().unwrap_or(&"_".into()),
2054                    &kw_var_param.vi,
2055                    kw_var_param,
2056                );
2057            }
2058        }
2059        let non_default_params = params
2060            .non_defaults
2061            .iter()
2062            .map(|param| {
2063                ParamTy::pos_or_kw(
2064                    param.name().map(|n| n.inspect().clone()),
2065                    param.vi.t.clone(),
2066                )
2067            })
2068            .collect::<Vec<_>>();
2069        let default_params = params
2070            .defaults
2071            .iter()
2072            .map(|param| {
2073                ParamTy::kw(
2074                    param.name().unwrap().inspect().clone(),
2075                    param.sig.vi.t.clone(),
2076                )
2077            })
2078            .collect::<Vec<_>>();
2079        let var_params = params.var_params.as_ref().map(|param| {
2080            ParamTy::pos_or_kw(
2081                param.name().map(|n| n.inspect().clone()),
2082                param
2083                    .vi
2084                    .t
2085                    .inner_ts()
2086                    .first()
2087                    .map_or(Type::Obj, |t| t.clone()),
2088            )
2089        });
2090        let kw_var_params = params
2091            .kw_var_params
2092            .as_ref()
2093            .map(|param| ParamTy::kw(param.name().unwrap().inspect().clone(), param.vi.t.clone()));
2094        let captured_names = mem::take(&mut self.module.context.captured_names);
2095        if in_statement {
2096            // For example, `i` in `for i in ...` is a parameter,
2097            // but should be treated as a local variable in the later analysis, so move it to locals
2098            for nd_param in params.non_defaults.iter() {
2099                if let Some(idx) = self
2100                    .module
2101                    .context
2102                    .params
2103                    .iter()
2104                    .position(|(name, _)| name.as_ref() == nd_param.name())
2105                {
2106                    let (name, vi) = self.module.context.params.remove(idx);
2107                    if let Some(name) = name {
2108                        self.module.context.locals.insert(name, vi);
2109                    }
2110                }
2111            }
2112        } else {
2113            self.pop_append_errs();
2114        }
2115        let ty = if is_procedural {
2116            proc(
2117                non_default_params,
2118                var_params,
2119                default_params,
2120                kw_var_params,
2121                body.t(),
2122            )
2123        } else {
2124            func(
2125                non_default_params,
2126                var_params,
2127                default_params,
2128                kw_var_params,
2129                body.t(),
2130            )
2131        };
2132        let t = if ty.has_unbound_var() {
2133            // TODO:
2134            // use crate::ty::free::HasLevel;
2135            // ty.lift();
2136            // self.module.context.generalize_t(ty)
2137            ty.quantify()
2138        } else {
2139            ty
2140        };
2141        let return_t_spec = lambda.sig.return_t_spec.map(|t_spec| t_spec.t_spec);
2142        let lambda = hir::Lambda::new(
2143            id,
2144            params,
2145            lambda.op,
2146            return_t_spec,
2147            captured_names,
2148            body,
2149            t,
2150        );
2151        if !errors.is_empty() {
2152            Err((lambda, errors))
2153        } else {
2154            Ok(lambda)
2155        }
2156    }
2157
2158    fn lower_def(&mut self, def: ast::Def, expect_body: Option<&Type>) -> FailableOption<hir::Def> {
2159        log!(info "entered {}({})", fn_name!(), def.sig);
2160        let mut errors = LowerErrors::empty();
2161        if def.def_kind().is_class_or_trait() && self.module.context.kind != ContextKind::Module {
2162            self.module
2163                .context
2164                .decls
2165                .remove(def.sig.ident().unwrap().inspect());
2166            let err = LowerError::inner_typedef_error(
2167                self.cfg.input.clone(),
2168                line!() as usize,
2169                def.loc(),
2170                self.module.context.caused_by(),
2171            );
2172            errors.push(err);
2173        }
2174        let name = if let Some(name) = def.sig.name_as_str() {
2175            name.clone()
2176        } else {
2177            Str::ever("<lambda>")
2178        };
2179        if ERG_MODE && (&name[..] == "module" || &name[..] == "global") {
2180            let err = LowerError::shadow_special_namespace_error(
2181                self.cfg.input.clone(),
2182                line!() as usize,
2183                def.sig.loc(),
2184                self.module.context.caused_by(),
2185                &name,
2186            );
2187            errors.push(err);
2188        } else if self
2189            .module
2190            .context
2191            .registered_info(&name, def.sig.is_const())
2192            .is_some()
2193            && def.sig.vis().is_private()
2194        {
2195            let err = LowerError::reassign_error(
2196                self.cfg.input.clone(),
2197                line!() as usize,
2198                def.sig.loc(),
2199                self.module.context.caused_by(),
2200                &name,
2201            );
2202            errors.push(err);
2203        } else if self
2204            .module
2205            .context
2206            .get_builtins()
2207            .and_then(|ctx| ctx.get_var_info(&name))
2208            .is_some()
2209            && def.sig.vis().is_private()
2210        {
2211            self.warns.push(LowerWarning::builtin_exists_warning(
2212                self.cfg.input.clone(),
2213                line!() as usize,
2214                def.sig.loc(),
2215                self.module.context.caused_by(),
2216                &name,
2217            ));
2218        }
2219        let kind = ContextKind::from(&def);
2220        let vis = match self.module.context.instantiate_vis_modifier(def.sig.vis()) {
2221            Ok(vis) => vis,
2222            Err(errs) => {
2223                errors.extend(errs);
2224                VisibilityModifier::Public
2225            }
2226        };
2227        let res = match def.sig {
2228            ast::Signature::Subr(sig) => {
2229                let tv_cache = match self
2230                    .module
2231                    .context
2232                    .instantiate_ty_bounds(&sig.bounds, RegistrationMode::Normal)
2233                {
2234                    Ok(tv_cache) => tv_cache,
2235                    Err((tv_cache, errs)) => {
2236                        errors.extend(errs);
2237                        tv_cache
2238                    }
2239                };
2240                self.module.context.grow(&name, kind, vis, Some(tv_cache));
2241                self.lower_subr_def(sig, def.body)
2242                    .map_err(|(def, es)| (Some(def), errors.concat(es)))
2243            }
2244            ast::Signature::Var(sig) => {
2245                self.module.context.grow(&name, kind, vis, None);
2246                self.lower_var_def(sig, def.body, expect_body)
2247            }
2248        };
2249        // TODO: Context上の関数に型境界情報を追加
2250        self.pop_append_errs();
2251        // remove from decls regardless of success or failure to lower
2252        self.module.context.decls.remove(&name);
2253        res
2254    }
2255
2256    fn lower_var_def(
2257        &mut self,
2258        sig: ast::VarSignature,
2259        body: ast::DefBody,
2260        expect_body: Option<&Type>,
2261    ) -> FailableOption<hir::Def> {
2262        log!(info "entered {}({sig})", fn_name!());
2263        let mut errors = LowerErrors::empty();
2264        if let Err(errs) = self.module.context.register_defs(&body.block) {
2265            errors.extend(errs);
2266        }
2267        let outer = self.module.context.outer.as_ref().unwrap();
2268        let existing_vi = sig
2269            .ident()
2270            .and_then(|ident| outer.get_current_scope_var(&ident.name))
2271            .cloned();
2272        let existing_t = existing_vi.as_ref().map(|vi| vi.t.clone());
2273        let expect_body_t = sig
2274            .t_spec
2275            .as_ref()
2276            .map(|t_spec| {
2277                match self
2278                    .module
2279                    .context
2280                    .instantiate_var_sig_t(Some(&t_spec.t_spec), RegistrationMode::PreRegister)
2281                {
2282                    Ok(t) => t,
2283                    // REVIEW:
2284                    Err((t, _errs)) => t,
2285                }
2286            })
2287            .or_else(|| {
2288                sig.ident()
2289                    .and_then(|ident| outer.get_current_param_or_decl(ident.inspect()))
2290                    .map(|vi| vi.t.clone())
2291            });
2292        match self.lower_block(body.block, expect_body.or(expect_body_t.as_ref())) {
2293            Ok(block) => {
2294                let found_body_t = block.ref_t();
2295                let ident = match &sig.pat {
2296                    ast::VarPattern::Ident(ident) | ast::VarPattern::Phi(ident) => ident.clone(),
2297                    ast::VarPattern::Discard(token) => {
2298                        ast::Identifier::private_from_token(token.clone())
2299                    }
2300                    ast::VarPattern::Glob(token) => {
2301                        return self
2302                            .lower_glob(token.clone(), hir::DefBody::new(body.op, block, body.id))
2303                            .map_err(|errs| (None, errors.concat(errs)));
2304                    }
2305                    other => {
2306                        log!(err "unexpected pattern: {other}");
2307                        return unreachable_error!(LowerErrors, LowerError, self.module.context)
2308                            .map_err(|errs| (None, errors.concat(errs)));
2309                    }
2310                };
2311                let mut no_reassign = false;
2312                if let Some(expect_body_t) = expect_body_t {
2313                    // TODO: expect_body_t is smaller for constants
2314                    // TODO: 定数の場合、expect_body_tのほうが小さくなってしまう
2315                    if !sig.is_const() {
2316                        if let Err(e) = self.var_result_t_check(
2317                            &sig,
2318                            ident.inspect(),
2319                            &expect_body_t,
2320                            found_body_t,
2321                        ) {
2322                            errors.push(e);
2323                            no_reassign = true;
2324                        }
2325                    }
2326                }
2327                let found_body_t = if sig.is_phi() {
2328                    self.module
2329                        .context
2330                        .union(existing_t.as_ref().unwrap_or(&Type::Never), found_body_t)
2331                } else {
2332                    found_body_t.clone()
2333                };
2334                let vi = if no_reassign {
2335                    VarInfo {
2336                        t: found_body_t,
2337                        ..existing_vi.unwrap_or_default()
2338                    }
2339                } else {
2340                    match self.module.context.outer.as_mut().unwrap().assign_var_sig(
2341                        &sig,
2342                        &found_body_t,
2343                        body.id,
2344                        block.last(),
2345                        None,
2346                    ) {
2347                        Ok(vi) => vi,
2348                        Err(errs) => {
2349                            errors.extend(errs);
2350                            VarInfo::ILLEGAL
2351                        }
2352                    }
2353                };
2354                let ident = hir::Identifier::new(ident, None, vi);
2355                let t_spec = if let Some(ts) = sig.t_spec {
2356                    let spec_t = match self.module.context.instantiate_typespec(&ts.t_spec) {
2357                        Ok(spec_t) => spec_t,
2358                        Err((spec_t, errs)) => {
2359                            errors.extend(errs);
2360                            spec_t
2361                        }
2362                    };
2363                    let expr = match self.fake_lower_expr(*ts.t_spec_as_expr.clone()) {
2364                        Ok(expr) => expr,
2365                        Err(errs) => {
2366                            errors.extend(errs);
2367                            hir::Expr::Dummy(hir::Dummy::empty())
2368                        }
2369                    };
2370                    Some(hir::TypeSpecWithOp::new(*ts, expr, spec_t))
2371                } else {
2372                    None
2373                };
2374                let sig = hir::VarSignature::new(ident, t_spec);
2375                let body = hir::DefBody::new(body.op, block, body.id);
2376                let def = hir::Def::new(hir::Signature::Var(sig), body);
2377                if errors.is_empty() {
2378                    Ok(def)
2379                } else {
2380                    Err((Some(def), errors))
2381                }
2382            }
2383            Err((block, errs)) => {
2384                errors.extend(errs);
2385                let found_body_t = block.ref_t();
2386                let ident = match &sig.pat {
2387                    ast::VarPattern::Ident(ident) | ast::VarPattern::Phi(ident) => ident.clone(),
2388                    ast::VarPattern::Discard(token) => {
2389                        ast::Identifier::private_from_token(token.clone())
2390                    }
2391                    ast::VarPattern::Glob(token) => {
2392                        return self
2393                            .lower_glob(token.clone(), hir::DefBody::new(body.op, block, body.id))
2394                            .map_err(|errs| (None, errors.concat(errs)));
2395                    }
2396                    other => {
2397                        log!(err "unexpected pattern: {other}");
2398                        return unreachable_error!(LowerErrors, LowerError, self.module.context)
2399                            .map_err(|errs| (None, errors.concat(errs)));
2400                    }
2401                };
2402                let found_body_t = if sig.is_phi() {
2403                    self.module
2404                        .context
2405                        .union(existing_t.as_ref().unwrap_or(&Type::Never), found_body_t)
2406                } else {
2407                    found_body_t.clone()
2408                };
2409                if let Err(errs) = self.module.context.outer.as_mut().unwrap().assign_var_sig(
2410                    &sig,
2411                    &found_body_t,
2412                    ast::DefId(0),
2413                    None,
2414                    None,
2415                ) {
2416                    errors.extend(errs);
2417                }
2418                let ident = hir::Identifier::new(ident, None, VarInfo::ILLEGAL);
2419                let sig = hir::VarSignature::new(ident, None);
2420                let body = hir::DefBody::new(body.op, block, body.id);
2421                let def = hir::Def::new(hir::Signature::Var(sig), body);
2422                Err((Some(def), errors))
2423            }
2424        }
2425    }
2426
2427    fn lower_glob(&mut self, token: Token, body: hir::DefBody) -> LowerResult<hir::Def> {
2428        let names = vec![];
2429        if let Some(path) = body.ref_t().module_path() {
2430            if let Some(module) = self.module.context.get_mod_with_path(&path) {
2431                for (name, vi) in module.local_dir().cloned() {
2432                    self.module
2433                        .context
2434                        .get_mut_outer()
2435                        .unwrap()
2436                        .locals
2437                        .insert(name, vi);
2438                }
2439            }
2440        }
2441        let vis = VisibilityModifier::Public;
2442        let sig = hir::Signature::Glob(hir::GlobSignature::new(token, vis, names, body.t()));
2443        Ok(hir::Def::new(sig, body))
2444    }
2445
2446    // NOTE: Note that this is in the inner scope while being called.
2447    fn lower_subr_def(
2448        &mut self,
2449        sig: ast::SubrSignature,
2450        body: ast::DefBody,
2451    ) -> Failable<hir::Def> {
2452        log!(info "entered {}({sig})", fn_name!());
2453        let mut errors = LowerErrors::empty();
2454        let registered_t = self
2455            .module
2456            .context
2457            .outer
2458            .as_ref()
2459            .unwrap()
2460            .get_current_scope_var(&sig.ident.name)
2461            .map(|vi| vi.t.clone())
2462            .unwrap_or(Type::Failure);
2463        let mut decorators = set! {};
2464        for deco in sig.decorators.iter() {
2465            // exclude comptime decorators
2466            if self.module.context.eval_const_expr(&deco.0).is_ok() {
2467                continue;
2468            }
2469            let deco = match self.lower_expr(deco.0.clone(), Some(&mono("Subroutine"))) {
2470                Ok(deco) => deco,
2471                Err((Some(deco), es)) => {
2472                    errors.extend(es);
2473                    deco
2474                }
2475                Err((None, es)) => {
2476                    errors.extend(es);
2477                    continue;
2478                }
2479            };
2480            decorators.insert(deco);
2481        }
2482        match registered_t {
2483            Type::Subr(subr_t) => self.lower_subr_block(subr_t, sig, decorators, body),
2484            quant @ Type::Quantified(_) => {
2485                let instance = match self.module.context.instantiate_dummy(quant) {
2486                    Ok(instance) => instance,
2487                    Err(errs) => {
2488                        errors.extend(errs);
2489                        Type::Failure
2490                    }
2491                };
2492                let subr_t = SubrType::try_from(instance).unwrap_or(SubrType::failed());
2493                self.lower_subr_block(subr_t, sig, decorators, body)
2494            }
2495            _ => {
2496                let params = match self.lower_params(sig.params, sig.bounds.clone(), None) {
2497                    Ok(params) => params,
2498                    Err((params, errs)) => {
2499                        errors.extend(errs);
2500                        params
2501                    }
2502                };
2503                if let Err(errs) = self.module.context.register_defs(&body.block) {
2504                    errors.extend(errs);
2505                }
2506                if let Err(es) = self
2507                    .module
2508                    .context
2509                    .outer
2510                    .as_mut()
2511                    .unwrap()
2512                    .fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)
2513                {
2514                    errors.extend(es);
2515                }
2516                let block = match self.lower_block(body.block, None) {
2517                    Ok(block) => block,
2518                    Err((block, errs)) => {
2519                        errors.extend(errs);
2520                        block
2521                    }
2522                };
2523                let ident = hir::Identifier::bare(sig.ident);
2524                let ret_t_spec = if let Some(ts) = sig.return_t_spec {
2525                    let spec_t = match self.module.context.instantiate_typespec(&ts.t_spec) {
2526                        Ok(spec_t) => spec_t,
2527                        Err((spec_t, errs)) => {
2528                            errors.extend(errs);
2529                            spec_t
2530                        }
2531                    };
2532                    let expr = match self.fake_lower_expr(*ts.t_spec_as_expr.clone()) {
2533                        Ok(expr) => expr,
2534                        Err(errs) => {
2535                            errors.extend(errs);
2536                            hir::Expr::Dummy(hir::Dummy::empty())
2537                        }
2538                    };
2539                    Some(hir::TypeSpecWithOp::new(*ts, expr, spec_t))
2540                } else {
2541                    None
2542                };
2543                let captured_names = mem::take(&mut self.module.context.captured_names);
2544                let sig = hir::SubrSignature::new(
2545                    decorators,
2546                    ident,
2547                    sig.bounds,
2548                    params,
2549                    ret_t_spec,
2550                    captured_names,
2551                );
2552                let body = hir::DefBody::new(body.op, block, body.id);
2553                let def = hir::Def::new(hir::Signature::Subr(sig), body);
2554                if errors.is_empty() {
2555                    Ok(def)
2556                } else {
2557                    Err((def, errors))
2558                }
2559            }
2560        }
2561    }
2562
2563    fn lower_subr_block(
2564        &mut self,
2565        registered_subr_t: SubrType,
2566        sig: ast::SubrSignature,
2567        decorators: Set<hir::Expr>,
2568        body: ast::DefBody,
2569    ) -> Failable<hir::Def> {
2570        let mut errors = LowerErrors::empty();
2571        let params = match self.lower_params(
2572            sig.params.clone(),
2573            sig.bounds.clone(),
2574            Some(&registered_subr_t),
2575        ) {
2576            Ok(params) => params,
2577            Err((params, errs)) => {
2578                errors.extend(errs);
2579                params
2580            }
2581        };
2582        if let Err(errs) = self.module.context.register_defs(&body.block) {
2583            errors.extend(errs);
2584        }
2585        let return_t = registered_subr_t
2586            .return_t
2587            .has_no_unbound_var()
2588            .then_some(registered_subr_t.return_t.as_ref());
2589        match self.lower_block(body.block, return_t) {
2590            Ok(block) => {
2591                let found_body_t = self.module.context.squash_tyvar(block.t());
2592                let vi = match self.module.context.outer.as_mut().unwrap().assign_subr(
2593                    &sig,
2594                    body.id,
2595                    &params,
2596                    &found_body_t,
2597                    block.last().unwrap(),
2598                ) {
2599                    Ok(vi) => vi,
2600                    Err((errs, vi)) => {
2601                        errors.extend(errs);
2602                        vi
2603                    }
2604                };
2605                let ident = hir::Identifier::new(sig.ident, None, vi);
2606                let ret_t_spec = if let Some(ts) = sig.return_t_spec {
2607                    let spec_t = match self.module.context.instantiate_typespec(&ts.t_spec) {
2608                        Ok(spec_t) => spec_t,
2609                        Err((spec_t, errs)) => {
2610                            errors.extend(errs);
2611                            spec_t
2612                        }
2613                    };
2614                    let expr = match self.fake_lower_expr(*ts.t_spec_as_expr.clone()) {
2615                        Ok(expr) => expr,
2616                        Err(errs) => {
2617                            errors.extend(errs);
2618                            hir::Expr::Dummy(hir::Dummy::empty())
2619                        }
2620                    };
2621                    Some(hir::TypeSpecWithOp::new(*ts, expr, spec_t))
2622                } else {
2623                    None
2624                };
2625                let captured_names = mem::take(&mut self.module.context.captured_names);
2626                let sig = hir::SubrSignature::new(
2627                    decorators,
2628                    ident,
2629                    sig.bounds,
2630                    params,
2631                    ret_t_spec,
2632                    captured_names,
2633                );
2634                let body = hir::DefBody::new(body.op, block, body.id);
2635                let def = hir::Def::new(hir::Signature::Subr(sig), body);
2636                if errors.is_empty() {
2637                    Ok(def)
2638                } else {
2639                    Err((def, errors))
2640                }
2641            }
2642            Err((block, errs)) => {
2643                errors.extend(errs);
2644                let found_body_t = self.module.context.squash_tyvar(block.t());
2645                let vi = match self.module.context.outer.as_mut().unwrap().assign_subr(
2646                    &sig,
2647                    ast::DefId(0),
2648                    &params,
2649                    &found_body_t,
2650                    &sig,
2651                ) {
2652                    Ok(vi) => vi,
2653                    Err((errs, vi)) => {
2654                        errors.extend(errs);
2655                        vi
2656                    }
2657                };
2658                let ident = hir::Identifier::new(sig.ident, None, vi);
2659                let ret_t_spec = if let Some(ts) = sig.return_t_spec {
2660                    let spec_t = match self.module.context.instantiate_typespec(&ts.t_spec) {
2661                        Ok(spec_t) => spec_t,
2662                        Err((spec_t, errs)) => {
2663                            errors.extend(errs);
2664                            spec_t
2665                        }
2666                    };
2667                    let expr = match self.fake_lower_expr(*ts.t_spec_as_expr.clone()) {
2668                        Ok(expr) => expr,
2669                        Err(errs) => {
2670                            errors.extend(errs);
2671                            hir::Expr::Dummy(hir::Dummy::empty())
2672                        }
2673                    };
2674                    Some(hir::TypeSpecWithOp::new(*ts, expr, spec_t))
2675                } else {
2676                    None
2677                };
2678                let captured_names = mem::take(&mut self.module.context.captured_names);
2679                let sig = hir::SubrSignature::new(
2680                    decorators,
2681                    ident,
2682                    sig.bounds,
2683                    params,
2684                    ret_t_spec,
2685                    captured_names,
2686                );
2687                let body = hir::DefBody::new(body.op, block, body.id);
2688                let def = hir::Def::new(hir::Signature::Subr(sig), body);
2689                if errors.is_empty() {
2690                    Ok(def)
2691                } else {
2692                    Err((def, errors))
2693                }
2694            }
2695        }
2696    }
2697
2698    fn lower_class_def(&mut self, class_def: ast::ClassDef) -> Failable<hir::ClassDef> {
2699        log!(info "entered {}({class_def})", fn_name!());
2700        let mut errors = LowerErrors::empty();
2701        let (is_inherit, sig, mut block) = match self.lower_def(class_def.def, None) {
2702            Ok(def) => (def.def_kind().is_inherit(), def.sig, def.body.block),
2703            Err((Some(def), errs)) => {
2704                errors.extend(errs);
2705                (false, def.sig, def.body.block)
2706            }
2707            Err((None, errs)) => {
2708                errors.extend(errs);
2709                let var = hir::VarSignature::new(hir::Identifier::public("<error>"), None);
2710                (false, hir::Signature::Var(var), hir::Block::empty())
2711            }
2712        };
2713        let mut hir_methods_list = vec![];
2714        let mut implemented = set! {};
2715        for methods in class_def.methods_list.into_iter() {
2716            let mut hir_methods = hir::Block::empty();
2717            let (class, impl_trait) =
2718                match self.module.context.get_class_and_impl_trait(&methods.class) {
2719                    Ok(x) => x,
2720                    Err((class, trait_, errs)) => {
2721                        errors.extend(errs);
2722                        (class.unwrap_or(Type::Obj), trait_)
2723                    }
2724                };
2725            if let Some(class_root) = self.module.context.get_nominal_type_ctx(&class) {
2726                if !class_root.kind.is_class() {
2727                    let err = LowerError::method_definition_error(
2728                        self.cfg.input.clone(),
2729                        line!() as usize,
2730                        methods.loc(),
2731                        self.module.context.caused_by(),
2732                        &class.qual_name(),
2733                        None,
2734                    );
2735                    errors.push(err);
2736                }
2737            } else {
2738                let err = LowerError::no_var_error(
2739                    self.cfg.input.clone(),
2740                    line!() as usize,
2741                    methods.class.loc(),
2742                    self.module.context.caused_by(),
2743                    &class.qual_name(),
2744                    self.module.context.get_similar_name(&class.local_name()),
2745                );
2746                errors.push(err);
2747            }
2748            let Some(methods_list) = self
2749                .module
2750                .context
2751                .get_mut_nominal_type_ctx(&class)
2752                .map(|ctx| &mut ctx.methods_list)
2753            else {
2754                let err = LowerError::unreachable(
2755                    self.cfg.input.clone(),
2756                    erg_common::fn_name!(),
2757                    line!(),
2758                );
2759                errors.push(err);
2760                continue;
2761            };
2762            let methods_idx = methods_list.iter().position(|m| m.id == methods.id);
2763            // We can't remove the method ctx here because methods' information must be hold
2764            let Some(methods_ctx) = methods_idx.map(|idx| methods_list[idx].clone()) else {
2765                let err = LowerError::unreachable(
2766                    self.cfg.input.clone(),
2767                    erg_common::fn_name!(),
2768                    line!(),
2769                );
2770                errors.push(err);
2771                continue;
2772            };
2773            self.module.context.replace(methods_ctx.ctx);
2774            for attr in methods.attrs.iter() {
2775                match attr {
2776                    ast::ClassAttr::Def(def) => {
2777                        if let Some(ident) = def.sig.ident() {
2778                            if self
2779                                .module
2780                                .context
2781                                .get_instance_attr(ident.inspect())
2782                                .is_some()
2783                            {
2784                                self.warns
2785                                    .push(CompileWarning::same_name_instance_attr_warning(
2786                                        self.cfg.input.clone(),
2787                                        line!() as usize,
2788                                        ident.loc(),
2789                                        self.module.context.caused_by(),
2790                                        ident.inspect(),
2791                                    ));
2792                            }
2793                        }
2794                    }
2795                    ast::ClassAttr::Decl(_) | ast::ClassAttr::Doc(_) => {}
2796                }
2797            }
2798            for attr in methods.attrs.into_iter() {
2799                match attr {
2800                    ast::ClassAttr::Def(def) => match self.lower_def(def, None) {
2801                        Ok(def) => {
2802                            hir_methods.push(hir::Expr::Def(def));
2803                        }
2804                        Err((def, errs)) => {
2805                            if let Some(def) = def {
2806                                hir_methods.push(hir::Expr::Def(def));
2807                            }
2808                            errors.extend(errs);
2809                        }
2810                    },
2811                    ast::ClassAttr::Decl(decl) => match self.lower_type_asc(decl, None) {
2812                        Ok(decl) => {
2813                            hir_methods.push(hir::Expr::TypeAsc(decl));
2814                        }
2815                        Err((tasc, errs)) => {
2816                            hir_methods.push(hir::Expr::TypeAsc(tasc));
2817                            errors.extend(errs);
2818                        }
2819                    },
2820                    ast::ClassAttr::Doc(doc) => match self.lower_literal(doc, None) {
2821                        Ok(doc) => {
2822                            hir_methods.push(hir::Expr::Literal(doc));
2823                        }
2824                        Err(errs) => {
2825                            errors.extend(errs);
2826                        }
2827                    },
2828                }
2829            }
2830            if let Some(methods_list) = self
2831                .module
2832                .context
2833                .get_mut_nominal_type_ctx(&class)
2834                .map(|ctx| &mut ctx.methods_list)
2835            {
2836                if let Some(idx) = methods_idx {
2837                    methods_list.remove(idx);
2838                }
2839            }
2840            if let Err(errs) = self.module.context.check_decls() {
2841                errors.extend(errs);
2842            }
2843            if let Some((trait_, _)) = &impl_trait {
2844                self.check_override(&class, Some(trait_));
2845            } else {
2846                self.check_override(&class, None);
2847            }
2848            if let Err(err) = self.check_trait_impl(impl_trait.clone(), &class, &mut implemented) {
2849                errors.push(err);
2850            }
2851            let impl_trait = impl_trait.map(|(t, _)| t);
2852            self.check_collision_and_push(methods.id, class.clone(), impl_trait.clone());
2853            hir_methods_list.push(hir::Methods::new(class, impl_trait, hir_methods));
2854        }
2855        let class = self.module.context.gen_type(&sig.ident().raw);
2856        let class_ctx = if let Some(ctx) = self.module.context.get_nominal_type_ctx(&class) {
2857            Some(ctx)
2858        } else {
2859            let err = LowerError::type_not_found(
2860                self.cfg.input.clone(),
2861                line!() as usize,
2862                sig.loc(),
2863                self.module.context.caused_by(),
2864                &class,
2865            );
2866            errors.push(err);
2867            None
2868        };
2869        let type_obj = match self
2870            .module
2871            .context
2872            .rec_get_const_obj(sig.ident().inspect())
2873            .cloned()
2874        {
2875            Some(ValueObj::Type(TypeObj::Generated(type_obj))) => type_obj,
2876            _ => GenTypeObj::class(Type::Failure, None, None, false),
2877        };
2878        if is_inherit {
2879            let call = match block.first() {
2880                Some(hir::Expr::Call(call)) => Some(call),
2881                _ => None,
2882            };
2883            if let Some(sup_type) = call.and_then(|call| call.args.get_left_or_key("Super")) {
2884                if let Err(err) = self.check_inheritable(&type_obj, sup_type, &sig) {
2885                    errors.extend(err);
2886                }
2887            }
2888        }
2889        let constructor = class_ctx
2890            .and_then(|ctx| {
2891                ctx.get_class_member(&VarName::from_static("__call__"), &self.module.context)
2892            })
2893            .map_or(Type::FAILURE, |vi| &vi.t);
2894        let need_to_gen_new = class_ctx
2895            .and_then(|ctx| ctx.get_current_scope_var(&VarName::from_static("new")))
2896            .is_some_and(|vi| vi.kind == VarKind::Auto);
2897        let require_or_sup = Self::get_require_or_sup_or_base(block.remove(0));
2898        let class_def = hir::ClassDef::new(
2899            type_obj,
2900            sig,
2901            require_or_sup,
2902            need_to_gen_new,
2903            constructor.clone(),
2904            hir_methods_list,
2905        );
2906        if errors.is_empty() {
2907            Ok(class_def)
2908        } else {
2909            Err((class_def, errors))
2910        }
2911    }
2912
2913    fn lower_patch_def(&mut self, class_def: ast::PatchDef) -> FailableOption<hir::PatchDef> {
2914        log!(info "entered {}({class_def})", fn_name!());
2915        let mut errors = LowerErrors::empty();
2916        let base_t = {
2917            let Some(ast::Expr::Call(call)) = class_def.def.body.block.get(0) else {
2918                return unreachable_error!(LowerErrors, LowerError, self)
2919                    .map_err(|errs| (None, errors.concat(errs)));
2920            };
2921            let base_t_expr = call.args.get_left_or_key("Base").unwrap();
2922            let spec = Parser::expr_to_type_spec(base_t_expr.clone()).unwrap();
2923            match self.module.context.instantiate_typespec(&spec) {
2924                Ok(t) => t,
2925                Err((t, errs)) => {
2926                    errors.extend(errs);
2927                    t
2928                }
2929            }
2930        };
2931        let mut hir_def = match self.lower_def(class_def.def, None) {
2932            Ok(def) => def,
2933            Err((_def, errs)) => {
2934                errors.extend(errs);
2935                return Err((None, errors));
2936            }
2937        };
2938        let base = Self::get_require_or_sup_or_base(hir_def.body.block.remove(0)).unwrap();
2939        let mut hir_methods = hir::Block::empty();
2940        for mut methods in class_def.methods_list.into_iter() {
2941            let kind = ContextKind::PatchMethodDefs(base_t.clone());
2942            self.module.context.grow(
2943                hir_def.sig.ident().inspect(),
2944                kind,
2945                hir_def.sig.vis().clone(),
2946                None,
2947            );
2948            for attr in methods.attrs.iter_mut() {
2949                match attr {
2950                    ast::ClassAttr::Def(def) => {
2951                        if methods.vis.is_public() {
2952                            def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(
2953                                Token::new(
2954                                    TokenKind::Dot,
2955                                    ".",
2956                                    def.sig.ln_begin().unwrap_or(0),
2957                                    def.sig.col_begin().unwrap_or(0),
2958                                )
2959                                .loc(),
2960                            );
2961                        }
2962                        if let Err(es) = self.module.context.register_def(def) {
2963                            errors.extend(es);
2964                        }
2965                    }
2966                    ast::ClassAttr::Decl(_) | ast::ClassAttr::Doc(_) => {}
2967                }
2968            }
2969            for attr in methods.attrs.into_iter() {
2970                match attr {
2971                    ast::ClassAttr::Def(def) => match self.lower_def(def, None) {
2972                        Ok(def) => {
2973                            hir_methods.push(hir::Expr::Def(def));
2974                        }
2975                        Err((def, errs)) => {
2976                            if let Some(def) = def {
2977                                hir_methods.push(hir::Expr::Def(def));
2978                            }
2979                            errors.extend(errs);
2980                        }
2981                    },
2982                    ast::ClassAttr::Decl(decl) => match self.lower_type_asc(decl, None) {
2983                        Ok(decl) => {
2984                            hir_methods.push(hir::Expr::TypeAsc(decl));
2985                        }
2986                        Err((tasc, errs)) => {
2987                            hir_methods.push(hir::Expr::TypeAsc(tasc));
2988                            errors.extend(errs);
2989                        }
2990                    },
2991                    ast::ClassAttr::Doc(doc) => match self.lower_literal(doc, None) {
2992                        Ok(doc) => {
2993                            hir_methods.push(hir::Expr::Literal(doc));
2994                        }
2995                        Err(errs) => {
2996                            errors.extend(errs);
2997                        }
2998                    },
2999                }
3000            }
3001            if let Err(errs) = self.module.context.check_decls() {
3002                errors.extend(errs);
3003            }
3004            self.push_patch(methods.id);
3005        }
3006        let patch = hir::PatchDef::new(hir_def.sig, base, hir_methods);
3007        if errors.is_empty() {
3008            Ok(patch)
3009        } else {
3010            Err((Some(patch), errors))
3011        }
3012    }
3013
3014    fn lower_redef(&mut self, redef: ast::ReDef) -> FailableOption<hir::Expr> {
3015        log!(info "entered {}({redef})", fn_name!());
3016        let mut errors = LowerErrors::empty();
3017        let mut attr = match self.lower_acc(redef.attr, None) {
3018            Ok(attr) => attr,
3019            Err((hir::Accessor::Ident(ident), _errs)) => {
3020                let pat = ast::VarPattern::Ident(ident.raw);
3021                let sig = ast::Signature::Var(ast::VarSignature::new(pat, None));
3022                let body = ast::DefBody::new_single(*redef.expr);
3023                let def = ast::Def::new(sig, body);
3024                return self
3025                    .lower_def(def, None)
3026                    .map(hir::Expr::Def)
3027                    .map_err(|(def, errs)| (def.map(hir::Expr::Def), errors.concat(errs)));
3028            }
3029            Err((acc, errs)) => {
3030                errors.extend(errs);
3031                acc
3032            }
3033        };
3034        let expr = match self.lower_expr(*redef.expr, None) {
3035            Ok(expr) => expr,
3036            Err((expr, errs)) => {
3037                errors.extend(errs);
3038                expr.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
3039            }
3040        };
3041        if let Err(err) =
3042            self.var_result_t_check(&attr, &Str::from(attr.show()), attr.ref_t(), expr.ref_t())
3043        {
3044            if PYTHON_MODE {
3045                if !self.widen_type(&mut attr, &expr) {
3046                    errors.push(err);
3047                }
3048            } else {
3049                errors.push(err);
3050            }
3051        }
3052        let redef = hir::ReDef::new(attr, hir::Block::new(vec![expr]));
3053        if errors.is_empty() {
3054            Ok(hir::Expr::ReDef(redef))
3055        } else {
3056            Err((Some(hir::Expr::ReDef(redef)), errors))
3057        }
3058    }
3059
3060    fn widen_type(&mut self, attr: &mut hir::Accessor, expr: &hir::Expr) -> bool {
3061        for sup in self
3062            .module
3063            .context
3064            .get_super_classes_or_self(attr.ref_t())
3065            .skip(1)
3066        {
3067            if sup == Type::Obj {
3068                break;
3069            }
3070            if self
3071                .var_result_t_check(attr, &Str::from(attr.show()), &sup, expr.ref_t())
3072                .is_ok()
3073            {
3074                if let Some(attr_t) = attr.ref_mut_t() {
3075                    *attr_t = sup.clone();
3076                }
3077                if let Some(ident) = attr.as_ident() {
3078                    if let Some(vi) = self
3079                        .module
3080                        .context
3081                        .rec_get_mut_var_info(&ident.raw, AccessKind::Name)
3082                    {
3083                        vi.t = sup;
3084                    }
3085                }
3086                return true;
3087            }
3088        }
3089        false
3090    }
3091
3092    fn check_inheritable(
3093        &self,
3094        type_obj: &GenTypeObj,
3095        sup_class: &hir::Expr,
3096        sub_sig: &hir::Signature,
3097    ) -> LowerResult<()> {
3098        if let Some(TypeObj::Generated(gen)) = type_obj.base_or_sup() {
3099            if let Some(ctx) = self.module.context.get_nominal_type_ctx(gen.typ()) {
3100                for super_trait in ctx.super_traits.iter() {
3101                    if self
3102                        .module
3103                        .context
3104                        .subtype_of(super_trait, &mono("InheritableType"))
3105                    {
3106                        return Ok(());
3107                    }
3108                }
3109            }
3110            if let Some(impls) = gen.impls() {
3111                if impls.contains_intersec(&mono("InheritableType")) {
3112                    return Ok(());
3113                }
3114            }
3115            return Err(LowerError::inheritance_error(
3116                self.cfg.input.clone(),
3117                line!() as usize,
3118                sup_class.to_string(),
3119                sup_class.loc(),
3120                sub_sig.ident().inspect().into(),
3121            )
3122            .into());
3123        }
3124        Ok(())
3125    }
3126
3127    fn check_override(&mut self, class: &Type, impl_trait: Option<&Type>) {
3128        if let Some(sups) = self.module.context.get_nominal_super_type_ctxs(class) {
3129            // exclude the first one because it is the class itself
3130            for sup in sups.into_iter().skip(1) {
3131                for (method_name, vi) in self.module.context.locals.iter().chain(
3132                    self.module
3133                        .context
3134                        .methods_list
3135                        .iter()
3136                        .flat_map(|c| c.locals.iter()),
3137                ) {
3138                    if let Some(sup_vi) = sup.get_current_scope_var(method_name) {
3139                        // must `@Override`
3140                        if let Some(decos) = &vi.comptime_decos {
3141                            if decos.contains("Override") {
3142                                continue;
3143                            }
3144                        }
3145                        if sup_vi.impl_of() != impl_trait {
3146                            continue;
3147                        }
3148                        self.errs.push(LowerError::override_error(
3149                            self.cfg.input.clone(),
3150                            line!() as usize,
3151                            method_name.inspect(),
3152                            method_name.loc(),
3153                            &from_str(&sup.name), // TODO: get super type
3154                            self.module.context.caused_by(),
3155                        ));
3156                    }
3157                }
3158            }
3159        }
3160    }
3161
3162    /// Inspect the Trait implementation for correctness,
3163    /// i.e., check that all required attributes are defined and that no extra attributes are defined
3164    fn check_trait_impl(
3165        &mut self, //: methods context
3166        impl_trait: Option<(Type, &TypeSpecWithOp)>,
3167        class: &Type,
3168        implemented: &mut Set<Type>,
3169    ) -> SingleLowerResult<()> {
3170        if let Some((impl_trait, t_spec)) = impl_trait {
3171            if let Some(mut sups) = self.module.context.get_super_traits(&impl_trait) {
3172                let outer = self.module.context.get_outer_scope().unwrap();
3173                let trait_ctx = outer.get_nominal_type_ctx(&impl_trait);
3174                let external_trait =
3175                    trait_ctx.is_none_or(|tr| !tr.name.starts_with(&outer.name[..]));
3176                if sups.any(|t| t == mono("Sealed")) && external_trait {
3177                    return Err(LowerError::sealed_trait_error(
3178                        self.cfg.input.clone(),
3179                        line!() as usize,
3180                        t_spec.loc(),
3181                        self.module.context.caused_by(),
3182                        &impl_trait.qual_name(),
3183                    ));
3184                }
3185            }
3186            let impl_trait = impl_trait.normalize();
3187            let (unverified_names, mut errors) = if let Some(typ_ctx) = self
3188                .module
3189                .context
3190                .get_outer_scope()
3191                .unwrap()
3192                .get_nominal_type_ctx(&impl_trait)
3193            {
3194                self.check_methods_compatibility(&impl_trait, class, typ_ctx, t_spec, implemented)
3195            } else {
3196                return Err(LowerError::no_type_error(
3197                    self.cfg.input.clone(),
3198                    line!() as usize,
3199                    t_spec.loc(),
3200                    self.module.context.caused_by(),
3201                    &impl_trait.qual_name(),
3202                    self.module
3203                        .context
3204                        .get_similar_name(&impl_trait.local_name()),
3205                ));
3206            };
3207            if !PYTHON_MODE {
3208                for unverified in unverified_names {
3209                    errors.push(LowerError::not_in_trait_error(
3210                        self.cfg.input.clone(),
3211                        line!() as usize,
3212                        self.module.context.caused_by(),
3213                        unverified.inspect(),
3214                        &impl_trait,
3215                        class,
3216                        None,
3217                        unverified.loc(),
3218                    ));
3219                }
3220            }
3221            self.errs.extend(errors);
3222        }
3223        Ok(())
3224    }
3225
3226    fn check_methods_compatibility(
3227        &self,
3228        impl_trait: &Type,
3229        class: &Type,
3230        TypeContext {
3231            typ: trait_type,
3232            ctx: trait_ctx,
3233        }: &TypeContext,
3234        t_spec: &TypeSpecWithOp,
3235        implemented: &mut Set<Type>,
3236    ) -> (Set<&VarName>, CompileErrors) {
3237        let mut errors = CompileErrors::empty();
3238        let mut unverified_names = self.module.context.locals.keys().collect::<Set<_>>();
3239        let mut super_impls = set! {};
3240        let retained_decls = |ctx: &Context, super_impls: &Set<&VarName>| {
3241            ctx.decls.clone().retained(|k, _| {
3242                let implemented_in_super = super_impls.contains(k);
3243                let class_decl = ctx.kind.is_class();
3244                !implemented_in_super && !class_decl
3245            })
3246        };
3247        let tys_decls = if self.module.context.is_class(trait_type) {
3248            vec![(impl_trait.clone(), retained_decls(trait_ctx, &super_impls))]
3249        } else if let Some(sups) = self.module.context.get_super_types(trait_type) {
3250            sups.map(|sup| {
3251                if implemented.linear_contains(&sup) {
3252                    return (sup, Dict::new());
3253                }
3254                let decls =
3255                    self.module
3256                        .context
3257                        .get_nominal_type_ctx(&sup)
3258                        .map_or(Dict::new(), |ctx| {
3259                            super_impls.extend(ctx.locals.keys());
3260                            for methods in &ctx.methods_list {
3261                                super_impls.extend(methods.locals.keys());
3262                            }
3263                            retained_decls(ctx, &super_impls)
3264                        });
3265                (sup, decls)
3266            })
3267            .collect::<Vec<_>>()
3268        } else {
3269            vec![(impl_trait.clone(), retained_decls(trait_ctx, &super_impls))]
3270        };
3271        for (impl_trait, decls) in tys_decls {
3272            for (decl_name, decl_vi) in decls {
3273                if let Some((name, vi)) = self.module.context.get_var_kv(decl_name.inspect()) {
3274                    let def_t = &vi.t;
3275                    let replaced_decl_t = decl_vi
3276                        .t
3277                        .clone()
3278                        .replace(trait_type, &impl_trait)
3279                        .replace(&impl_trait, class);
3280                    unverified_names.remove(name);
3281                    if !self.module.context.supertype_of(&replaced_decl_t, def_t) {
3282                        let hint = self
3283                            .module
3284                            .context
3285                            .get_simple_type_mismatch_hint(&replaced_decl_t, def_t);
3286                        errors.push(LowerError::trait_member_type_error(
3287                            self.cfg.input.clone(),
3288                            line!() as usize,
3289                            name.loc(),
3290                            self.module.context.caused_by(),
3291                            name.inspect(),
3292                            &impl_trait,
3293                            &decl_vi.t,
3294                            &vi.t,
3295                            hint,
3296                        ));
3297                    }
3298                } else {
3299                    errors.push(LowerError::trait_member_not_defined_error(
3300                        self.cfg.input.clone(),
3301                        line!() as usize,
3302                        self.module.context.caused_by(),
3303                        decl_name.inspect(),
3304                        &impl_trait,
3305                        class,
3306                        None,
3307                        t_spec.loc(),
3308                    ));
3309                }
3310            }
3311        }
3312        implemented.insert(trait_type.clone());
3313        (unverified_names, errors)
3314    }
3315
3316    fn check_collision_and_push(&mut self, id: DefId, class: Type, impl_trait: Option<Type>) {
3317        let methods = self.module.context.pop();
3318        self.module.context.register_methods(&class, &methods);
3319        let Some(class_root) = self.module.context.get_mut_nominal_type_ctx(&class) else {
3320            log!(err "{class} not found");
3321            return;
3322        };
3323        for (newly_defined_name, vi) in methods.locals.clone().into_iter() {
3324            for already_defined_methods in class_root.methods_list.iter_mut() {
3325                // TODO: 特殊化なら同じ名前でもOK
3326                // TODO: 定義のメソッドもエラー表示
3327                if let Some((_already_defined_name, already_defined_vi)) =
3328                    already_defined_methods.get_var_kv(newly_defined_name.inspect())
3329                {
3330                    if already_defined_vi.kind != VarKind::Auto
3331                        && already_defined_vi.impl_of() == vi.impl_of()
3332                    {
3333                        self.errs.push(LowerError::duplicate_definition_error(
3334                            self.cfg.input.clone(),
3335                            line!() as usize,
3336                            newly_defined_name.loc(),
3337                            methods.caused_by(),
3338                            newly_defined_name.inspect(),
3339                        ));
3340                    } else {
3341                        already_defined_methods
3342                            .locals
3343                            .remove(&newly_defined_name.inspect()[..]);
3344                    }
3345                }
3346            }
3347        }
3348        let typ = if let Some(impl_trait) = impl_trait {
3349            ClassDefType::impl_trait(class, impl_trait)
3350        } else {
3351            ClassDefType::Simple(class)
3352        };
3353        class_root
3354            .methods_list
3355            .push(MethodContext::new(id, typ, methods));
3356    }
3357
3358    fn push_patch(&mut self, id: DefId) {
3359        let methods = self.module.context.pop();
3360        let ContextKind::PatchMethodDefs(base) = &methods.kind else {
3361            unreachable!()
3362        };
3363        let patch_name = *methods.name.split_with(&["::", "."]).last().unwrap();
3364        let patch_root = self
3365            .module
3366            .context
3367            .patches
3368            .get_mut(patch_name)
3369            .unwrap_or_else(|| todo!("{} not found", methods.name));
3370        for (newly_defined_name, vi) in methods.locals.clone().into_iter() {
3371            for already_defined_methods in patch_root.methods_list.iter_mut() {
3372                // TODO: 特殊化なら同じ名前でもOK
3373                // TODO: 定義のメソッドもエラー表示
3374                if let Some((_already_defined_name, already_defined_vi)) =
3375                    already_defined_methods.get_var_kv(newly_defined_name.inspect())
3376                {
3377                    if already_defined_vi.kind != VarKind::Auto
3378                        && already_defined_vi.impl_of() == vi.impl_of()
3379                    {
3380                        self.errs.push(LowerError::duplicate_definition_error(
3381                            self.cfg.input.clone(),
3382                            line!() as usize,
3383                            newly_defined_name.loc(),
3384                            methods.caused_by(),
3385                            newly_defined_name.inspect(),
3386                        ));
3387                    } else {
3388                        already_defined_methods
3389                            .locals
3390                            .remove(&newly_defined_name.inspect()[..]);
3391                    }
3392                }
3393            }
3394        }
3395        patch_root.methods_list.push(MethodContext::new(
3396            id,
3397            ClassDefType::Simple(base.clone()),
3398            methods,
3399        ));
3400    }
3401
3402    fn get_require_or_sup_or_base(expr: hir::Expr) -> Option<hir::Expr> {
3403        match expr {
3404            acc @ hir::Expr::Accessor(_) => Some(acc),
3405            hir::Expr::Call(mut call) => match call.obj.show_acc().as_ref().map(|s| &s[..]) {
3406                Some("Class" | "Trait") => call.args.remove_left_or_key("Requirement"),
3407                Some("Inherit" | "Subsume") => call.args.remove_left_or_key("Super"),
3408                Some("Inheritable") => {
3409                    Self::get_require_or_sup_or_base(call.args.remove_left_or_key("Class")?)
3410                }
3411                Some("Structural") => call.args.remove_left_or_key("Type"),
3412                Some("Patch") => call.args.remove_left_or_key("Base"),
3413                _ => todo!(),
3414            },
3415            other => todo!("{other}"),
3416        }
3417    }
3418
3419    fn lower_type_asc(
3420        &mut self,
3421        tasc: ast::TypeAscription,
3422        expect: Option<&Type>,
3423    ) -> Failable<hir::TypeAscription> {
3424        log!(info "entered {}({tasc})", fn_name!());
3425        let mut errors = LowerErrors::empty();
3426        let kind = tasc.kind();
3427        let spec_t = match self
3428            .module
3429            .context
3430            .instantiate_typespec(&tasc.t_spec.t_spec)
3431        {
3432            Ok(spec_t) => spec_t,
3433            Err((t, errs)) => {
3434                errors.extend(errs);
3435                t
3436            }
3437        };
3438        let expect = expect.map_or(Some(&spec_t), |exp| {
3439            self.module.context.min(exp, &spec_t).ok().or(Some(&spec_t))
3440        });
3441        let expr = match self.lower_expr(*tasc.expr, expect) {
3442            Ok(expr) => expr,
3443            Err((exp, errs)) => {
3444                errors.extend(errs);
3445                exp.unwrap_or(hir::Expr::Dummy(hir::Dummy::empty()))
3446            }
3447        };
3448        match kind {
3449            AscriptionKind::TypeOf | AscriptionKind::AsCast => {
3450                if let Err(es) = self.module.context.sub_unify(
3451                    expr.ref_t(),
3452                    &spec_t,
3453                    &expr,
3454                    Some(&Str::from(expr.to_string())),
3455                ) {
3456                    errors.extend(es);
3457                }
3458            }
3459            AscriptionKind::SubtypeOf => {
3460                if let Ok(ctxs) = self
3461                    .module
3462                    .context
3463                    .get_singular_ctxs_by_hir_expr(&expr, &self.module.context)
3464                {
3465                    let ctx = ctxs.first().unwrap();
3466                    // REVIEW: need to use subtype_of?
3467                    if ctx.super_traits.iter().all(|trait_| trait_ != &spec_t)
3468                        && ctx.super_classes.iter().all(|class| class != &spec_t)
3469                    {
3470                        let errs = LowerError::subtyping_error(
3471                            self.cfg.input.clone(),
3472                            line!() as usize,
3473                            expr.ref_t(), // FIXME:
3474                            &spec_t,
3475                            Location::concat(&expr, &tasc.t_spec),
3476                            self.module.context.caused_by(),
3477                        );
3478                        errors.push(errs);
3479                    }
3480                } else {
3481                    errors.push(LowerError::no_var_error(
3482                        self.cfg.input.clone(),
3483                        line!() as usize,
3484                        expr.loc(),
3485                        self.module.context.caused_by(),
3486                        &expr.to_string(),
3487                        None,
3488                    ));
3489                };
3490            }
3491            _ => {}
3492        }
3493        let t_spec = match self.lower_type_spec_with_op(tasc.t_spec, spec_t) {
3494            Ok(t_spec) => t_spec,
3495            Err((t_spec, errs)) => {
3496                errors.extend(errs);
3497                t_spec
3498            }
3499        };
3500        let tasc = expr.type_asc(t_spec);
3501        if errors.is_empty() {
3502            Ok(tasc)
3503        } else {
3504            Err((tasc, errors))
3505        }
3506    }
3507
3508    fn lower_decl(&mut self, tasc: ast::TypeAscription) -> LowerResult<hir::TypeAscription> {
3509        log!(info "entered {}({tasc})", fn_name!());
3510        let mut errors = LowerErrors::empty();
3511        let kind = tasc.kind();
3512        let spec_t = match self
3513            .module
3514            .context
3515            .instantiate_typespec(&tasc.t_spec.t_spec)
3516        {
3517            Ok(spec_t) => spec_t,
3518            Err((t, errs)) => {
3519                errors.extend(errs);
3520                t
3521            }
3522        };
3523        let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = *tasc.expr else {
3524            return Err(LowerErrors::from(LowerError::syntax_error(
3525                self.cfg.input.clone(),
3526                line!() as usize,
3527                tasc.expr.loc(),
3528                self.module.context.caused_by(),
3529                switch_lang!(
3530                    "japanese" => "無効な型宣言です(左辺には変数のみ使用出来ます)".to_string(),
3531                    "simplified_chinese" => "无效的类型声明".to_string(),
3532                    "traditional_chinese" => "無效的型宣告".to_string(),
3533                    "english" => "Invalid type declaration (currently only variables are allowed at LHS)".to_string(),
3534                ),
3535                None,
3536            )));
3537        };
3538        let ident_vi = self
3539            .module
3540            .context
3541            .rec_get_decl_info(
3542                &ident,
3543                AccessKind::Name,
3544                &self.cfg.input,
3545                &self.module.context,
3546            )
3547            .none_or_else(|| {
3548                self.module.context.rec_get_var_info(
3549                    &ident,
3550                    AccessKind::Name,
3551                    &self.cfg.input,
3552                    &self.module.context,
3553                )
3554            })
3555            .none_or_result(|| {
3556                let (similar_info, similar_name) = self
3557                    .module
3558                    .context
3559                    .get_similar_name_and_info(ident.inspect())
3560                    .unzip();
3561                LowerError::detailed_no_var_error(
3562                    self.cfg.input.clone(),
3563                    line!() as usize,
3564                    ident.loc(),
3565                    self.module.context.caused_by(),
3566                    ident.inspect(),
3567                    similar_name,
3568                    similar_info,
3569                )
3570            })?;
3571        match kind {
3572            AscriptionKind::TypeOf | AscriptionKind::AsCast => {
3573                self.module.context.sub_unify(
3574                    &ident_vi.t,
3575                    &spec_t,
3576                    &ident,
3577                    Some(ident.inspect()),
3578                )?;
3579            }
3580            AscriptionKind::SubtypeOf => {
3581                if self.module.context.subtype_of(&ident_vi.t, &spec_t) {
3582                    return Err(LowerErrors::from(LowerError::subtyping_error(
3583                        self.cfg.input.clone(),
3584                        line!() as usize,
3585                        &ident_vi.t,
3586                        &spec_t,
3587                        ident.loc(),
3588                        self.module.context.caused_by(),
3589                    )));
3590                }
3591            }
3592            _ => {}
3593        }
3594        let qual_name = self
3595            .module
3596            .context
3597            .get_singular_ctxs_by_ident(&ident, &self.module.context)
3598            .ok()
3599            .and_then(|ctxs| ctxs.first().map(|ctx| ctx.name.clone()));
3600        let ident = hir::Identifier::new(ident, qual_name, ident_vi);
3601        let expr = hir::Expr::Accessor(hir::Accessor::Ident(ident));
3602        let t_spec = match self.lower_type_spec_with_op(tasc.t_spec, spec_t) {
3603            Ok(t_spec) => t_spec,
3604            Err((t_spec, errs)) => {
3605                errors.extend(errs);
3606                t_spec
3607            }
3608        };
3609        let tasc = expr.type_asc(t_spec);
3610        if errors.is_empty() {
3611            Ok(tasc)
3612        } else {
3613            Err(errors)
3614        }
3615    }
3616
3617    // Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
3618    // so turn off type checking (check=false)
3619    fn lower_expr(&mut self, expr: ast::Expr, expect: Option<&Type>) -> FailableOption<hir::Expr> {
3620        log!(info "entered {}", fn_name!());
3621        let casted = self.module.context.get_casted_type(&expr);
3622        let mut expr = match expr {
3623            ast::Expr::Literal(lit) => {
3624                hir::Expr::Literal(self.lower_literal(lit, expect).map_err(|es| (None, es))?)
3625            }
3626            ast::Expr::List(lis) => hir::Expr::List(
3627                self.lower_list(lis, expect)
3628                    .map_err(|(list, es)| (list.map(hir::Expr::List), es))?,
3629            ),
3630            ast::Expr::Tuple(tup) => hir::Expr::Tuple(
3631                self.lower_tuple(tup, expect)
3632                    .map_err(|(tuple, es)| (Some(hir::Expr::Tuple(tuple)), es))?,
3633            ),
3634            ast::Expr::Record(rec) => hir::Expr::Record(
3635                self.lower_record(rec, expect)
3636                    .map_err(|(rec, es)| (Some(hir::Expr::Record(rec)), es))?,
3637            ),
3638            ast::Expr::Set(set) => hir::Expr::Set(
3639                self.lower_set(set, expect)
3640                    .map_err(|(set, es)| (set.map(hir::Expr::Set), es))?,
3641            ),
3642            ast::Expr::Dict(dict) => hir::Expr::Dict(
3643                self.lower_dict(dict, expect)
3644                    .map_err(|(dict, es)| (dict.map(hir::Expr::Dict), es))?,
3645            ),
3646            ast::Expr::Accessor(acc) => hir::Expr::Accessor(
3647                self.lower_acc(acc, expect)
3648                    .map_err(|(acc, errs)| (Some(hir::Expr::Accessor(acc)), errs))?,
3649            ),
3650            ast::Expr::BinOp(bin) => hir::Expr::BinOp(
3651                self.lower_bin(bin, expect)
3652                    .map_err(|(bin, es)| (Some(hir::Expr::BinOp(bin)), es))?,
3653            ),
3654            ast::Expr::UnaryOp(unary) => hir::Expr::UnaryOp(
3655                self.lower_unary(unary, expect)
3656                    .map_err(|(un, es)| (Some(hir::Expr::UnaryOp(un)), es))?,
3657            ),
3658            ast::Expr::Call(call) => hir::Expr::Call(
3659                self.lower_call(call, expect)
3660                    .map_err(|(call, es)| (Some(hir::Expr::Call(call)), es))?,
3661            ),
3662            ast::Expr::DataPack(pack) => hir::Expr::Call(
3663                self.lower_pack(pack, expect)
3664                    .map_err(|(pack, es)| (Some(hir::Expr::Call(pack)), es))?,
3665            ),
3666            ast::Expr::Lambda(lambda) => hir::Expr::Lambda(
3667                self.lower_lambda(lambda, expect)
3668                    .map_err(|(lambda, es)| (Some(hir::Expr::Lambda(lambda)), es))?,
3669            ),
3670            ast::Expr::TypeAscription(tasc) => hir::Expr::TypeAsc(
3671                self.lower_type_asc(tasc, expect)
3672                    .map_err(|(tasc, es)| (Some(hir::Expr::TypeAsc(tasc)), es))?,
3673            ),
3674            ast::Expr::Compound(comp) => hir::Expr::Compound(
3675                self.lower_compound(comp, expect)
3676                    .map_err(|(cmp, es)| (Some(hir::Expr::Compound(cmp)), es))?,
3677            ),
3678            // Checking is also performed for expressions in Dummy. However, it has no meaning in code generation
3679            ast::Expr::Dummy(dummy) => hir::Expr::Dummy(
3680                self.lower_dummy(dummy, expect)
3681                    .map_err(|(dummy, es)| (Some(hir::Expr::Dummy(dummy)), es))?,
3682            ),
3683            ast::Expr::InlineModule(inline) => hir::Expr::Call(
3684                self.lower_inline_module(inline, expect)
3685                    .map_err(|(call, es)| (Some(hir::Expr::Call(call)), es))?,
3686            ),
3687            other => {
3688                log!(err "unreachable: {other}");
3689                return unreachable_error!(LowerErrors, LowerError, self.module.context)
3690                    .map_err(|errs| (None, errs));
3691            }
3692        };
3693        if let Some(casted) = casted {
3694            // e.g. casted == {x: Obj | x != None}, expr: Int or NoneType => intersec == Int
3695            let intersec = self.module.context.intersection(expr.ref_t(), &casted);
3696            // bad narrowing: C and Structural { foo = Foo }
3697            if expr.ref_t().is_proj()
3698                || (intersec != Type::Never && intersec.ands().iter().all(|t| !t.is_structural()))
3699            {
3700                if let Some(ref_mut_t) = expr.ref_mut_t() {
3701                    *ref_mut_t = intersec;
3702                }
3703            }
3704        }
3705        // debug_assert!(expr.ref_t().has_no_qvar(), "{expr} has qvar");
3706        Ok(expr)
3707    }
3708
3709    /// The meaning of TypeAscription changes between chunk and expr.
3710    /// For example, `x: Int`, as expr, is `x` itself,
3711    /// but as chunk, it declares that `x` is of type `Int`, and is valid even before `x` is defined.
3712    pub(crate) fn lower_chunk(
3713        &mut self,
3714        chunk: ast::Expr,
3715        expect: Option<&Type>,
3716    ) -> FailableOption<hir::Expr> {
3717        log!(info "entered {}", fn_name!());
3718        match chunk {
3719            ast::Expr::Def(def) => Ok(hir::Expr::Def(
3720                self.lower_def(def, None)
3721                    .map_err(|(def, es)| (def.map(hir::Expr::Def), es))?,
3722            )),
3723            ast::Expr::ClassDef(defs) => Ok(hir::Expr::ClassDef(
3724                self.lower_class_def(defs)
3725                    .map_err(|(def, es)| (Some(hir::Expr::ClassDef(def)), es))?,
3726            )),
3727            ast::Expr::PatchDef(defs) => Ok(hir::Expr::PatchDef(
3728                self.lower_patch_def(defs)
3729                    .map_err(|(def, es)| (def.map(hir::Expr::PatchDef), es))?,
3730            )),
3731            ast::Expr::ReDef(redef) => Ok(self.lower_redef(redef)?),
3732            ast::Expr::TypeAscription(tasc) => Ok(hir::Expr::TypeAsc(
3733                self.lower_decl(tasc).map_err(|es| (None, es))?,
3734            )),
3735            other => self.lower_expr(other, expect),
3736        }
3737    }
3738
3739    pub fn lower_and_resolve_chunk(
3740        &mut self,
3741        chunk: ast::Expr,
3742        expect: Option<&Type>,
3743    ) -> FailableOption<hir::Expr> {
3744        match self.lower_chunk(chunk, expect) {
3745            Ok(mut chunk) => {
3746                let _ = self.module.context.resolve_expr_t(&mut chunk, &set! {});
3747                Ok(chunk)
3748            }
3749            Err((Some(mut chunk), errs)) => {
3750                let _ = self.module.context.resolve_expr_t(&mut chunk, &set! {});
3751                Err((Some(chunk), errs))
3752            }
3753            Err((None, errs)) => Err((None, errs)),
3754        }
3755    }
3756
3757    fn lower_block(
3758        &mut self,
3759        ast_block: ast::Block,
3760        expect: Option<&Type>,
3761    ) -> Failable<hir::Block> {
3762        log!(info "entered {}", fn_name!());
3763        let mut errors = LowerErrors::empty();
3764        let mut hir_block = Vec::with_capacity(ast_block.len());
3765        let last = ast_block.len().saturating_sub(1);
3766        for (i, chunk) in ast_block.into_iter().enumerate() {
3767            let expect = if i == last { expect } else { None };
3768            match self.lower_chunk(chunk, expect) {
3769                Ok(chunk) => hir_block.push(chunk),
3770                Err((chunk, errs)) => {
3771                    if let Some(chunk) = chunk {
3772                        hir_block.push(chunk);
3773                    }
3774                    errors.extend(errs);
3775                }
3776            };
3777        }
3778        let block = hir::Block::new(hir_block);
3779        if errors.is_empty() {
3780            Ok(block)
3781        } else {
3782            Err((block, errors))
3783        }
3784    }
3785
3786    fn lower_compound(
3787        &mut self,
3788        compound: ast::Compound,
3789        expect: Option<&Type>,
3790    ) -> Failable<hir::Block> {
3791        log!(info "entered {}", fn_name!());
3792        let mut hir_block = Vec::with_capacity(compound.len());
3793        let mut errors = LowerErrors::empty();
3794        let last = compound.len().saturating_sub(1);
3795        for (i, chunk) in compound.into_iter().enumerate() {
3796            let expect = if i == last { expect } else { None };
3797            match self.lower_chunk(chunk, expect) {
3798                Ok(chunk) => hir_block.push(chunk),
3799                Err((Some(chunk), errs)) => {
3800                    hir_block.push(chunk);
3801                    errors.extend(errs);
3802                }
3803                Err((None, errs)) => errors.extend(errs),
3804            }
3805        }
3806        if errors.is_empty() {
3807            Ok(hir::Block::new(hir_block))
3808        } else {
3809            Err((hir::Block::new(hir_block), errors))
3810        }
3811    }
3812
3813    fn lower_dummy(
3814        &mut self,
3815        ast_dummy: ast::Dummy,
3816        expect: Option<&Type>,
3817    ) -> Failable<hir::Dummy> {
3818        log!(info "entered {}", fn_name!());
3819        let mut hir_dummy = Vec::with_capacity(ast_dummy.len());
3820        let mut errors = LowerErrors::empty();
3821        let last = ast_dummy.len().saturating_sub(1);
3822        for (i, chunk) in ast_dummy.into_iter().enumerate() {
3823            let expect = if i == last { expect } else { None };
3824            match self.lower_chunk(chunk, expect) {
3825                Ok(chunk) => hir_dummy.push(chunk),
3826                Err((Some(chunk), errs)) => {
3827                    hir_dummy.push(chunk);
3828                    errors.extend(errs);
3829                }
3830                Err((None, errs)) => errors.extend(errs),
3831            }
3832        }
3833        if errors.is_empty() {
3834            Ok(hir::Dummy::new(hir_dummy))
3835        } else {
3836            Err((hir::Dummy::new(hir_dummy), errors))
3837        }
3838    }
3839
3840    pub(crate) fn lower_inline_module(
3841        &mut self,
3842        inline: InlineModule,
3843        expect: Option<&Type>,
3844    ) -> Failable<hir::Call> {
3845        log!(info "entered {}", fn_name!());
3846        let path = NormalizedPathBuf::from(inline.input.path().to_path_buf());
3847        if self
3848            .module
3849            .context
3850            .shared()
3851            .get_module(&path)
3852            .is_some_and(|ent| ent.is_complete())
3853        {
3854            return self.lower_call(inline.import, expect);
3855        }
3856        let parent = self.get_mod_ctx().context.get_module().unwrap().clone();
3857        let mod_ctx = ModuleContext::new(parent, dict! {});
3858        let mod_name = mod_name(&path);
3859        let mut builder = GenericHIRBuilder::<A>::new_submodule(mod_ctx, &mod_name);
3860        builder.lowerer.module.context.cfg.input = inline.input.clone();
3861        builder.cfg_mut().input = inline.input.clone();
3862        let mode = if path.to_string_lossy().ends_with(".d.er") {
3863            "declare"
3864        } else {
3865            "exec"
3866        };
3867        let (hir, status) = match builder.check(inline.ast, mode) {
3868            Ok(art) => {
3869                self.warns.extend(art.warns);
3870                (Some(art.object), CheckStatus::Succeed)
3871            }
3872            Err(art) => {
3873                self.warns.extend(art.warns);
3874                self.errs.extend(art.errors);
3875                (art.object, CheckStatus::Failed)
3876            }
3877        };
3878        let ctx = builder.pop_mod_ctx().unwrap();
3879        let cache = if path.to_string_lossy().ends_with(".d.er") {
3880            &self.module.context.shared().py_mod_cache
3881        } else {
3882            &self.module.context.shared().mod_cache
3883        };
3884        cache.register(path.to_path_buf(), None, hir, ctx, status);
3885        self.lower_call(inline.import, expect)
3886    }
3887
3888    fn return_incomplete_artifact(&mut self, hir: HIR) -> IncompleteArtifact {
3889        self.module.context.clear_invalid_vars();
3890        IncompleteArtifact::new(
3891            Some(hir),
3892            LowerErrors::from(self.errs.take_all()),
3893            LowerWarnings::from(self.warns.take_all()),
3894        )
3895    }
3896
3897    pub(crate) fn lint(&mut self, hir: &HIR, mode: &str) {
3898        self.warn_implicit_union(hir);
3899        self.warn_unused_expr(&hir.module, mode);
3900        self.check_doc_comments(hir);
3901        self.warn_unused_local_vars(mode);
3902    }
3903
3904    pub fn lower(&mut self, ast: AST, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
3905        log!(info "the AST lowering process has started.");
3906        log!(info "the type-checking process has started.");
3907        let ast = match ASTLinker::new(self.cfg.clone()).link(ast, mode) {
3908            Ok(ast) => ast,
3909            Err((ast, errs)) => {
3910                self.errs.extend(errs);
3911                ast
3912            }
3913        };
3914        if mode == "declare" {
3915            let hir = self.declare_module(ast);
3916            if self.errs.is_empty() {
3917                log!(info "HIR:\n{hir}");
3918                log!(info "the declaring process has completed.");
3919                return Ok(CompleteArtifact::new(
3920                    hir,
3921                    LowerWarnings::from(self.warns.take_all()),
3922                ));
3923            } else {
3924                log!(err "the declaring process has failed.");
3925                return Err(self.return_incomplete_artifact(hir));
3926            }
3927        }
3928        let mut module = hir::Module::with_capacity(ast.module.len());
3929        if let Err(errs) = self.module.context.preregister_consts(ast.module.block()) {
3930            self.errs.extend(errs);
3931        }
3932        if let Err(errs) = self.module.context.register_defs(ast.module.block()) {
3933            self.errs.extend(errs);
3934        }
3935        for chunk in ast.module.into_iter() {
3936            match self.lower_chunk(chunk, None) {
3937                Ok(chunk) => {
3938                    module.push(chunk);
3939                }
3940                Err((chunk, errs)) => {
3941                    if let Some(chunk) = chunk {
3942                        module.push(chunk);
3943                    }
3944                    self.errs.extend(errs);
3945                }
3946            }
3947        }
3948        self.module.context.clear_invalid_vars();
3949        self.module.context.check_decls().unwrap_or_else(|errs| {
3950            self.errs.extend(errs);
3951        });
3952        let hir = HIR::new(ast.name, module);
3953        log!(info "HIR (not resolved, current errs: {}):\n{hir}", self.errs.len());
3954        let hir = match self.module.context.resolve(hir) {
3955            Ok(hir) => {
3956                log!(info "HIR (resolved):\n{hir}");
3957                hir
3958            }
3959            Err((hir, errs)) => {
3960                self.errs.extend(errs);
3961                log!(err "the resolving process has failed. errs:  {}", self.errs.len());
3962                return Err(self.return_incomplete_artifact(hir));
3963            }
3964        };
3965        self.lint(&hir, mode);
3966        if &self.module.context.name[..] == "<module>" || ELS {
3967            if ELS {
3968                self.module
3969                    .context
3970                    .shared()
3971                    .promises
3972                    .join_children(&self.cfg);
3973            } else {
3974                self.module.context.shared().promises.join_all(&self.cfg);
3975            }
3976            let errs = self.module.context.shared().errors.take();
3977            let warns = self.module.context.shared().warns.take();
3978            self.errs.extend(errs);
3979            self.warns.extend(warns);
3980        }
3981        if self.errs.is_empty() {
3982            log!(info "the AST lowering process has completed.");
3983            Ok(CompleteArtifact::new(
3984                hir,
3985                LowerWarnings::from(self.warns.take_all()),
3986            ))
3987        } else {
3988            log!(err "the AST lowering process has failed. errs: {}", self.errs.len());
3989            Err(self.return_incomplete_artifact(hir))
3990        }
3991    }
3992}