mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-01 17:33:29 +00:00
Fix type ascription bugs
This commit is contained in:
parent
5aae4a69a5
commit
aacad4fc8e
7 changed files with 79 additions and 8 deletions
|
@ -1619,7 +1619,10 @@ impl CodeGenerator {
|
||||||
Expr::Compound(chunks) => {
|
Expr::Compound(chunks) => {
|
||||||
self.emit_frameless_block(chunks, vec![]);
|
self.emit_frameless_block(chunks, vec![]);
|
||||||
}
|
}
|
||||||
// Dict, Decl
|
Expr::TypeAsc(tasc) => {
|
||||||
|
self.emit_expr(*tasc.expr);
|
||||||
|
}
|
||||||
|
// Dict,
|
||||||
other => {
|
other => {
|
||||||
self.errs.push(CompileError::feature_error(
|
self.errs.push(CompileError::feature_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
|
|
@ -529,8 +529,8 @@ impl Context {
|
||||||
Ok(decl_t.typ().clone())
|
Ok(decl_t.typ().clone())
|
||||||
} else {
|
} else {
|
||||||
let typ = mono(self.mod_name(), Str::rc(other));
|
let typ = mono(self.mod_name(), Str::rc(other));
|
||||||
if self.get_nominal_type_ctx(&typ).is_some() {
|
if let Some((defined_t, _)) = self.get_nominal_type_ctx(&typ) {
|
||||||
Ok(typ)
|
Ok(defined_t.clone())
|
||||||
} else {
|
} else {
|
||||||
Err(TyCheckError::no_var_error(
|
Err(TyCheckError::no_var_error(
|
||||||
line!() as usize,
|
line!() as usize,
|
||||||
|
|
|
@ -839,6 +839,7 @@ impl Context {
|
||||||
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||||
#[allow(clippy::match_single_binding)]
|
#[allow(clippy::match_single_binding)]
|
||||||
match &__name__[..] {
|
match &__name__[..] {
|
||||||
|
// TODO: erg builtin modules
|
||||||
_ => self.import_user_erg_mod(
|
_ => self.import_user_erg_mod(
|
||||||
current_input,
|
current_input,
|
||||||
var_name,
|
var_name,
|
||||||
|
@ -957,13 +958,62 @@ impl Context {
|
||||||
|
|
||||||
fn import_user_py_mod(
|
fn import_user_py_mod(
|
||||||
&self,
|
&self,
|
||||||
_current_input: Input,
|
current_input: Input,
|
||||||
_var_name: &VarName,
|
var_name: &VarName,
|
||||||
lit: &Literal,
|
lit: &Literal,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
|
let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str);
|
||||||
let _mod_cache = self.mod_cache.as_ref().unwrap();
|
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||||
todo!()
|
if let Some((_, entry)) = py_mod_cache.get_by_name(&__name__) {
|
||||||
|
py_mod_cache.register_alias(var_name.clone(), entry);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let mut dir = if let Input::File(mut path) = current_input {
|
||||||
|
path.pop();
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
PathBuf::new()
|
||||||
|
};
|
||||||
|
dir.push(format!("{__name__}.er"));
|
||||||
|
// TODO: returns an error
|
||||||
|
let path = match dir.canonicalize() {
|
||||||
|
Ok(path) => path,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(TyCheckError::import_error(
|
||||||
|
line!() as usize,
|
||||||
|
err.to_string(),
|
||||||
|
lit.loc(),
|
||||||
|
self.caused_by(),
|
||||||
|
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
|
||||||
|
self.similar_builtin_py_mod_name(&__name__).or_else(|| {
|
||||||
|
self.py_mod_cache
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.get_similar_name(&__name__)
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let cfg = ErgConfig {
|
||||||
|
input: Input::File(path),
|
||||||
|
..ErgConfig::default()
|
||||||
|
};
|
||||||
|
let src = cfg.input.read();
|
||||||
|
let mut builder = HIRBuilder::new_with_cache(
|
||||||
|
cfg,
|
||||||
|
var_name.inspect(),
|
||||||
|
py_mod_cache.clone(),
|
||||||
|
py_mod_cache.clone(),
|
||||||
|
);
|
||||||
|
match builder.build(src, "declare") {
|
||||||
|
Ok(hir) => {
|
||||||
|
py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx());
|
||||||
|
}
|
||||||
|
Err(errs) => {
|
||||||
|
errs.fmt_all_stderr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {
|
pub(crate) fn _push_subtype_bound(&mut self, sub: Type, sup: Type) {
|
||||||
|
|
|
@ -137,6 +137,9 @@ impl SideEffectChecker {
|
||||||
self.path_stack.pop();
|
self.path_stack.pop();
|
||||||
self.block_stack.pop();
|
self.block_stack.pop();
|
||||||
}
|
}
|
||||||
|
Expr::TypeAsc(tasc) => {
|
||||||
|
self.check_expr(&tasc.expr);
|
||||||
|
}
|
||||||
other => todo!("{other}"),
|
other => todo!("{other}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,6 +295,9 @@ impl SideEffectChecker {
|
||||||
self.path_stack.pop();
|
self.path_stack.pop();
|
||||||
self.block_stack.pop();
|
self.block_stack.pop();
|
||||||
}
|
}
|
||||||
|
Expr::TypeAsc(type_asc) => {
|
||||||
|
self.check_expr(&type_asc.expr);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,6 +312,7 @@ impl SideEffectChecker {
|
||||||
// !procedural: !x.y
|
// !procedural: !x.y
|
||||||
Expr::Accessor(Accessor::Attr(attr)) => attr.ident.is_procedural(),
|
Expr::Accessor(Accessor::Attr(attr)) => attr.ident.is_procedural(),
|
||||||
Expr::Accessor(_) => todo!(),
|
Expr::Accessor(_) => todo!(),
|
||||||
|
Expr::TypeAsc(tasc) => self.is_procedural(&tasc.expr),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1579,6 +1579,10 @@ impl Expr {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_type_asc(&self) -> bool {
|
||||||
|
matches!(self, Expr::TypeAsc(_))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toplevel grammar unit
|
/// Toplevel grammar unit
|
||||||
|
|
|
@ -146,8 +146,12 @@ impl ASTLowerer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// OK: exec `i: Int`
|
||||||
|
/// OK: exec `i: Int = 1`
|
||||||
|
/// NG: exec `1 + 2`
|
||||||
|
/// OK: exec `None`
|
||||||
fn use_check(&self, expr: &hir::Expr, mode: &str) -> LowerResult<()> {
|
fn use_check(&self, expr: &hir::Expr, mode: &str) -> LowerResult<()> {
|
||||||
if mode != "eval" && !expr.ref_t().is_nonelike() {
|
if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() {
|
||||||
Err(LowerError::syntax_error(
|
Err(LowerError::syntax_error(
|
||||||
0,
|
0,
|
||||||
expr.loc(),
|
expr.loc(),
|
||||||
|
|
|
@ -187,6 +187,9 @@ impl OwnershipChecker {
|
||||||
self.check_block(&lambda.body);
|
self.check_block(&lambda.body);
|
||||||
self.path_stack.pop();
|
self.path_stack.pop();
|
||||||
}
|
}
|
||||||
|
Expr::TypeAsc(asc) => {
|
||||||
|
self.check_expr(&asc.expr, ownership, chunk);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue