1use 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#[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 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 }
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 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 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 } }
466 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 let elems = hir::Args::values(new_set, None);
738 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 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 }
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 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 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 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 }
1021 }
1022 let ident = hir::Identifier::new(attr.ident, None, vi);
1023 let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident));
1024 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 _ => 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 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 }
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 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 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 }
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 }
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 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 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 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 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 }
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 }
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 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 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 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 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 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 self.module.context.locals.remove(&var);
2027 } else {
2028 self.module.context.locals.insert(var, vi);
2029 }
2030 }
2031 }
2032 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()), ¶m.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 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 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 self.pop_append_errs();
2251 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 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 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 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 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(®istered_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 ¶ms,
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 ¶ms,
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 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 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 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), self.module.context.caused_by(),
3155 ));
3156 }
3157 }
3158 }
3159 }
3160 }
3161
3162 fn check_trait_impl(
3165 &mut self, 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 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 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 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(), &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 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 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 let intersec = self.module.context.intersection(expr.ref_t(), &casted);
3696 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 Ok(expr)
3707 }
3708
3709 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}