mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 04:44:44 +00:00
Fix #72
This commit is contained in:
parent
fad62f6fa3
commit
c0742005ee
3 changed files with 74 additions and 84 deletions
|
@ -25,11 +25,11 @@ use Visibility::*;
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
/// If it is a constant that is defined, there must be no variable of the same name defined across all scopes
|
/// 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, _)| {
|
if self.params.iter().any(|(maybe_name, _)| {
|
||||||
maybe_name
|
maybe_name
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|n| n.inspect() == name)
|
.map(|n| &n.inspect()[..] == name)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}) || self.locals.contains_key(name)
|
}) || self.locals.contains_key(name)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ impl Context {
|
||||||
let muty = Mutability::from(&name[..]);
|
let muty = Mutability::from(&name[..]);
|
||||||
let kind = id.map_or(VarKind::Declared, VarKind::Defined);
|
let kind = id.map_or(VarKind::Declared, VarKind::Defined);
|
||||||
if self.registered(name, sig.is_const()) {
|
if self.registered(name, sig.is_const()) {
|
||||||
return Err(TyCheckError::duplicate_decl_error(
|
return Err(TyCheckError::reassign_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
sig.loc(),
|
sig.loc(),
|
||||||
self.caused_by(),
|
self.caused_by(),
|
||||||
|
@ -136,22 +136,13 @@ impl Context {
|
||||||
self.validate_var_sig_t(ident, sig.t_spec.as_ref(), body_t, Normal)?;
|
self.validate_var_sig_t(ident, sig.t_spec.as_ref(), body_t, Normal)?;
|
||||||
let muty = Mutability::from(&ident.inspect()[..]);
|
let muty = Mutability::from(&ident.inspect()[..]);
|
||||||
let generalized = self.generalize_t(body_t.clone());
|
let generalized = self.generalize_t(body_t.clone());
|
||||||
if self.registered(ident.inspect(), ident.is_const()) {
|
if self.decls.remove(ident.inspect()).is_some() {
|
||||||
Err(TyCheckError::reassign_error(
|
// something to do?
|
||||||
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(())
|
|
||||||
}
|
}
|
||||||
|
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に宣言の型を渡す
|
/// 宣言が既にある場合、opt_decl_tに宣言の型を渡す
|
||||||
|
@ -370,71 +361,62 @@ impl Context {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
if self.registered(name.inspect(), name.is_const()) {
|
let sub_t = if sig.ident.is_procedural() {
|
||||||
Err(TyCheckError::reassign_error(
|
proc(
|
||||||
line!() as usize,
|
non_default_params.clone(),
|
||||||
name.loc(),
|
var_args.cloned(),
|
||||||
self.caused_by(),
|
default_params.clone(),
|
||||||
name.inspect(),
|
body_t.clone(),
|
||||||
))
|
)
|
||||||
} else {
|
} else {
|
||||||
let sub_t = if sig.ident.is_procedural() {
|
func(
|
||||||
proc(
|
non_default_params.clone(),
|
||||||
non_default_params.clone(),
|
var_args.cloned(),
|
||||||
var_args.cloned(),
|
default_params.clone(),
|
||||||
default_params.clone(),
|
body_t.clone(),
|
||||||
body_t.clone(),
|
)
|
||||||
)
|
};
|
||||||
} else {
|
sub_t.lift();
|
||||||
func(
|
let found_t = self.generalize_t(sub_t);
|
||||||
non_default_params.clone(),
|
if let Some(mut vi) = self.decls.remove(name) {
|
||||||
var_args.cloned(),
|
if vi.t.has_unbound_var() {
|
||||||
default_params.clone(),
|
vi.t.lift();
|
||||||
body_t.clone(),
|
vi.t = self.generalize_t(vi.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);
|
|
||||||
}
|
}
|
||||||
if let Some(vi) = self.decls.remove(name) {
|
self.decls.insert(name.clone(), vi);
|
||||||
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(())
|
|
||||||
}
|
}
|
||||||
|
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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// To allow forward references and recursive definitions
|
// To allow forward references and recursive definitions
|
||||||
|
|
|
@ -685,10 +685,10 @@ impl TyCheckError {
|
||||||
AssignError,
|
AssignError,
|
||||||
loc,
|
loc,
|
||||||
switch_lang!(
|
switch_lang!(
|
||||||
"japanese" => format!("変数{name}に再代入されています"),
|
"japanese" => format!("変数{YELLOW}{name}{RESET}に再代入されています"),
|
||||||
"simplified_chinese" => format!("不能为变量{name}分配两次"),
|
"simplified_chinese" => format!("不能为变量{YELLOW}{name}{RESET}分配两次"),
|
||||||
"traditional_chinese" => format!("不能為變量{name}分配兩次"),
|
"traditional_chinese" => format!("不能為變量{YELLOW}{name}{RESET}分配兩次"),
|
||||||
"english" => format!("cannot assign twice to the variable {name}"),
|
"english" => format!("cannot assign twice to the variable {YELLOW}{name}{RESET}"),
|
||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
|
|
|
@ -577,6 +577,14 @@ impl ASTLowerer {
|
||||||
} else {
|
} else {
|
||||||
"<lambda>"
|
"<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())?;
|
self.ctx.grow(name, ContextKind::Instant, def.sig.vis())?;
|
||||||
let res = match def.sig {
|
let res = match def.sig {
|
||||||
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
|
ast::Signature::Subr(sig) => self.lower_subr_def(sig, def.body),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue