1use std::mem;
2
3use erg_common::consts::PYTHON_MODE;
4use erg_common::error::Location;
5use erg_common::pathutil::NormalizedPathBuf;
6use erg_common::traits::{Locational, Runnable, Stream};
7use erg_common::{fn_name, log, set, Str, Triple};
8
9use erg_parser::ast::{self, AscriptionKind, DefId, Identifier, TypeAppArgsKind, VarName, AST};
10use erg_parser::build_ast::ASTBuildable;
11use erg_parser::desugar::Desugarer;
12
13use crate::context::instantiate::TyVarCache;
14use crate::context::{ClassDefType, Context, MethodContext, MethodPair, TraitImpl};
15use crate::lower::GenericASTLowerer;
16use crate::ty::constructors::{list_t, mono, mono_q, mono_q_tp, poly, v_enum};
17use crate::ty::free::{Constraint, HasLevel};
18use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
19use crate::ty::{HasType, TyParam, Type, Visibility};
20
21use crate::compile::AccessKind;
22use crate::error::{LowerError, LowerErrors, LowerResult};
23use crate::hir::HIR;
24use crate::varinfo::{Mutability, VarInfo, VarKind};
25use crate::{feature_error, hir};
26
27impl<A: ASTBuildable> GenericASTLowerer<A> {
28 fn declare_var(
29 &mut self,
30 sig: ast::VarSignature,
31 mut body: ast::DefBody,
32 ) -> LowerResult<hir::Def> {
33 log!(info "entered {}({sig})", fn_name!());
34 if body.block.len() > 1 {
35 return Err(LowerErrors::from(LowerError::declare_error(
36 self.cfg().input.clone(),
37 line!() as usize,
38 body.block.loc(),
39 self.module.context.caused_by(),
40 )));
41 }
42 let opt_spec_t = if let Some(t_spec) = &sig.t_spec {
43 let t = match self.module.context.instantiate_typespec(&t_spec.t_spec) {
44 Ok(t) => t,
45 Err((t, es)) => {
46 self.errs.extend(es);
47 t
48 }
49 };
50 t.lift();
51 Some(self.module.context.generalize_t(t))
52 } else {
53 None
54 };
55 let rhs = body.block.remove(0);
56 let chunk = self.declare_chunk(rhs, true)?;
57 let py_name = match &chunk {
58 hir::Expr::TypeAsc(tasc) => {
59 if let hir::Expr::Accessor(acc) = tasc.expr.as_ref() {
60 acc.local_name().map(Str::rc)
61 } else {
62 None
63 }
64 }
65 hir::Expr::Accessor(hir::Accessor::Ident(ident)) => ident.vi.py_name.clone(),
66 _ => sig.escaped(),
67 };
68 let found_body_t = chunk.ref_t();
69 let ident = match &sig.pat {
70 ast::VarPattern::Ident(ident) => ident,
71 ast::VarPattern::Discard(token) => {
72 return Err(LowerErrors::from(LowerError::declare_error(
73 self.cfg().input.clone(),
74 line!() as usize,
75 token.loc(),
76 self.module.context.caused_by(),
77 )));
78 }
79 _ => unreachable!(),
80 };
81 let id = body.id;
82 if let Some(spec_t) = opt_spec_t {
83 self.module
84 .context
85 .sub_unify(found_body_t, &spec_t, &sig, None)?;
86 }
87 if let Some(py_name) = &py_name {
88 self.declare_instance(ident, found_body_t, py_name.clone())?;
89 } else {
90 self.module
91 .context
92 .assign_var_sig(&sig, found_body_t, id, Some(&chunk), None)?;
93 }
94 let mut ident = hir::Identifier::bare(ident.clone());
95 let t = match found_body_t {
96 Type::ClassType => {
97 let t = mono(format!("{}{}", self.module.context.path(), ident.raw));
98 v_enum(set! { ValueObj::builtin_class(t) })
99 }
100 Type::TraitType => {
101 let t = mono(format!("{}{}", self.module.context.path(), ident.raw));
102 v_enum(set! { ValueObj::builtin_trait(t) })
103 }
104 _ => found_body_t.clone(),
105 };
106 if let hir::Expr::TypeAsc(hir::TypeAscription { expr, .. }) = &chunk {
109 if let hir::Expr::Accessor(acc) = expr.as_ref() {
110 if let Some(name) = acc.local_name() {
111 let name = VarName::from_str(Str::rc(name));
112 if let Some(vi) = self.module.context.get_mut_current_scope_var(&name) {
113 vi.t = t.clone();
114 }
115 }
116 }
117 }
118 ident.vi.t = t;
119 ident.vi.py_name = py_name;
120 ident.vi.def_loc = self.module.context.absolutize(ident.raw.name.loc());
121 let t_spec = if let Some(ts) = sig.t_spec {
122 let spec_t = match self.module.context.instantiate_typespec(&ts.t_spec) {
123 Ok(t) => t,
124 Err((t, es)) => {
125 self.errs.extend(es);
126 t
127 }
128 };
129 let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
130 Some(hir::TypeSpecWithOp::new(*ts, expr, spec_t))
131 } else {
132 None
133 };
134 let sig = hir::VarSignature::new(ident, t_spec);
135 let body = hir::DefBody::new(body.op, hir::Block::new(vec![chunk]), body.id);
136 Ok(hir::Def::new(hir::Signature::Var(sig), body))
137 }
138
139 fn declare_def(&mut self, def: ast::Def) -> LowerResult<hir::Def> {
141 log!(info "entered {}({})", fn_name!(), def.sig);
142 let name = if let Some(name) = def.sig.name_as_str() {
143 name.clone()
144 } else {
145 Str::ever("<lambda>")
146 };
147 if self
148 .module
149 .context
150 .registered_info(&name, def.sig.is_const())
151 .is_some_and(|(_, vi)| {
152 !vi.kind.is_builtin()
153 && vi.def_loc
154 != self.module.context.absolutize(
155 def.sig
156 .ident()
157 .map_or(Location::Unknown, |ident| ident.loc()),
158 )
159 })
160 {
161 return Err(LowerErrors::from(LowerError::reassign_error(
162 self.cfg().input.clone(),
163 line!() as usize,
164 def.sig.loc(),
165 self.module.context.caused_by(),
166 &name,
167 )));
168 }
169 #[allow(clippy::let_and_return)]
170 let res = match def.sig {
171 ast::Signature::Subr(sig) => {
172 return Err(LowerErrors::from(LowerError::declare_error(
173 self.cfg().input.clone(),
174 line!() as usize,
175 sig.loc(),
176 self.module.context.caused_by(),
177 )));
178 }
179 ast::Signature::Var(sig) => self.declare_var(sig, def.body),
180 };
181 res
183 }
184
185 fn fake_lower_literal(&self, lit: ast::Literal) -> LowerResult<hir::Literal> {
186 let loc = lit.loc();
187 let lit = hir::Literal::try_from(lit.token).map_err(|_| {
188 LowerError::invalid_literal(
189 self.cfg.input.clone(),
190 line!() as usize,
191 loc,
192 self.module.context.caused_by(),
193 )
194 })?;
195 Ok(lit)
196 }
197
198 fn fake_lower_acc(&self, acc: ast::Accessor) -> LowerResult<hir::Accessor> {
199 match acc {
201 ast::Accessor::Ident(ident) => {
202 let vi = self
204 .module
205 .context
206 .rec_get_var_info(&ident, AccessKind::Name, self.input(), &self.module.context)
207 .unwrap_or_default();
208 let ident = hir::Identifier::new(ident, None, vi);
209 let acc = hir::Accessor::Ident(ident);
210 Ok(acc)
211 }
212 ast::Accessor::Attr(attr) => {
213 let obj = self.fake_lower_expr(*attr.obj)?;
214 let mut ident = hir::Identifier::bare(attr.ident);
215 if let Ok(ctxs) = self
216 .module
217 .context
218 .get_singular_ctxs_by_hir_expr(&obj, &self.module.context)
219 {
220 for ctx in ctxs {
221 if let Triple::Ok(vi) = ctx.rec_get_var_info(
222 &ident.raw,
223 AccessKind::UnboundAttr,
224 self.input(),
225 &self.module.context,
226 ) {
227 ident.vi = vi;
228 break;
229 }
230 }
231 }
232 Ok(obj.attr(ident))
233 }
234 other => Err(LowerErrors::from(LowerError::declare_error(
235 self.cfg().input.clone(),
236 line!() as usize,
237 other.loc(),
238 self.module.context.caused_by(),
239 ))),
240 }
241 }
242
243 fn fake_lower_args(&self, args: ast::Args) -> LowerResult<hir::Args> {
244 let (pos_args_, var_args_, kw_args_, kw_var_, paren) = args.deconstruct();
245 let mut pos_args = vec![];
246 for arg in pos_args_.into_iter() {
247 let arg = self.fake_lower_expr(arg.expr)?;
248 pos_args.push(hir::PosArg::new(arg));
249 }
250 let var_args = match var_args_ {
251 Some(var_args) => {
252 let var_args = self.fake_lower_expr(var_args.expr)?;
253 Some(hir::PosArg::new(var_args))
254 }
255 None => None,
256 };
257 let mut kw_args = vec![];
258 for kw_arg in kw_args_.into_iter() {
259 let expr = self.fake_lower_expr(kw_arg.expr)?;
260 kw_args.push(hir::KwArg::new(kw_arg.keyword, expr));
261 }
262 let kw_var = match kw_var_ {
263 Some(kw_var) => {
264 let kw_var = self.fake_lower_expr(kw_var.expr)?;
265 Some(hir::PosArg::new(kw_var))
266 }
267 None => None,
268 };
269 let args = hir::Args::new(pos_args, var_args, kw_args, kw_var, paren);
270 Ok(args)
271 }
272
273 fn fake_lower_call(&self, mut call: ast::Call) -> LowerResult<hir::Call> {
274 let obj = self.fake_lower_expr(*call.obj)?;
275 if call
276 .attr_name
277 .as_ref()
278 .is_some_and(|attr| attr.inspect() == "__Tuple_getitem__")
279 {
280 call.attr_name
281 .as_mut()
282 .unwrap()
283 .name
284 .rename("__getitem__".into());
285 }
286 let attr_name = call.attr_name.map(hir::Identifier::bare);
287 let args = self.fake_lower_args(call.args)?;
288 Ok(hir::Call::new(obj, attr_name, args))
289 }
290
291 fn fake_lower_binop(&self, binop: ast::BinOp) -> LowerResult<hir::BinOp> {
292 let mut args = binop.args.into_iter();
293 let lhs = self.fake_lower_expr(*args.next().unwrap())?;
294 let rhs = self.fake_lower_expr(*args.next().unwrap())?;
295 Ok(hir::BinOp::new(binop.op, lhs, rhs, VarInfo::default()))
296 }
297
298 fn fake_lower_unaryop(&self, unaryop: ast::UnaryOp) -> LowerResult<hir::UnaryOp> {
299 let mut args = unaryop.args.into_iter();
300 let expr = self.fake_lower_expr(*args.next().unwrap())?;
301 Ok(hir::UnaryOp::new(unaryop.op, expr, VarInfo::default()))
302 }
303
304 fn fake_lower_list(&self, arr: ast::List) -> LowerResult<hir::List> {
305 match arr {
306 ast::List::WithLength(lis) => {
307 let len = self.fake_lower_expr(*lis.len)?;
308 let elem = self.fake_lower_expr(lis.elem.expr)?;
309 Ok(hir::List::WithLength(hir::ListWithLength::new(
310 lis.l_sqbr,
311 lis.r_sqbr,
312 Type::Failure,
313 elem,
314 Some(len),
315 )))
316 }
317 ast::List::Normal(lis) => {
318 let mut elems = Vec::new();
319 let (elems_, ..) = lis.elems.deconstruct();
320 for elem in elems_.into_iter() {
321 let elem = self.fake_lower_expr(elem.expr)?;
322 elems.push(hir::PosArg::new(elem));
323 }
324 let elems = hir::Args::new(elems, None, vec![], None, None);
325 let t = list_t(Type::Failure, TyParam::value(elems.len()));
326 Ok(hir::List::Normal(hir::NormalList::new(
327 lis.l_sqbr, lis.r_sqbr, t, elems,
328 )))
329 }
330 other => Err(LowerErrors::from(LowerError::declare_error(
331 self.cfg().input.clone(),
332 line!() as usize,
333 other.loc(),
334 self.module.context.caused_by(),
335 ))),
336 }
337 }
338
339 fn fake_lower_tuple(&self, tup: ast::Tuple) -> LowerResult<hir::Tuple> {
340 match tup {
341 ast::Tuple::Normal(tup) => {
342 let mut elems = Vec::new();
343 let (elems_, _, _, _, paren) = tup.elems.deconstruct();
344 for elem in elems_.into_iter() {
345 let elem = self.fake_lower_expr(elem.expr)?;
346 elems.push(hir::PosArg::new(elem));
347 }
348 let elems = hir::Args::pos_only(elems, paren);
349 Ok(hir::Tuple::Normal(hir::NormalTuple::new(elems)))
350 }
351 }
352 }
353
354 fn fake_lower_signature(&self, sig: ast::Signature) -> LowerResult<hir::Signature> {
355 match sig {
356 ast::Signature::Var(var) => {
357 let Some(ident) = var.ident().cloned() else {
358 return Err(LowerErrors::from(LowerError::declare_error(
359 self.cfg().input.clone(),
360 line!() as usize,
361 var.loc(),
362 self.module.context.caused_by(),
363 )));
364 };
365 let ident = hir::Identifier::bare(ident);
366 let t_spec = if let Some(ts) = var.t_spec {
367 let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
368 Some(hir::TypeSpecWithOp::new(*ts, expr, Type::Failure))
369 } else {
370 None
371 };
372 let sig = hir::VarSignature::new(ident, t_spec);
373 Ok(hir::Signature::Var(sig))
374 }
375 ast::Signature::Subr(subr) => {
376 let mut decorators = set! {};
377 for decorator in subr.decorators.into_iter() {
378 let decorator = self.fake_lower_expr(decorator.0)?;
379 decorators.insert(decorator);
380 }
381 let ident = hir::Identifier::bare(subr.ident);
382 let params = self.fake_lower_params(subr.params)?;
383 let ret_t_spec = if let Some(ts) = subr.return_t_spec {
384 let spec_t = self
385 .module
386 .context
387 .instantiate_typespec(&ts.t_spec)
388 .map_err(|(_, es)| es)?;
389 let expr = self.fake_lower_expr(*ts.t_spec_as_expr.clone())?;
390 Some(hir::TypeSpecWithOp::new(*ts, expr, spec_t))
391 } else {
392 None
393 };
394 let sig = hir::SubrSignature::new(
395 decorators,
396 ident,
397 subr.bounds,
398 params,
399 ret_t_spec,
400 vec![],
401 );
402 Ok(hir::Signature::Subr(sig))
403 }
404 }
405 }
406
407 fn fake_lower_def(&self, def: ast::Def) -> LowerResult<hir::Def> {
408 let sig = self.fake_lower_signature(def.sig)?;
409 let block = self.fake_lower_block(def.body.block)?;
410 let body = hir::DefBody::new(def.body.op, block, def.body.id);
411 Ok(hir::Def::new(sig, body))
412 }
413
414 fn fake_lower_record(&self, rec: ast::Record) -> LowerResult<hir::Record> {
415 let rec = match rec {
416 ast::Record::Normal(rec) => rec,
417 ast::Record::Mixed(mixed) => Desugarer::desugar_shortened_record_inner(mixed),
418 };
419 let mut elems = Vec::new();
420 for elem in rec.attrs.into_iter() {
421 let elem = self.fake_lower_def(elem)?;
422 elems.push(elem);
423 }
424 let attrs = hir::RecordAttrs::new(elems);
425 Ok(hir::Record::new(rec.l_brace, rec.r_brace, attrs))
426 }
427
428 fn fake_lower_set(&self, set: ast::Set) -> LowerResult<hir::Set> {
429 match set {
430 ast::Set::Normal(set) => {
431 let mut elems = Vec::new();
432 let (elems_, ..) = set.elems.deconstruct();
433 for elem in elems_.into_iter() {
434 let elem = self.fake_lower_expr(elem.expr)?;
435 elems.push(hir::PosArg::new(elem));
436 }
437 let elems = hir::Args::pos_only(elems, None);
438 Ok(hir::Set::Normal(hir::NormalSet::new(
439 set.l_brace,
440 set.r_brace,
441 Type::Failure,
442 elems,
443 )))
444 }
445 ast::Set::WithLength(set) => {
446 let len = self.fake_lower_expr(*set.len)?;
447 let elem = self.fake_lower_expr(set.elem.expr)?;
448 Ok(hir::Set::WithLength(hir::SetWithLength::new(
449 set.l_brace,
450 set.r_brace,
451 Type::Failure,
452 len,
453 elem,
454 )))
455 }
456 ast::Set::Comprehension(set) => Ok(hir::Set::Normal(hir::NormalSet::new(
458 set.l_brace,
459 set.r_brace,
460 Type::Failure,
461 hir::Args::empty(),
462 ))),
463 }
464 }
465
466 fn fake_lower_dict(&self, dict: ast::Dict) -> LowerResult<hir::Dict> {
467 match dict {
468 ast::Dict::Normal(dict) => {
469 let mut kvs = Vec::new();
470 for elem in dict.kvs.into_iter() {
471 let key = self.fake_lower_expr(elem.key)?;
472 let val = self.fake_lower_expr(elem.value)?;
473 kvs.push(hir::KeyValue::new(key, val));
474 }
475 let tys = erg_common::dict::Dict::new();
476 Ok(hir::Dict::Normal(hir::NormalDict::new(
477 dict.l_brace,
478 dict.r_brace,
479 tys,
480 kvs,
481 )))
482 }
483 other => Err(LowerErrors::from(LowerError::declare_error(
484 self.cfg().input.clone(),
485 line!() as usize,
486 other.loc(),
487 self.module.context.caused_by(),
488 ))),
489 }
490 }
491
492 fn fake_lower_params(&self, params: ast::Params) -> LowerResult<hir::Params> {
493 let (non_defaults_, var_params_, defaults_, kw_var_, guards_, parens) =
494 params.deconstruct();
495 let mut non_defaults = vec![];
496 for non_default_ in non_defaults_.into_iter() {
497 let t_spec_as_expr = non_default_
498 .t_spec
499 .as_ref()
500 .map(|t_spec| self.fake_lower_expr(*t_spec.t_spec_as_expr.clone()))
501 .transpose()?;
502 let non_default = hir::NonDefaultParamSignature::new(
503 non_default_,
504 VarInfo::default(),
505 t_spec_as_expr,
506 );
507 non_defaults.push(non_default);
508 }
509 let var_params = if let Some(var_params) = var_params_ {
510 let t_spec_as_expr = var_params
511 .t_spec
512 .as_ref()
513 .map(|t_spec| self.fake_lower_expr(*t_spec.t_spec_as_expr.clone()))
514 .transpose()?;
515 Some(Box::new(hir::NonDefaultParamSignature::new(
516 *var_params,
517 VarInfo::default(),
518 t_spec_as_expr,
519 )))
520 } else {
521 None
522 };
523 let mut defaults = vec![];
524 for default_ in defaults_.into_iter() {
525 let t_spec_as_expr = default_
526 .sig
527 .t_spec
528 .as_ref()
529 .map(|t_spec| self.fake_lower_expr(*t_spec.t_spec_as_expr.clone()))
530 .transpose()?;
531 let default_val = self.fake_lower_expr(default_.default_val)?;
532 let sig = hir::NonDefaultParamSignature::new(
533 default_.sig,
534 VarInfo::default(),
535 t_spec_as_expr,
536 );
537 let default = hir::DefaultParamSignature::new(sig, default_val);
538 defaults.push(default);
539 }
540 let kw_var = if let Some(kw_var) = kw_var_ {
541 let t_spec_as_expr = kw_var
542 .t_spec
543 .as_ref()
544 .map(|t_spec| self.fake_lower_expr(*t_spec.t_spec_as_expr.clone()))
545 .transpose()?;
546 Some(Box::new(hir::NonDefaultParamSignature::new(
547 *kw_var,
548 VarInfo::default(),
549 t_spec_as_expr,
550 )))
551 } else {
552 None
553 };
554 let mut guards = vec![];
555 for guard in guards_.into_iter() {
556 let guard = match guard {
557 ast::GuardClause::Condition(cond) => {
558 hir::GuardClause::Condition(self.fake_lower_expr(cond)?)
559 }
560 ast::GuardClause::Bind(bind) => hir::GuardClause::Bind(self.fake_lower_def(bind)?),
561 };
562 guards.push(guard);
563 }
564 Ok(hir::Params::new(
565 non_defaults,
566 var_params,
567 defaults,
568 kw_var,
569 guards,
570 parens,
571 ))
572 }
573
574 fn fake_lower_block(&self, block: ast::Block) -> LowerResult<hir::Block> {
575 let mut chunks = vec![];
576 for chunk in block.into_iter() {
577 let chunk = self.fake_lower_expr(chunk)?;
578 chunks.push(chunk);
579 }
580 Ok(hir::Block::new(chunks))
581 }
582
583 fn fake_lower_lambda(&self, lambda: ast::Lambda) -> LowerResult<hir::Lambda> {
584 let params = self.fake_lower_params(lambda.sig.params)?;
585 let return_t_spec = lambda.sig.return_t_spec.map(|t_spec| t_spec.t_spec);
586 let body = self.fake_lower_block(lambda.body)?;
587 Ok(hir::Lambda::new(
588 lambda.id.0,
589 params,
590 lambda.op,
591 return_t_spec,
592 vec![],
593 body,
594 Type::Failure,
595 ))
596 }
597
598 fn fake_lower_dummy(&self, dummy: ast::Dummy) -> LowerResult<hir::Dummy> {
599 let mut dummy_ = vec![];
600 for elem in dummy.into_iter() {
601 let elem = self.fake_lower_expr(elem)?;
602 dummy_.push(elem);
603 }
604 Ok(hir::Dummy::new(dummy_))
605 }
606
607 fn fake_lower_type_asc(&self, tasc: ast::TypeAscription) -> LowerResult<hir::TypeAscription> {
608 let expr = self.fake_lower_expr(*tasc.expr)?;
609 let t_spec_as_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr.clone())?;
610 let spec_t = self
611 .module
612 .context
613 .instantiate_typespec(&tasc.t_spec.t_spec)
614 .map_err(|(_, es)| es)?;
615 let spec = hir::TypeSpecWithOp::new(tasc.t_spec, t_spec_as_expr, spec_t);
616 Ok(hir::TypeAscription::new(expr, spec))
617 }
618
619 fn fake_lower_compound(&self, compound: ast::Compound) -> LowerResult<hir::Block> {
620 let mut chunks = vec![];
621 for chunk in compound.into_iter() {
622 let chunk = self.fake_lower_expr(chunk)?;
623 chunks.push(chunk);
624 }
625 Ok(hir::Block::new(chunks))
626 }
627
628 pub(crate) fn fake_lower_expr(&self, expr: ast::Expr) -> LowerResult<hir::Expr> {
629 match expr {
630 ast::Expr::Literal(lit) => Ok(hir::Expr::Literal(self.fake_lower_literal(lit)?)),
631 ast::Expr::BinOp(binop) => Ok(hir::Expr::BinOp(self.fake_lower_binop(binop)?)),
632 ast::Expr::UnaryOp(unop) => Ok(hir::Expr::UnaryOp(self.fake_lower_unaryop(unop)?)),
633 ast::Expr::List(lis) => Ok(hir::Expr::List(self.fake_lower_list(lis)?)),
634 ast::Expr::Tuple(tup) => Ok(hir::Expr::Tuple(self.fake_lower_tuple(tup)?)),
635 ast::Expr::Record(rec) => Ok(hir::Expr::Record(self.fake_lower_record(rec)?)),
636 ast::Expr::Set(set) => Ok(hir::Expr::Set(self.fake_lower_set(set)?)),
637 ast::Expr::Dict(dict) => Ok(hir::Expr::Dict(self.fake_lower_dict(dict)?)),
638 ast::Expr::Accessor(ast::Accessor::TypeApp(tapp)) => self.fake_lower_expr(*tapp.obj),
639 ast::Expr::Accessor(acc) => Ok(hir::Expr::Accessor(self.fake_lower_acc(acc)?)),
640 ast::Expr::Call(call) => Ok(hir::Expr::Call(self.fake_lower_call(call)?)),
641 ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.fake_lower_lambda(lambda)?)),
642 ast::Expr::Compound(compound) => {
643 Ok(hir::Expr::Compound(self.fake_lower_compound(compound)?))
644 }
645 ast::Expr::Dummy(dummy) => Ok(hir::Expr::Dummy(self.fake_lower_dummy(dummy)?)),
646 ast::Expr::TypeAscription(tasc) => {
647 Ok(hir::Expr::TypeAsc(self.fake_lower_type_asc(tasc)?))
648 }
649 other => Err(LowerErrors::from(LowerError::declare_error(
650 self.cfg().input.clone(),
651 line!() as usize,
652 other.loc(),
653 self.module.context.caused_by(),
654 ))),
655 }
656 }
657
658 fn declare_ident(&mut self, tasc: ast::TypeAscription) -> LowerResult<hir::TypeAscription> {
659 log!(info "entered {}({})", fn_name!(), tasc);
660 let kind = tasc.kind();
661 match *tasc.expr {
662 ast::Expr::Accessor(ast::Accessor::Ident(ident)) => {
663 let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
664 let t = match self
665 .module
666 .context
667 .instantiate_typespec(&tasc.t_spec.t_spec)
668 {
669 Ok(t) => t,
670 Err((t, es)) => {
671 self.errs.extend(es);
672 t
673 }
674 };
675 t.lift();
676 let t = self.module.context.generalize_t(t);
677 match kind {
678 AscriptionKind::TypeOf | AscriptionKind::AsCast => {
679 self.declare_instance(&ident, &t, py_name.clone())?;
680 }
681 AscriptionKind::SubtypeOf => {
682 self.declare_subtype(&ident, &t)?;
683 }
684 _ => {
685 log!(err "supertype ascription is not supported yet");
686 }
687 }
688 let muty = Mutability::from(&ident.inspect()[..]);
689 let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?;
690 let vi = VarInfo::new(
691 t,
692 muty,
693 Visibility::new(vis, self.module.context.name.clone()),
694 VarKind::Declared,
695 None,
696 self.module.context.kind.clone(),
697 Some(py_name),
698 self.module.context.absolutize(ident.name.loc()),
699 );
700 let ident = hir::Identifier::new(ident, None, vi);
701 let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr.clone())?;
702 let t_spec = hir::TypeSpecWithOp::new(tasc.t_spec, t_spec_expr, Type::Failure);
703 Ok(hir::Expr::Accessor(hir::Accessor::Ident(ident)).type_asc(t_spec))
704 }
705 ast::Expr::Accessor(ast::Accessor::Attr(attr)) => {
706 let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!'));
707 let mut tv_cache = if let Ok(call) = ast::Call::try_from(*attr.obj.clone()) {
708 let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = *call.obj else {
709 return feature_error!(
710 LowerErrors,
711 LowerError,
712 &self.module.context,
713 call.obj.loc(),
714 "complex polymorphic type declaration"
715 );
716 };
717 self.module.context.get_tv_ctx(&ident, &call.args)
718 } else {
719 TyVarCache::new(self.module.context.level, &self.module.context)
720 };
721 let t = match self
722 .module
723 .context
724 .instantiate_typespec_with_tv_cache(&tasc.t_spec.t_spec, &mut tv_cache)
725 {
726 Ok(t) => t,
727 Err((t, es)) => {
728 self.errs.extend(es);
729 t
730 }
731 };
732 let impl_trait = if let ast::Expr::Accessor(ast::Accessor::TypeApp(tapp)) =
733 attr.obj.as_ref()
734 {
735 match &tapp.type_args.args {
736 TypeAppArgsKind::SubtypeOf(typ) => {
737 let trait_ = match self
738 .module
739 .context
740 .instantiate_typespec_with_tv_cache(&typ.t_spec, &mut tv_cache)
741 {
742 Ok(t) => t,
743 Err((t, es)) => {
744 self.errs.extend(es);
745 t
746 }
747 };
748 if !self.module.context.is_trait(&trait_) {
749 return Err(LowerErrors::from(LowerError::type_mismatch_error(
750 self.cfg().input.clone(),
751 line!() as usize,
752 typ.loc(),
753 self.module.context.caused_by(),
754 "SuperTrait",
755 None,
756 &Type::TraitType,
757 &Type::ClassType,
758 None,
759 None,
760 )));
761 }
762 Some(trait_)
763 }
764 TypeAppArgsKind::Args(args) => {
765 log!(err "{args}");
766 None
767 }
768 }
769 } else {
770 None
771 };
772 let ctx = self.module.context.get_mut_singular_ctx_and_t(
773 attr.obj.as_ref(),
774 &self.module.context.name.clone(),
775 )?;
776 let class = ctx.typ.clone();
777 let ctx = if let Some(impl_trait) = impl_trait {
778 match ctx
779 .methods_list
780 .iter_mut()
781 .find(|ctx| ctx.typ.is_impl_of(&impl_trait))
782 {
783 Some(impl_ctx) => impl_ctx,
784 None => {
785 let impl_ctx = Context::methods(
786 Some(impl_trait.clone()),
787 self.cfg.copy(),
788 ctx.shared.clone(),
789 0,
790 ctx.level,
791 );
792 ctx.super_traits.push(impl_trait.clone());
793 let declared_in = NormalizedPathBuf::from(ctx.module_path());
794 let declared_in = declared_in.exists().then_some(declared_in);
795 if let Some(mut impls) =
796 ctx.trait_impls().get_mut(&impl_trait.qual_name())
797 {
798 impls.insert(TraitImpl::new(
799 class.clone(),
800 impl_trait.clone(),
801 declared_in,
802 ));
803 } else {
804 ctx.trait_impls().register(
805 impl_trait.qual_name(),
806 set! { TraitImpl::new(class.clone(), impl_trait.clone(), declared_in) },
807 );
808 }
809 ctx.methods_list.push(MethodContext::new(
810 DefId(0),
811 ClassDefType::impl_trait(class.clone(), impl_trait),
812 impl_ctx,
813 ));
814 &mut ctx.methods_list.iter_mut().last().unwrap().ctx
815 }
816 }
817 } else {
818 ctx
819 };
820 let vi = ctx.assign_var_sig(
821 &ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None),
822 &t,
823 ast::DefId(0),
824 None,
825 Some(py_name.clone()),
826 )?;
827 if let Some(types) = self
828 .module
829 .context
830 .method_to_classes
831 .get_mut(attr.ident.inspect())
832 {
833 types.push(MethodPair::new(class, vi.clone()));
834 } else {
835 self.module.context.method_to_classes.insert(
836 attr.ident.inspect().clone(),
837 vec![MethodPair::new(class, vi.clone())],
838 );
839 }
840 let obj = self.fake_lower_expr(*attr.obj)?;
841 let muty = Mutability::from(&attr.ident.inspect()[..]);
842 let vis = self
843 .module
844 .context
845 .instantiate_vis_modifier(&attr.ident.vis)?;
846 let vi = VarInfo::new(
847 t,
848 muty,
849 Visibility::new(vis, self.module.context.name.clone()),
850 VarKind::Declared,
851 None,
852 self.module.context.kind.clone(),
853 Some(py_name),
854 self.module.context.absolutize(attr.ident.name.loc()),
855 );
856 let ident = hir::Identifier::new(attr.ident, None, vi);
857 let attr = obj.attr_expr(ident);
858 let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr.clone())?;
859 let t_spec = hir::TypeSpecWithOp::new(tasc.t_spec, t_spec_expr, Type::Failure);
860 Ok(attr.type_asc(t_spec))
861 }
862 ast::Expr::Call(call) => {
863 let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = *call.obj else {
864 return feature_error!(
865 LowerErrors,
866 LowerError,
867 &self.module.context,
868 call.obj.loc(),
869 "complex polymorphic type declaration"
870 );
871 };
872 let py_name = Str::rc(ident.inspect().trim_end_matches('!'));
873 let mut tv_cache = self.module.context.get_tv_ctx(&ident, &call.args);
874 let t = match self
875 .module
876 .context
877 .instantiate_typespec_with_tv_cache(&tasc.t_spec.t_spec, &mut tv_cache)
878 {
879 Ok(t) => t,
880 Err((t, es)) => {
881 self.errs.extend(es);
882 t
883 }
884 };
885 match kind {
886 AscriptionKind::TypeOf | AscriptionKind::AsCast => {
887 self.declare_instance(&ident, &t, py_name)?;
888 }
889 AscriptionKind::SubtypeOf => {
890 self.declare_subtype(&ident, &t)?;
891 }
892 _ => {
893 log!(err "supertype ascription is not supported yet");
894 }
895 }
896 let acc = self.fake_lower_acc(ast::Accessor::Ident(ident))?;
897 let args = self.fake_lower_args(call.args)?;
898 let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr.clone())?;
899 let t_spec = hir::TypeSpecWithOp::new(tasc.t_spec, t_spec_expr, Type::Failure);
900 Ok(hir::Expr::Accessor(acc).call_expr(args).type_asc(t_spec))
901 }
902 other => Err(LowerErrors::from(LowerError::declare_error(
903 self.cfg().input.clone(),
904 line!() as usize,
905 other.loc(),
906 self.module.context.caused_by(),
907 ))),
908 }
909 }
910
911 fn declare_instance(
912 &mut self,
913 ident: &ast::Identifier,
914 t: &Type,
915 py_name: Str,
916 ) -> LowerResult<()> {
917 if ident.is_raw() {
919 return Ok(());
920 }
921 let mut type_as_function = false;
929 if PYTHON_MODE
930 && self
931 .module
932 .context
933 .registered_info(ident.inspect(), ident.is_const())
934 .is_some_and(|(_, vi)| {
935 self.module.context.subtype_of(t, &Type::Type)
936 || self.module.context.subtype_of(&vi.t, &Type::Type)
937 })
938 {
939 let typ = self.module.context.get_type_ctx(ident.inspect());
940 if typ.is_some_and(|ctx| ctx.has("__call__")) {
941 type_as_function = true;
942 }
943 }
944 if !type_as_function
945 && self
946 .module
947 .context
948 .registered_info(ident.inspect(), ident.is_const())
949 .is_some_and(|(_, vi)| {
950 !vi.kind.is_builtin()
951 && vi.def_loc != self.module.context.absolutize(ident.loc())
952 })
953 {
954 return Err(LowerErrors::from(LowerError::reassign_error(
955 self.cfg().input.clone(),
956 line!() as usize,
957 ident.loc(),
958 self.module.context.caused_by(),
959 ident.inspect(),
960 )));
961 }
962 let new_ident = if PYTHON_MODE {
963 let mut symbol = ident.name.clone().into_token();
964 symbol.content = py_name.clone();
965 Identifier::new(ident.vis.clone(), VarName::new(symbol))
966 } else {
967 ident.clone()
968 };
969 let (t, ty_obj) = match t {
970 Type::ClassType => {
971 let t = mono(format!("{}{ident}", self.module.context.path()));
972 let ty_obj = GenTypeObj::class(t.clone(), None, None, true);
973 let t = v_enum(set! { ValueObj::builtin_class(t) });
974 (t, Some(ty_obj))
975 }
976 Type::TraitType => {
977 let t = mono(format!("{}{ident}", self.module.context.path()));
978 let ty_obj = GenTypeObj::trait_(
979 t.clone(),
980 TypeObj::builtin_type(Type::Uninited),
981 None,
982 true,
983 );
984 let t = v_enum(set! { ValueObj::builtin_trait(t) });
985 (t, Some(ty_obj))
986 }
987 Type::Subr(subr) if subr.return_t.is_class_type() => {
988 let params = subr
989 .non_default_params
990 .iter()
991 .map(|p| {
992 let c = Constraint::new_type_of(p.typ().clone());
993 if self.module.context.subtype_of(p.typ(), &Type::Type) {
994 TyParam::t(mono_q(p.name().unwrap_or(&Str::ever("_")), c))
995 } else {
996 mono_q_tp(p.name().unwrap_or(&Str::ever("_")), c)
997 }
998 })
999 .collect();
1000 let t = poly(format!("{}{ident}", self.module.context.path()), params);
1001 let ty_obj = GenTypeObj::class(t.clone(), None, None, true);
1002 let t = v_enum(set! { ValueObj::builtin_class(t) });
1003 (t, Some(ty_obj))
1004 }
1005 _ => (t.clone(), None),
1006 };
1007 self.module.context.assign_var_sig(
1008 &ast::VarSignature::new(ast::VarPattern::Ident(ident.clone()), None),
1009 &t,
1010 ast::DefId(0),
1011 None,
1012 Some(py_name),
1013 )?;
1014 if let Some(gen) = ty_obj {
1015 self.module
1016 .context
1017 .register_gen_type(&new_ident, gen, None)?;
1018 }
1019 Ok(())
1020 }
1021
1022 fn declare_subtype(&mut self, ident: &ast::Identifier, sup: &Type) -> LowerResult<()> {
1023 if ident.is_raw() {
1024 return Ok(());
1025 }
1026 let name = if PYTHON_MODE {
1027 self.module
1028 .context
1029 .erg_to_py_names
1030 .get(ident.inspect())
1031 .map_or(Str::ever("?"), |s| s.clone())
1032 } else {
1033 ident.inspect().clone()
1034 };
1035 if let Some(ctx) = self.module.context.rec_get_mut_type(&name) {
1036 let mut tmp = mem::take(ctx);
1037 let res = if self.module.context.is_class(sup) {
1038 tmp.register_base_class(&self.module.context, sup.clone())
1039 } else {
1040 let class = tmp.typ.clone();
1041 let imp = self.module.context.register_trait_impl(&class, sup, ident);
1042 imp.and(tmp.register_trait(&self.module.context, sup.clone()))
1043 };
1044 res.inspect_err(|_err| {
1045 let ctx = self.module.context.rec_get_mut_type(&name).unwrap();
1046 mem::swap(ctx, &mut tmp);
1047 })?;
1048 let ctx = self.module.context.rec_get_mut_type(&name).unwrap();
1049 mem::swap(ctx, &mut tmp);
1050 Ok(())
1051 } else {
1052 Err(LowerErrors::from(LowerError::no_var_error(
1053 self.cfg().input.clone(),
1054 line!() as usize,
1055 ident.loc(),
1056 self.module.context.caused_by(),
1057 ident.inspect(),
1058 self.module.context.get_similar_name(ident.inspect()),
1059 )))
1060 }
1061 }
1062
1063 fn declare_chunk(&mut self, expr: ast::Expr, allow_acc: bool) -> LowerResult<hir::Expr> {
1064 log!(info "entered {}", fn_name!());
1065 match expr {
1066 ast::Expr::Literal(lit) if lit.is_doc_comment() => {
1067 Ok(hir::Expr::Literal(self.lower_literal(lit, None)?))
1068 }
1069 ast::Expr::Accessor(acc) if allow_acc => Ok(hir::Expr::Accessor(
1070 self.lower_acc(acc, None).map_err(|(_, errs)| errs)?,
1071 )),
1072 ast::Expr::Def(def) => Ok(hir::Expr::Def(self.declare_def(def)?)),
1073 ast::Expr::TypeAscription(tasc) => Ok(hir::Expr::TypeAsc(self.declare_ident(tasc)?)),
1074 ast::Expr::Call(call)
1075 if call
1076 .additional_operation()
1077 .map(|op| op.is_import())
1078 .unwrap_or(false) =>
1079 {
1080 Ok(hir::Expr::Call(
1081 self.lower_call(call, None).map_err(|(_, errs)| errs)?,
1082 ))
1083 }
1084 ast::Expr::Compound(compound) => {
1085 let mut chunks = vec![];
1086 for chunk in compound.into_iter() {
1087 let chunk = self.declare_chunk(chunk, true)?;
1088 chunks.push(chunk);
1089 }
1090 Ok(hir::Expr::Compound(hir::Block::new(chunks)))
1091 }
1092 ast::Expr::Dummy(dummy) => {
1093 let mut dummy_ = vec![];
1094 for elem in dummy.into_iter() {
1095 let elem = self.declare_chunk(elem, true)?;
1096 dummy_.push(elem);
1097 }
1098 Ok(hir::Expr::Dummy(hir::Dummy::new(dummy_)))
1099 }
1100 ast::Expr::InlineModule(inline) => {
1101 let import = self
1102 .lower_inline_module(inline, None)
1103 .map_err(|(_, es)| es)?;
1104 Ok(hir::Expr::Call(import))
1105 }
1106 other => Err(LowerErrors::from(LowerError::declare_error(
1107 self.cfg().input.clone(),
1108 line!() as usize,
1109 other.loc(),
1110 self.module.context.caused_by(),
1111 ))),
1112 }
1113 }
1114
1115 fn pre_declare_chunk(&mut self, expr: &ast::Expr) {
1116 match expr {
1117 ast::Expr::TypeAscription(tasc) => {
1118 let _ = self.declare_ident(tasc.clone());
1119 }
1120 ast::Expr::Def(def) => {
1121 let _ = self.declare_def(def.clone());
1122 }
1123 ast::Expr::Compound(compound) => {
1124 for chunk in compound.iter() {
1125 self.pre_declare_chunk(chunk);
1126 }
1127 }
1128 ast::Expr::Dummy(dummy) => {
1129 for elem in dummy.iter() {
1130 self.pre_declare_chunk(elem);
1131 }
1132 }
1133 _ => {}
1134 }
1135 }
1136
1137 pub(crate) fn declare_module(&mut self, ast: AST) -> HIR {
1138 let mut module = hir::Module::with_capacity(ast.module.len());
1139 for chunk in ast.module.iter() {
1141 self.pre_declare_chunk(chunk);
1142 }
1143 self.warns.clear();
1144 self.errs.clear();
1145 for chunk in ast.module.into_iter() {
1146 match self.declare_chunk(chunk, false) {
1147 Ok(chunk) => {
1148 module.push(chunk);
1149 }
1150 Err(errs) => {
1151 self.errs.extend(errs);
1152 }
1153 }
1154 }
1155 let hir = HIR::new(ast.name, module);
1156 self.lint(&hir, "declare");
1157 hir
1158 }
1159}