checker, cgen: fix error for if expr with generic sumtype (#14056)

master
yuyi 2022-04-17 13:19:44 +08:00 committed by GitHub
parent 4f14f7714f
commit cb44f5981e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 1 deletions

View File

@ -204,6 +204,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
} }
} }
if node.is_expr && c.table.sym(former_expected_type).kind == .sum_type { if node.is_expr && c.table.sym(former_expected_type).kind == .sum_type {
node.typ = former_expected_type
continue continue
} }
if is_noreturn_callexpr(last_expr.expr) { if is_noreturn_callexpr(last_expr.expr) {

View File

@ -74,7 +74,12 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
g.expr(branch.cond) g.expr(branch.cond)
g.write(' ? ') g.write(' ? ')
} }
prev_expected_cast_type := g.expected_cast_type
if node.is_expr && g.table.sym(node.typ).kind == .sum_type {
g.expected_cast_type = node.typ
}
g.stmts(branch.stmts) g.stmts(branch.stmts)
g.expected_cast_type = prev_expected_cast_type
} }
if node.branches.len == 1 { if node.branches.len == 1 {
g.write(': 0') g.write(': 0')
@ -195,11 +200,12 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
} }
} }
if needs_tmp_var { if needs_tmp_var {
prev_expected_cast_type := g.expected_cast_type
if node.is_expr && g.table.sym(node.typ).kind == .sum_type { if node.is_expr && g.table.sym(node.typ).kind == .sum_type {
g.expected_cast_type = node.typ g.expected_cast_type = node.typ
} }
g.stmts_with_tmp_var(branch.stmts, tmp) g.stmts_with_tmp_var(branch.stmts, tmp)
g.expected_cast_type = 0 g.expected_cast_type = prev_expected_cast_type
} else { } else {
// restore if_expr stmt header pos // restore if_expr stmt header pos
stmt_pos := g.nth_stmt_pos(0) stmt_pos := g.nth_stmt_pos(0)

View File

@ -0,0 +1,17 @@
type Opt<T> = None<T> | Some<T>
struct None<T> {}
struct Some<T> {
mut:
value T
}
fn operation(r int) Opt<int> {
return if r > 0 { Some<int>{r} } else { None<int>{} }
}
fn test_if_expr_with_generic_sumtype() {
op := operation(1)
assert Opt<int>(Some<int>{1}) == op
}