aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorTetralux <tetralux@teknik.io>2020-04-22 06:12:41 +0100
committerGitHub <noreply@github.com>2020-04-22 06:12:41 +0100
commite7e936f4804d7e5ba5f5cb77818240216a80648b (patch)
tree2ad8f308089222f37d32e0e6a3475a2a6d4c1710 /src/check_expr.cpp
parent3afa2736b7c8826527cb71ec3ca220750e0d2a9e (diff)
parent026bb8ed6f6e626c69ccfe32de5b2323d86b4620 (diff)
Merge branch 'master' into fix-sync-badopt
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp74
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;
}