Fix type ascription bugs

This commit is contained in:
Shunsuke Shibayama 2022-09-26 14:50:28 +09:00
parent 5aae4a69a5
commit aacad4fc8e
7 changed files with 79 additions and 8 deletions

View file

@ -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(),

View file

@ -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,

View file

@ -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) {

View file

@ -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,
} }
} }

View file

@ -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

View file

@ -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(),

View file

@ -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);
}
_ => {} _ => {}
} }
} }