Skip to content

Commit

Permalink
add a option emit_error in check_type() to not report an error when t…
Browse files Browse the repository at this point in the history
…rying to upgrade dict into schema

Signed-off-by: he1pa <[email protected]>
  • Loading branch information
He1pa committed May 24, 2024
1 parent 7c2681c commit 8024feb
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 33 deletions.
3 changes: 2 additions & 1 deletion kclvm/sema/src/resolver/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl<'ctx> Resolver<'ctx> {
return;
}
};
self.must_assignable_to(ty.clone(), expected_ty, args[i].get_span_pos(), None)
self.must_assignable_to(ty.clone(), expected_ty, args[i].get_span_pos(), None, true)
}
// Do keyword argument type check
for (i, (arg_name, kwarg_ty)) in kwarg_types.iter().enumerate() {
Expand Down Expand Up @@ -132,6 +132,7 @@ impl<'ctx> Resolver<'ctx> {
expected_types[0].clone(),
kwargs[i].get_span_pos(),
None,
true,
);
};
}
Expand Down
1 change: 1 addition & 0 deletions kclvm/sema/src/resolver/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ impl<'ctx> Resolver<'ctx> {
ty,
key.get_span_pos(),
Some(obj_last.get_span_pos()),
true,
);
}
self.clear_config_expr_context(stack_depth, false);
Expand Down
14 changes: 13 additions & 1 deletion kclvm/sema/src/resolver/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
expected_ty.clone(),
unification_stmt.target.get_span_pos(),
None,
true,
);
if !ty.is_any() && expected_ty.is_any() {
self.set_type_to_scope(&names[0].node, ty, &names[0]);
Expand Down Expand Up @@ -184,6 +185,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
expected_ty.clone(),
target.get_span_pos(),
None,
true,
);

let upgrade_schema_type = self.upgrade_dict_to_schema(
Expand Down Expand Up @@ -219,6 +221,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
expected_ty.clone(),
target.get_span_pos(),
None,
true,
);

