Skip to content

Commit 659ba29

Browse files
committed
fix: missing closure assign tp check & fn auto cast
1 parent 760f6e4 commit 659ba29

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

src/ast/ctx.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use super::traits::CustomType;
2323

2424
use crate::ast::builder::BuilderEnum;
2525
use crate::ast::builder::IRBuilder;
26+
use crate::format_label;
2627
use crate::lsp::semantic_tokens::type_index;
2728

2829
use crate::mismatch_err;
@@ -221,7 +222,24 @@ impl<'a, 'ctx> Ctx<'a> {
221222
ori_value: usize,
222223
builder: &'b BuilderEnum<'a, 'ctx>,
223224
) -> Result<usize, PLDiag> {
224-
if let PLType::Closure(_) = &*target_pltype.borrow() {
225+
if let (PLType::Closure(c), PLType::Fn(f)) =
226+
(&*target_pltype.borrow(), &*ori_pltype.borrow())
227+
{
228+
if f.to_closure_ty(self, builder) != *c {
229+
return Err(ori_range
230+
.new_err(ErrorCode::FUNCTION_TYPE_NOT_MATCH)
231+
.add_label(
232+
target_range,
233+
self.get_file(),
234+
format_label!("expected type `{}`", c.get_name()),
235+
)
236+
.add_label(
237+
ori_range,
238+
self.get_file(),
239+
format_label!("found type `{}`", f.to_closure_ty(self, builder).get_name()),
240+
)
241+
.add_to_ctx(self));
242+
}
225243
if ori_value == usize::MAX {
226244
return Err(ori_range
227245
.new_err(ErrorCode::CANNOT_ASSIGN_INCOMPLETE_GENERICS)

src/ast/diag.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ define_error!(
122122
METHOD_NOT_FOUND = "method not found",
123123
DERIVE_TRAIT_NOT_IMPL = "derive trait not impl",
124124
CANNOT_ASSIGN_INCOMPLETE_GENERICS = "cannot assign incomplete generic function to variable",
125+
FUNCTION_TYPE_NOT_MATCH = "function type not match",
125126
);
126127
macro_rules! define_warn {
127128
($(

src/ast/node/statement.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,28 @@ impl Node for DefNode {
6464
return Err(ctx.add_diag(self.range.new_err(ErrorCode::UNDEFINED_TYPE)));
6565
}
6666
let re = re.unwrap();
67-
let tp = re.get_ty();
67+
let mut tp = re.get_ty();
68+
let v = if let PLType::Fn(f) = &*tp.clone().borrow() {
69+
let oritp = tp;
70+
let c = Arc::new(RefCell::new(PLType::Closure(f.to_closure_ty(ctx, builder))));
71+
tp = c.clone();
72+
ctx.up_cast(
73+
c,
74+
oritp,
75+
Default::default(),
76+
Default::default(),
77+
re.get_value(),
78+
builder,
79+
)
80+
.unwrap()
81+
} else {
82+
re.get_value()
83+
};
6884
if pltype.is_none() {
6985
ctx.push_type_hints(self.var.range, tp.clone());
7086
pltype = Some(tp);
7187
}
72-
expv = Some(re.get_value());
88+
expv = Some(v);
7389
}
7490
let pltype = pltype.unwrap();
7591
let ptr2value = builder.alloc(

src/ast/pltype.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,22 @@ impl TryFrom<PLType> for FNValue {
600600
}
601601
}
602602
impl FNValue {
603+
pub fn to_closure_ty<'a, 'ctx, 'b>(
604+
&self,
605+
ctx: &'b mut Ctx<'a>,
606+
builder: &'b BuilderEnum<'a, 'ctx>,
607+
) -> ClosureType {
608+
return ClosureType {
609+
range: Default::default(),
610+
ret_type: self.fntype.ret_pltype.get_type(ctx, builder).unwrap(),
611+
arg_types: self
612+
.fntype
613+
.param_pltypes
614+
.iter()
615+
.map(|x| x.get_type(ctx, builder).unwrap())
616+
.collect(),
617+
};
618+
}
603619
pub fn is_modified_by(&self, modifier: TokenType) -> bool {
604620
if let Some((t, _)) = self.fntype.modifier {
605621
t == modifier

0 commit comments

Comments
 (0)