checker: fix generic inference in if expressions used in assignments (#21781)

This commit is contained in:
Felipe Pena 2024-07-02 04:50:26 -03:00 committed by GitHub
parent 06825006b3
commit a3793e3bb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 0 deletions

View file

@ -53,6 +53,14 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
right_len = node.right_types.len
} else if right_type == ast.void_type {
right_len = 0
if mut right is ast.IfExpr {
last_branch := right.branches.last()
last_stmts := last_branch.stmts.filter(it is ast.ExprStmt)
if last_stmts.any((it as ast.ExprStmt).typ.has_flag(.generic)) {
right_len = last_branch.stmts.len
node.right_types = last_stmts.map((it as ast.ExprStmt).typ)
}
}
}
}
if mut right is ast.InfixExpr {

View file

@ -473,6 +473,10 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(stmt.typ)}`',
node.pos)
} else {
if node.is_expr == false && c.comptime.is_generic_param_var(stmt.expr) {
// generic variable no yet type bounded
node.is_expr = true
}
if c.inside_assign && node.is_expr && !node.typ.has_flag(.shared_f)
&& stmt.typ != ast.voidptr_type {
if stmt.typ.is_ptr() != node.typ.is_ptr() {

View file

@ -0,0 +1,8 @@
fn clamp[T](a T, x T, b T) T {
min := if x < b { x } else { b }
return if min < a { a } else { min }
}
fn test_main() {
assert dump(clamp(1, 2, 3)) == 2
}