Skip to content

Commit

Permalink
Merge pull request #149 from erg-lang/fix-#72
Browse files Browse the repository at this point in the history
Fix #72
  • Loading branch information
mtshiba authored Sep 11, 2022
2 parents fa8021a + c074200 commit 2126b17
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 83 deletions.
140 changes: 61 additions & 79 deletions compiler/erg_compiler/context/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ use Visibility::*;

impl Context {
/// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
fn registered(&self, name: &Str, is_const: bool) -> bool {
pub(crate) fn registered(&self, name: &str, is_const: bool) -> bool {
if self.params.iter().any(|(maybe_name, _)| {
maybe_name
.as_ref()
.map(|n| n.inspect() == name)
.map(|n| &n.inspect()[..] == name)
.unwrap_or(false)
}) || self.locals.contains_key(name)
{
Expand Down Expand Up @@ -87,7 +87,7 @@ impl Context {
let muty = Mutability::from(&name[..]);
let kind = id.map_or(VarKind::Declared, VarKind::Defined);
if self.registered(name, sig.is_const()) {
return Err(TyCheckError::duplicate_decl_error(
return Err(TyCheckError::reassign_error(
line!() as usize,
sig.loc(),
self.caused_by(),
Expand Down Expand Up @@ -136,22 +136,13 @@ impl Context {
self.validate_var_sig_t(ident, sig.t_spec.as_ref(), body_t, Normal)?;
let muty = Mutability::from(&ident.inspect()[..]);
let generalized = self.generalize_t(body_t.clone());
if self.registered(ident.inspect(), ident.is_const()) {
Err(TyCheckError::reassign_error(
line!() as usize,
ident.loc(),
self.caused_by(),
ident.inspect(),
))
} else {
if self.decls.remove(ident.inspect()).is_some() {
// something to do?
}
let vis = ident.vis();
let vi = VarInfo::new(generalized, muty, vis, VarKind::Defined(id), None);
self.locals.insert(ident.name.clone(), vi);
Ok(())
if self.decls.remove(ident.inspect()).is_some() {
// something to do?
}
let vis = ident.vis();
let vi = VarInfo::new(generalized, muty, vis, VarKind::Defined(id), None);
self.locals.insert(ident.name.clone(), vi);
Ok(())
}

/// 宣言が既にある場合、opt_decl_tに宣言の型を渡す
Expand Down Expand Up @@ -370,71 +361,62 @@ impl Context {
)
})?;
}
if self.registered(name.inspect(), name.is_const()) {
Err(TyCheckError::reassign_error(
line!() as usize,
name.loc(),
self.caused_by(),
name.inspect(),
))
let sub_t = if sig.ident.is_procedural() {
proc(
non_default_params.clone(),
var_args.cloned(),
default_params.clone(),
body_t.clone(),
)
} else {
let sub_t = if sig.ident.is_procedural() {
proc(
non_default_params.clone(),
var_args.cloned(),
default_params.clone(),
body_t.clone(),
)
} else {
func(
non_default_params.clone(),
var_args.cloned(),
default_params.clone(),
body_t.clone(),
)
};
sub_t.lift();
let found_t = self.generalize_t(sub_t);
if let Some(mut vi) = self.decls.remove(name) {
if vi.t.has_unbound_var() {
vi.t.lift();
vi.t = self.generalize_t(vi.t.clone());
}
self.decls.insert(name.clone(), vi);
func(
non_default_params.clone(),
var_args.cloned(),
default_params.clone(),
body_t.clone(),
)
};
sub_t.lift();
let found_t = self.generalize_t(sub_t);
if let Some(mut vi) = self.decls.remove(name) {
if vi.t.has_unbound_var() {
vi.t.lift();
vi.t = self.generalize_t(vi.t.clone());
}
if let Some(vi) = self.decls.remove(name) {
if !self.rec_supertype_of(&vi.t, &found_t) {
return Err(TyCheckError::violate_decl_error(
line!() as usize,
sig.loc(),
self.caused_by(),
name.inspect(),
&vi.t,
&found_t,
));
}
self.decls.insert(name.clone(), vi);
}
if let Some(vi) = self.decls.remove(name) {
if !self.rec_supertype_of(&vi.t, &found_t) {
return Err(TyCheckError::violate_decl_error(
line!() as usize,
sig.loc(),
self.caused_by(),
name.inspect(),
&vi.t,
&found_t,
));
}
let comptime_decos = sig
.decorators
.iter()
.filter_map(|deco| match &deco.0 {
ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
Some(local.inspect().clone())
}
_ => None,
})
.collect();
let vi = VarInfo::new(
found_t,
muty,
sig.ident.vis(),
VarKind::Defined(id),
Some(comptime_decos),
);
log!(info "Registered {}::{name}: {}", self.name, &vi.t);
self.locals.insert(name.clone(), vi);
Ok(())
}
let comptime_decos = sig
.decorators
.iter()
.filter_map(|deco| match &deco.0 {
ast::Expr::Accessor(ast::Accessor::Ident(local)) if local.is_const() => {
Some(local.inspect().clone())
}
_ => None,
})
.collect();
let vi = VarInfo::new(
found_t,
muty,
sig.ident.vis(),
VarKind::Defined(id),
Some(comptime_decos),
);
log!(info "Registered {}::{name}: {}", self.name, &vi.t);
self.locals.insert(name.clone(), vi);
Ok(())
}

// To allow forward references and recursive definitions
Expand Down
8 changes: 4 additions & 4 deletions compiler/erg_compiler/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -685,10 +685,10 @@ impl TyCheckError {
AssignError,
loc,
switch_lang!(
"japanese" => format!("変数{name}に再代入されています"),
"simplified_chinese" => format!("不能为变量{name}分配两次"),
"traditional_chinese" => format!("不能為變量{name}分配兩次"),
"english" => format!("cannot assign twice to the variable {name}"),
"japanese" => format!("変数{YELLOW}{name}{RESET}に再代入されています"),
"simplified_chinese" => format!("不能为变量{YELLOW}{name}{RESET}分配两次"),
"traditional_chinese" => format!("不能為變量{YELLOW}{name}{RESET}分配兩次"),
"english" => format!("cannot assign twice to the variable {YELLOW}{name}{RESET}"),
),
None,
),
Expand Down
8 changes: 8 additions & 0 deletions compiler/erg_compiler/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,14 @@ impl ASTLowerer {
} else {
"<lambda>"
};
if self.ctx.registered(name, def.sig.is_const()) {
return Err(LowerError::reassign_error(
line!() as usize,
def.sig.loc(),
self.ctx.caused_by(),
name,
));
}
self.ctx.grow(name, ContextKind::Instant, def.sig.vis())?;
let res = match def.sig {
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
Expand Down

0 comments on commit 2126b17

Please sign in to comment.