diff options
| author | Tetralux <tetralux@teknik.io> | 2020-04-22 06:12:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-22 06:12:41 +0100 |
| commit | e7e936f4804d7e5ba5f5cb77818240216a80648b (patch) | |
| tree | 2ad8f308089222f37d32e0e6a3475a2a6d4c1710 /src/check_expr.cpp | |
| parent | 3afa2736b7c8826527cb71ec3ca220750e0d2a9e (diff) | |
| parent | 026bb8ed6f6e626c69ccfe32de5b2323d86b4620 (diff) | |
Merge branch 'master' into fix-sync-badopt
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 9879d3b8b..af9750ee4 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5750,19 +5750,45 @@ bool check_assignment_arguments(CheckerContext *ctx, Array<Operand> const &lhs, optional_ok = true; tuple_index += 2; + } else if (o.mode == Addressing_OptionalOk && is_type_tuple(o.type)) { + Type *tuple = o.type; + GB_ASSERT(tuple->Tuple.variables.count == 2); + Ast *expr = unparen_expr(o.expr); + if (expr->kind == Ast_CallExpr) { + expr->CallExpr.optional_ok_one = true; + } + Operand val = o; + val.type = tuple->Tuple.variables[0]->type; + val.mode = Addressing_Value; + array_add(operands, val); + tuple_index += tuple->Tuple.variables.count; } else { array_add(operands, o); tuple_index += 1; } } else { TypeTuple *tuple = &o.type->Tuple; - for_array(j, tuple->variables) { - o.type = tuple->variables[j]->type; - array_add(operands, o); - } + if (o.mode == Addressing_OptionalOk && is_type_tuple(o.type) && lhs.count == 1) { + GB_ASSERT(tuple->variables.count == 2); + Ast *expr = unparen_expr(o.expr); + if (expr->kind == Ast_CallExpr) { + expr->CallExpr.optional_ok_one = true; + } + Operand val = o; + val.type = tuple->variables[0]->type; + val.mode = Addressing_Value; + array_add(operands, val); + tuple_index += tuple->variables.count; - isize count = tuple->variables.count; - tuple_index += 2; + add_type_and_value(c->info, val.expr, val.mode, val.type, val.value); + } else { + for_array(j, tuple->variables) { + o.type = tuple->variables[j]->type; + array_add(operands, o); + } + + tuple_index += tuple->variables.count; + } } } @@ -5839,13 +5865,30 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, } } else { TypeTuple *tuple = &o.type->Tuple; - for_array(j, tuple->variables) { - o.type = tuple->variables[j]->type; - array_add(operands, o); - } + if (o.mode == Addressing_OptionalOk && lhs_count == 1) { + GB_ASSERT(tuple->variables.count == 2); + Ast *expr = unparen_expr(o.expr); + if (expr->kind == Ast_CallExpr) { + expr->CallExpr.optional_ok_one = true; + } + Operand val = o; + val.type = tuple->variables[0]->type; + val.mode = Addressing_Value; + array_add(operands, val); + + isize count = tuple->variables.count; + tuple_index += add_dependencies_from_unpacking(c, lhs, lhs_count, tuple_index, count); + + add_type_and_value(c->info, val.expr, val.mode, val.type, val.value); + } else { + for_array(j, tuple->variables) { + o.type = tuple->variables[j]->type; + array_add(operands, o); + } - isize count = tuple->variables.count; - tuple_index += add_dependencies_from_unpacking(c, lhs, lhs_count, tuple_index, count); + isize count = tuple->variables.count; + tuple_index += add_dependencies_from_unpacking(c, lhs, lhs_count, tuple_index, count); + } } } @@ -7332,7 +7375,7 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Type *t if (pl->inlining == ProcInlining_no_inline) { error(call, "'inline' cannot be applied to a procedure that has be marked as 'no_inline'"); } - } + } } break; } @@ -7342,6 +7385,11 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Type *t } operand->expr = call; + + if (pt->kind == Type_Proc && pt->Proc.optional_ok) { + operand->mode = Addressing_OptionalOk; + } + return Expr_Expr; } |