let upgrade_schema_type = self.upgrade_dict_to_schema(
Expand Down Expand Up @@ -287,6 +290,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
expected_ty,
aug_assign_stmt.target.get_span_pos(),
None,
true,
);
self.ctx.l_value = false;
new_target_ty
Expand Down Expand Up @@ -453,6 +457,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
expected_ty,
schema_attr.name.get_span_pos(),
None,
true,
);
}
// Assign
Expand All @@ -461,6 +466,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
expected_ty,
schema_attr.name.get_span_pos(),
None,
true,
),
},
None => bug!("invalid ast schema attr op kind"),
Expand Down Expand Up @@ -1094,7 +1100,13 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> {
let real_ret_ty = self.stmts(&lambda_expr.body);
self.leave_scope();
self.ctx.in_lambda_expr.pop();
self.must_assignable_to(real_ret_ty.clone(), ret_ty.clone(), (start, end), None);
self.must_assignable_to(
real_ret_ty.clone(),
ret_ty.clone(),
(start, end),
None,
true,
);
if !real_ret_ty.is_any() && ret_ty.is_any() && lambda_expr.return_ty.is_none() {
ret_ty = real_ret_ty;
}
Expand Down
1 change: 1 addition & 0 deletions kclvm/sema/src/resolver/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl<'ctx> Resolver<'ctx> {
expected_ty,
index_signature_node.get_span_pos(),
None,
true,
);
}
}
Expand Down
86 changes: 55 additions & 31 deletions kclvm/sema/src/resolver/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<'ctx> Resolver<'ctx> {
#[inline]
pub fn must_be_type(&mut self, expr: &'ctx ast::NodeRef<ast::Expr>, expected_ty: TypeRef) {
let ty = self.expr(expr);
self.must_assignable_to(ty, expected_ty, expr.get_span_pos(), None);
self.must_assignable_to(ty, expected_ty, expr.get_span_pos(), None, true);
}

/// Must assignable to the expected type.
Expand All @@ -104,8 +104,9 @@ impl<'ctx> Resolver<'ctx> {
expected_ty: TypeRef,
range: Range,
expected_pos: Option<Range>,
emit_error: bool,
) {
if !self.check_type(ty.clone(), expected_ty.clone(), &range) {
if !self.check_type(ty.clone(), expected_ty.clone(), &range, emit_error) && emit_error {
let mut msgs = vec![Message {
range,
style: Style::LineAndColumn,
Expand Down Expand Up @@ -140,8 +141,13 @@ impl<'ctx> Resolver<'ctx> {
) -> TypeRef {
match (&ty.kind, &expected_ty.kind) {
(TypeKind::Dict(DictType { key_ty, val_ty, .. }), TypeKind::Schema(schema_ty)) => {
if self.dict_assignable_to_schema(key_ty.clone(), val_ty.clone(), schema_ty, range)
{
if self.dict_assignable_to_schema(
key_ty.clone(),
val_ty.clone(),
schema_ty,
range,
false,
) {
expected_ty
} else {
ty
Expand All @@ -167,7 +173,7 @@ impl<'ctx> Resolver<'ctx> {
TypeKind::Dict(DictType { key_ty, val_ty, .. }),
TypeKind::Union(expected_union_type),
) => {
let types: Vec<&Arc<Type>> = expected_union_type
let types: Vec<Arc<Type>> = expected_union_type
.iter()
.filter(|ty| match ty.kind {
TypeKind::Schema(_) => true,
Expand All @@ -179,20 +185,13 @@ impl<'ctx> Resolver<'ctx> {
val_ty.clone(),
&ty.into_schema_type(),
range,
false,
)
})
.map(|ty| ty.clone())
.collect();
match types.len() {
0 => ty,
1 => types[0].clone(),
_ => Type::union(
&types
.into_iter()
.map(|ty| ty.clone())
.collect::<Vec<TypeRef>>(),
)
.into(),
}

crate::ty::sup(&types).into()
}
_ => ty,
}
Expand Down Expand Up @@ -257,17 +256,29 @@ impl<'ctx> Resolver<'ctx> {
self.set_type_to_scope(name, target_ty.clone(), &target.node.names[0]);

// Check the type of value and the type annotation of target
self.must_assignable_to(value_ty.clone(), target_ty, target.get_span_pos(), None)
self.must_assignable_to(
value_ty.clone(),
target_ty,
target.get_span_pos(),
None,
true,
)
}
}
}

/// The check type main function, returns a boolean result.
#[inline]
pub fn check_type(&mut self, ty: TypeRef, expected_ty: TypeRef, range: &Range) -> bool {
pub fn check_type(
&mut self,
ty: TypeRef,
expected_ty: TypeRef,
range: &Range,
emit_error: bool,
) -> bool {
match (&ty.kind, &expected_ty.kind) {
(TypeKind::List(item_ty), TypeKind::List(expected_item_ty)) => {
self.check_type(item_ty.clone(), expected_item_ty.clone(), range)
self.check_type(item_ty.clone(), expected_item_ty.clone(), range, emit_error)
}
(
TypeKind::Dict(DictType { key_ty, val_ty, .. }),
Expand All @@ -277,18 +288,23 @@ impl<'ctx> Resolver<'ctx> {
..
}),
) => {
self.check_type(key_ty.clone(), expected_key_ty.clone(), range)
&& self.check_type(val_ty.clone(), expected_val_ty.clone(), range)
}
(TypeKind::Dict(DictType { key_ty, val_ty, .. }), TypeKind::Schema(schema_ty)) => {
self.dict_assignable_to_schema(key_ty.clone(), val_ty.clone(), schema_ty, range)
self.check_type(key_ty.clone(), expected_key_ty.clone(), range, emit_error)
&& self.check_type(val_ty.clone(), expected_val_ty.clone(), range, emit_error)
}
(TypeKind::Dict(DictType { key_ty, val_ty, .. }), TypeKind::Schema(schema_ty)) => self
.dict_assignable_to_schema(
key_ty.clone(),
val_ty.clone(),
schema_ty,
range,
emit_error,
),
(TypeKind::Union(types), _) => types
.iter()
.all(|ty| self.check_type(ty.clone(), expected_ty.clone(), range)),
(_, TypeKind::Union(types)) => types
.iter()
.any(|expected_ty| self.check_type(ty.clone(), expected_ty.clone(), range)),
.all(|ty| self.check_type(ty.clone(), expected_ty.clone(), range, emit_error)),
(_, TypeKind::Union(types)) => types.iter().any(|expected_ty| {
self.check_type(ty.clone(), expected_ty.clone(), range, emit_error)
}),
_ => assignable_to(ty, expected_ty),
}
}
Expand All @@ -301,9 +317,16 @@ impl<'ctx> Resolver<'ctx> {
val_ty: TypeRef,
schema_ty: &SchemaType,
range: &Range,
emit_error: bool,
) -> bool {
if let Some(index_signature) = &schema_ty.index_signature {
if !self.check_type(val_ty.clone(), index_signature.val_ty.clone(), range) {
if !self.check_type(
val_ty.clone(),
index_signature.val_ty.clone(),
range,
emit_error,
) && emit_error
{
self.handler.add_type_error(
&format!(
"expected schema index signature value type {}, got {}",
Expand All @@ -314,8 +337,8 @@ impl<'ctx> Resolver<'ctx> {
);
}
if index_signature.any_other {
return self.check_type(key_ty, index_signature.key_ty.clone(), range)
&& self.check_type(val_ty, index_signature.val_ty.clone(), range);
return self.check_type(key_ty, index_signature.key_ty.clone(), range, emit_error)
&& self.check_type(val_ty, index_signature.val_ty.clone(), range, emit_error);
}
true
} else {
Expand All @@ -328,6 +351,7 @@ impl<'ctx> Resolver<'ctx> {
attr_obj.ty.clone(),
range.clone(),
Some(attr_obj.range.clone()),
emit_error,
);
return true;
}
Expand Down

0 comments on commit 8024feb

Please sign in to comment.