mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 21:01:10 +00:00
Add TypeAscription
This commit is contained in:
parent
6cfb0d1544
commit
9ccfdadf22
3 changed files with 68 additions and 3 deletions
|
@ -489,6 +489,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
hir::Expr::TypeAsc(tasc) => self.resolve_expr_t(&mut tasc.expr),
|
||||||
hir::Expr::Code(chunks) | hir::Expr::Compound(chunks) => {
|
hir::Expr::Code(chunks) | hir::Expr::Compound(chunks) => {
|
||||||
for chunk in chunks.iter_mut() {
|
for chunk in chunks.iter_mut() {
|
||||||
self.resolve_expr_t(chunk)?;
|
self.resolve_expr_t(chunk)?;
|
||||||
|
|
|
@ -1485,6 +1485,49 @@ impl AttrDef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct TypeAscription {
|
||||||
|
pub expr: Box<Expr>,
|
||||||
|
pub spec: TypeSpec,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NestedDisplay for TypeAscription {
|
||||||
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result {
|
||||||
|
writeln!(f, "{}: {}", self.expr, self.spec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_display_from_nested!(TypeAscription);
|
||||||
|
impl_locational!(TypeAscription, expr, spec);
|
||||||
|
|
||||||
|
impl HasType for TypeAscription {
|
||||||
|
#[inline]
|
||||||
|
fn ref_t(&self) -> &Type {
|
||||||
|
self.expr.ref_t()
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn ref_mut_t(&mut self) -> &mut Type {
|
||||||
|
self.expr.ref_mut_t()
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn signature_t(&self) -> Option<&Type> {
|
||||||
|
self.expr.signature_t()
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn signature_mut_t(&mut self) -> Option<&mut Type> {
|
||||||
|
self.expr.signature_mut_t()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeAscription {
|
||||||
|
pub fn new(expr: Expr, spec: TypeSpec) -> Self {
|
||||||
|
Self {
|
||||||
|
expr: Box::new(expr),
|
||||||
|
spec,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
Lit(Literal),
|
Lit(Literal),
|
||||||
|
@ -1502,14 +1545,15 @@ pub enum Expr {
|
||||||
Def(Def),
|
Def(Def),
|
||||||
ClassDef(ClassDef),
|
ClassDef(ClassDef),
|
||||||
AttrDef(AttrDef),
|
AttrDef(AttrDef),
|
||||||
|
TypeAsc(TypeAscription),
|
||||||
Code(Block), // code object
|
Code(Block), // code object
|
||||||
Compound(Block), // compound statement
|
Compound(Block), // compound statement
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound);
|
impl_nested_display_for_chunk_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc);
|
||||||
impl_display_from_nested!(Expr);
|
impl_display_from_nested!(Expr);
|
||||||
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound);
|
impl_locational_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc);
|
||||||
impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound);
|
impl_t_for_enum!(Expr; Lit, Accessor, Array, Tuple, Dict, Record, BinOp, UnaryOp, Call, Lambda, Decl, Def, ClassDef, AttrDef, Code, Compound, TypeAsc);
|
||||||
|
|
||||||
impl Expr {
|
impl Expr {
|
||||||
pub fn receiver_t(&self) -> Option<&Type> {
|
pub fn receiver_t(&self) -> Option<&Type> {
|
||||||
|
|
|
@ -968,6 +968,25 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lower_type_asc(&mut self, tasc: ast::TypeAscription) -> LowerResult<hir::TypeAscription> {
|
||||||
|
log!(info "entered {}({tasc})", fn_name!());
|
||||||
|
let t = self.ctx.instantiate_typespec(
|
||||||
|
&tasc.t_spec,
|
||||||
|
None,
|
||||||
|
&mut None,
|
||||||
|
RegistrationMode::Normal,
|
||||||
|
)?;
|
||||||
|
let expr = self.lower_expr(*tasc.expr)?;
|
||||||
|
self.ctx.sub_unify(
|
||||||
|
expr.ref_t(),
|
||||||
|
&t,
|
||||||
|
Some(expr.loc()),
|
||||||
|
None,
|
||||||
|
Some(&Str::from(expr.to_string())),
|
||||||
|
)?;
|
||||||
|
Ok(hir::TypeAscription::new(expr, tasc.t_spec))
|
||||||
|
}
|
||||||
|
|
||||||
// Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
|
// Call.obj == Accessor cannot be type inferred by itself (it can only be inferred with arguments)
|
||||||
// so turn off type checking (check=false)
|
// so turn off type checking (check=false)
|
||||||
fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult<hir::Expr> {
|
fn lower_expr(&mut self, expr: ast::Expr) -> LowerResult<hir::Expr> {
|
||||||
|
@ -985,6 +1004,7 @@ impl ASTLowerer {
|
||||||
ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)),
|
ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)),
|
||||||
ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)),
|
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::ClassDef(defs) => Ok(hir::Expr::ClassDef(self.lower_class_def(defs)?)),
|
||||||
|
ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.lower_type_asc(tasc)?)),
|
||||||
other => todo!("{other}"),
|
other => todo!("{other}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue