diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index e296d981..3a78a2bc 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -37,8 +37,8 @@ use erg_parser::token::{Token, TokenKind}; use crate::compile::{AccessKind, Name, StoreLoadKind}; use crate::error::CompileError; use crate::hir::{ - Accessor, Args, Array, AttrDef, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, Identifier, - Lambda, Literal, Params, PatchDef, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp, + Accessor, Args, Array, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, Identifier, Lambda, + Literal, Params, PatchDef, PosArg, ReDef, Record, Signature, SubrSignature, Tuple, UnaryOp, VarSignature, HIR, }; use crate::ty::value::ValueObj; @@ -1220,10 +1220,10 @@ impl PyCodeGenerator { } } - fn emit_attr_def(&mut self, attr_def: AttrDef) { - log!(info "entered {} ({attr_def})", fn_name!()); - self.emit_frameless_block(attr_def.block, vec![]); - self.store_acc(attr_def.attr); + fn emit_redef(&mut self, redef: ReDef) { + log!(info "entered {} ({redef})", fn_name!()); + self.emit_frameless_block(redef.block, vec![]); + self.store_acc(redef.attr); } fn emit_var_def(&mut self, sig: VarSignature, mut body: DefBody) { @@ -2640,7 +2640,7 @@ impl PyCodeGenerator { Expr::Def(def) => self.emit_def(def), Expr::ClassDef(class) => self.emit_class_def(class), Expr::PatchDef(patch) => self.emit_patch_def(patch), - Expr::AttrDef(attr) => self.emit_attr_def(attr), + Expr::ReDef(attr) => self.emit_redef(attr), Expr::Lambda(lambda) => self.emit_lambda(lambda), Expr::UnaryOp(unary) => self.emit_unaryop(unary), Expr::BinOp(bin) => self.emit_binop(bin), @@ -2669,7 +2669,7 @@ impl PyCodeGenerator { Expr::Def(def) => self.emit_def(def), Expr::ClassDef(class) => self.emit_class_def(class), Expr::PatchDef(patch) => self.emit_patch_def(patch), - Expr::AttrDef(attr) => self.emit_attr_def(attr), + Expr::ReDef(attr) => self.emit_redef(attr), Expr::Lambda(lambda) => self.emit_lambda(lambda), Expr::UnaryOp(unary) => self.emit_unaryop(unary), Expr::BinOp(bin) => self.emit_binop(bin), @@ -2840,8 +2840,8 @@ impl PyCodeGenerator { dot, VarName::from_str(field.symbol.clone()), )); - let attr_def = AttrDef::new(attr, Block::new(vec![expr])); - attrs.push(Expr::AttrDef(attr_def)); + let redef = ReDef::new(attr, Block::new(vec![expr])); + attrs.push(Expr::ReDef(redef)); } let none = Token::new(TokenKind::NoneLit, "None", line, 0); attrs.push(Expr::Lit(Literal::new(ValueObj::None, none))); diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index fa70ff35..97c00719 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -869,9 +869,9 @@ impl Context { } Ok(()) } - hir::Expr::AttrDef(attr_def) => { - // REVIEW: attr_def.attr is not dereferenced - for chunk in attr_def.block.iter_mut() { + hir::Expr::ReDef(redef) => { + // REVIEW: redef.attr is not dereferenced + for chunk in redef.block.iter_mut() { self.resolve_expr_t(chunk)?; } Ok(()) diff --git a/compiler/erg_compiler/desugar_hir.rs b/compiler/erg_compiler/desugar_hir.rs index 4e162579..24732755 100644 --- a/compiler/erg_compiler/desugar_hir.rs +++ b/compiler/erg_compiler/desugar_hir.rs @@ -1,7 +1,7 @@ use erg_common::log; use erg_common::traits::Stream; -use crate::hir::{Accessor, AttrDef, Block, Expr, HIR}; +use crate::hir::{Accessor, Block, Expr, ReDef, HIR}; /// Desugares HIR to make it more like Python semantics. pub struct HIRDesugarer {} @@ -45,8 +45,8 @@ impl HIRDesugarer { .map(|expr| match expr { Expr::Def(def) => { let acc = class.clone().attr(def.sig.into_ident()); - let attr_def = AttrDef::new(acc, def.body.block); - Expr::AttrDef(attr_def) + let redef = ReDef::new(acc, def.body.block); + Expr::ReDef(redef) } _ => expr, }) diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index 232e9c3c..e7b10aa5 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -194,7 +194,7 @@ impl SideEffectChecker { self.path_stack.pop(); self.block_stack.pop(); } - Expr::AttrDef(_) + Expr::ReDef(_) | Expr::Code(_) | Expr::Compound(_) | Expr::Import(_) @@ -457,7 +457,7 @@ impl SideEffectChecker { )); } } - Expr::AttrDef(_) + Expr::ReDef(_) | Expr::Code(_) | Expr::Compound(_) | Expr::Import(_) diff --git a/compiler/erg_compiler/hir.rs b/compiler/erg_compiler/hir.rs index 312e9fa2..7bc0b5b2 100644 --- a/compiler/erg_compiler/hir.rs +++ b/compiler/erg_compiler/hir.rs @@ -2181,12 +2181,12 @@ impl PatchDef { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct AttrDef { +pub struct ReDef { pub attr: Accessor, pub block: Block, } -impl NestedDisplay for AttrDef { +impl NestedDisplay for ReDef { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { self.attr.fmt_nest(f, level)?; writeln!(f, " = ")?; @@ -2194,7 +2194,7 @@ impl NestedDisplay for AttrDef { } } -impl NoTypeDisplay for AttrDef { +impl NoTypeDisplay for ReDef { fn to_string_notype(&self) -> String { format!( "{} = {}", @@ -2204,10 +2204,10 @@ impl NoTypeDisplay for AttrDef { } } -impl_display_from_nested!(AttrDef); -impl_locational!(AttrDef, attr, block); +impl_display_from_nested!(ReDef); +impl_locational!(ReDef, attr, block); -impl HasType for AttrDef { +impl HasType for ReDef { #[inline] fn ref_t(&self) -> &Type { Type::NONE @@ -2226,7 +2226,7 @@ impl HasType for AttrDef { } } -impl AttrDef { +impl ReDef { pub const fn new(attr: Accessor, block: Block) -> Self { Self { attr, block } } @@ -2297,7 +2297,7 @@ pub enum Expr { Def(Def), ClassDef(ClassDef), PatchDef(PatchDef), - AttrDef(AttrDef), + ReDef(ReDef), TypeAsc(TypeAscription), Code(Block), // code object Compound(Block), // compound statement @@ -2305,11 +2305,11 @@ pub enum Expr { Dummy(Dummy), // for mapping to Python AST } -impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy); -impl_no_type_display_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy); +impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy); +impl_no_type_display_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy); impl_display_from_nested!(Expr); -impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy); -impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, AttrDef, Code, Compound, TypeAsc, Set, Import, Dummy); +impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy); +impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Def, ClassDef, PatchDef, ReDef, Code, Compound, TypeAsc, Set, Import, Dummy); impl Default for Expr { fn default() -> Self { diff --git a/compiler/erg_compiler/link.rs b/compiler/erg_compiler/link.rs index f9455e30..d58cfcad 100644 --- a/compiler/erg_compiler/link.rs +++ b/compiler/erg_compiler/link.rs @@ -145,9 +145,9 @@ impl<'a> Linker<'a> { self.resolve_pymod_path(def); } } - Expr::AttrDef(attr_def) => { + Expr::ReDef(redef) => { // REVIEW: - for chunk in attr_def.block.iter_mut() { + for chunk in redef.block.iter_mut() { self.resolve_pymod_path(chunk); } } @@ -267,9 +267,9 @@ impl<'a> Linker<'a> { self.replace_import(def); } } - Expr::AttrDef(attr_def) => { + Expr::ReDef(redef) => { // REVIEW: - for chunk in attr_def.block.iter_mut() { + for chunk in redef.block.iter_mut() { self.replace_import(chunk); } } diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 17fa2259..34107c7e 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -1473,10 +1473,11 @@ impl ASTLowerer { Ok(hir::PatchDef::new(hir_def.sig, base, hir_methods)) } - fn lower_attr_def(&mut self, attr_def: ast::AttrDef) -> LowerResult { - log!(info "entered {}({attr_def})", fn_name!()); - let attr = self.lower_acc(attr_def.attr)?; - let expr = self.lower_expr(*attr_def.expr)?; + fn lower_redef(&mut self, redef: ast::ReDef) -> LowerResult { + log!(info "entered {}({redef})", fn_name!()); + let loc = redef.loc(); + let attr = self.lower_acc(redef.attr)?; + let expr = self.lower_expr(*redef.expr)?; if let Err(err) = self.var_result_t_check( attr.loc(), &Str::from(attr.show()), @@ -1485,7 +1486,21 @@ impl ASTLowerer { ) { self.errs.push(err); } - Ok(hir::AttrDef::new(attr, hir::Block::new(vec![expr]))) + if !self.ctx.supertype_of(attr.ref_t(), expr.ref_t()) { + self.errs.push(LowerError::type_mismatch_error( + self.cfg.input.clone(), + line!() as usize, + loc, + self.ctx.caused_by(), + &attr.to_string_notype(), + None, + attr.ref_t(), + expr.ref_t(), + None, + None, + )); + } + Ok(hir::ReDef::new(attr, hir::Block::new(vec![expr]))) } fn register_trait_impl( @@ -1960,7 +1975,7 @@ impl ASTLowerer { ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)), ast::Expr::ClassDef(defs) => Ok(hir::Expr::ClassDef(self.lower_class_def(defs)?)), ast::Expr::PatchDef(defs) => Ok(hir::Expr::PatchDef(self.lower_patch_def(defs)?)), - ast::Expr::AttrDef(adef) => Ok(hir::Expr::AttrDef(self.lower_attr_def(adef)?)), + ast::Expr::ReDef(redef) => Ok(hir::Expr::ReDef(self.lower_redef(redef)?)), ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_decl(tasc)?)), other => self.lower_expr(other), } diff --git a/compiler/erg_compiler/transpile.rs b/compiler/erg_compiler/transpile.rs index fc2d22be..11d848dc 100644 --- a/compiler/erg_compiler/transpile.rs +++ b/compiler/erg_compiler/transpile.rs @@ -19,8 +19,8 @@ use crate::context::{Context, ContextProvider}; use crate::desugar_hir::HIRDesugarer; use crate::error::{CompileError, CompileErrors}; use crate::hir::{ - Accessor, Args, Array, AttrDef, BinOp, Block, Call, ClassDef, Def, Dict, Expr, Identifier, - Lambda, Literal, Params, PatchDef, Record, Set, Signature, Tuple, UnaryOp, HIR, + Accessor, Args, Array, BinOp, Block, Call, ClassDef, Def, Dict, Expr, Identifier, Lambda, + Literal, Params, PatchDef, ReDef, Record, Set, Signature, Tuple, UnaryOp, HIR, }; use crate::link::Linker; use crate::mod_cache::SharedModuleCache; @@ -415,7 +415,7 @@ impl ScriptGenerator { Expr::Lambda(lambda) => self.transpile_lambda(lambda), Expr::ClassDef(classdef) => self.transpile_classdef(classdef), Expr::PatchDef(patchdef) => self.transpile_patchdef(patchdef), - Expr::AttrDef(adef) => self.transpile_attrdef(adef), + Expr::ReDef(redef) => self.transpile_attrdef(redef), // TODO: Expr::Compound(comp) => { let mut code = "".to_string(); @@ -916,17 +916,17 @@ impl ScriptGenerator { code } - fn transpile_attrdef(&mut self, mut adef: AttrDef) -> String { - let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(adef.attr))); - if adef.block.len() > 1 { + fn transpile_attrdef(&mut self, mut redef: ReDef) -> String { + let mut code = format!("{} = ", self.transpile_expr(Expr::Accessor(redef.attr))); + if redef.block.len() > 1 { let name = format!("instant_block_{}__", self.fresh_var_n); self.fresh_var_n += 1; let mut code = format!("def {name}():\n"); - code += &self.transpile_block(adef.block, Return); + code += &self.transpile_block(redef.block, Return); self.prelude += &code; format!("{name}()") } else { - let expr = adef.block.remove(0); + let expr = redef.block.remove(0); code += &self.transpile_expr(expr); code } diff --git a/compiler/erg_parser/ast.rs b/compiler/erg_parser/ast.rs index d4077afe..6ea72191 100644 --- a/compiler/erg_parser/ast.rs +++ b/compiler/erg_parser/ast.rs @@ -3537,12 +3537,12 @@ impl Def { /// This is not necessary for Erg syntax, but necessary for mapping ASTs in Python #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct AttrDef { +pub struct ReDef { pub attr: Accessor, pub expr: Box, } -impl NestedDisplay for AttrDef { +impl NestedDisplay for ReDef { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { self.attr.fmt_nest(f, level)?; writeln!(f, " = ")?; @@ -3550,10 +3550,10 @@ impl NestedDisplay for AttrDef { } } -impl_display_from_nested!(AttrDef); -impl_locational!(AttrDef, attr, expr); +impl_display_from_nested!(ReDef); +impl_locational!(ReDef, attr, expr); -impl AttrDef { +impl ReDef { pub fn new(attr: Accessor, expr: Expr) -> Self { Self { attr, @@ -3672,14 +3672,14 @@ pub enum Expr { Methods(Methods), ClassDef(ClassDef), PatchDef(PatchDef), - AttrDef(AttrDef), + ReDef(ReDef), /// for mapping to Python AST Dummy(Dummy), } -impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, AttrDef, Dummy); +impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, ReDef, Dummy); impl_display_from_nested!(Expr); -impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, AttrDef, Dummy); +impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAsc, Def, Methods, ClassDef, PatchDef, ReDef, Dummy); impl Expr { pub fn is_match_call(&self) -> bool { diff --git a/compiler/erg_parser/desugar.rs b/compiler/erg_parser/desugar.rs index 5b88ff0e..6e6b83d9 100644 --- a/compiler/erg_parser/desugar.rs +++ b/compiler/erg_parser/desugar.rs @@ -9,14 +9,14 @@ use erg_common::Str; use erg_common::{enum_unwrap, get_hash, log, set}; use crate::ast::{ - Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, AttrDef, BinOp, - Block, Call, ClassAttr, ClassAttrs, ClassDef, ConstExpr, DataPack, Def, DefBody, DefId, Dict, - Dummy, Expr, Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods, - MixedRecord, Module, NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, - NormalSet, NormalTuple, ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, Record, - RecordAttrOrIdent, RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, - TupleTypeSpec, TypeAppArgs, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, - VarPattern, VarRecordAttr, VarSignature, + Accessor, Args, Array, ArrayComprehension, ArrayTypeSpec, ArrayWithLength, BinOp, Block, Call, + ClassAttr, ClassAttrs, ClassDef, ConstExpr, DataPack, Def, DefBody, DefId, Dict, Dummy, Expr, + Identifier, KeyValue, KwArg, Lambda, LambdaSignature, Literal, Methods, MixedRecord, Module, + NonDefaultParamSignature, NormalArray, NormalDict, NormalRecord, NormalSet, NormalTuple, + ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent, + RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec, + TypeAppArgs, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, VarPattern, + VarRecordAttr, VarSignature, }; use crate::token::{Token, TokenKind, COLON, DOT}; @@ -254,10 +254,10 @@ impl Desugarer { .collect(); Expr::PatchDef(PatchDef::new(def, methods)) } - Expr::AttrDef(adef) => { - let expr = desugar(*adef.expr); - let attr = Self::perform_desugar_acc(desugar, adef.attr); - Expr::AttrDef(AttrDef::new(attr, expr)) + Expr::ReDef(redef) => { + let expr = desugar(*redef.expr); + let attr = Self::perform_desugar_acc(desugar, redef.attr); + Expr::ReDef(ReDef::new(attr, expr)) } Expr::Lambda(lambda) => { let mut chunks = vec![];