aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-04-15 15:36:21 +0100
committergingerBill <bill@gingerbill.org>2023-04-15 15:37:32 +0100
commit5da76ae34bac2f54b1bda5528cf49c0551e88bba (patch)
tree78a6189f351ceb8dd070c2e453c4b0462d532235 /src/check_expr.cpp
parentb7b5043aea792839226baf9e6d0ca54b73dac9a5 (diff)
Add `struct #no_copy`
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index f27675301..e55765ff8 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -5043,6 +5043,21 @@ gb_internal isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lh
return tuple_count;
}
+gb_internal bool check_no_copy_assignment(Operand const &o, String const &context) {
+ if (o.type && is_type_no_copy(o.type)) {
+ Ast *expr = unparen_expr(o.expr);
+ if (expr && o.mode != Addressing_Constant) {
+ if (expr->kind == Ast_CallExpr) {
+ // Okay
+ } else {
+ error(o.expr, "Invalid use a #no_copy value in %.*s", LIT(context));
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array<Operand> const &lhs, Array<Operand> *operands, Slice<Ast *> const &rhs) {
bool optional_ok = false;
@@ -5114,6 +5129,7 @@ gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array<Operand>
for (Entity *e : tuple->variables) {
o.type = e->type;
array_add(operands, o);
+ check_no_copy_assignment(o, str_lit("assignment"));
}
tuple_index += tuple->variables.count;
@@ -5952,6 +5968,10 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op
}
}
+ for (Operand const &o : operands) {
+ check_no_copy_assignment(o, str_lit("call expression"));
+ }
+
if (operand->mode == Addressing_ProcGroup) {
check_entity_decl(c, operand->proc_group, nullptr, nullptr);