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