aboutsummaryrefslogtreecommitdiff
path: root/src/check_type.cpp
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2021-04-23 10:24:05 +0200
committerDaniel Gavin <danielgavin5@hotmail.com>2021-04-23 10:24:05 +0200
commitf10f7ebbf1c9833c74d09db68c0a0f5a149bde8d (patch)
treed25d97bafc0f762e537428f99607680aa5e434b3 /src/check_type.cpp
parent40ed7e48d0e4a1f000efbd03d19a4eebe9b8e2f6 (diff)
parent17bbb48d8a04aaf6cc53777fe4da6ba1b7fff61b (diff)
Merge remote-tracking branch 'upstream/master' into prototype-fmt
Diffstat (limited to 'src/check_type.cpp')
-rw-r--r--src/check_type.cpp42
1 files changed, 35 insertions, 7 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 39fea75db..e3aac161c 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2101,8 +2101,15 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type, ProcCall
}
break;
}
- case Type_Pointer: break;
- case Type_Proc: break; // NOTE(bill): Just a pointer
+ case Type_Pointer:
+ if (is_type_struct(bt->Pointer.elem)) {
+ // Force to a raw pointer
+ new_type = t_rawptr;
+ }
+ break;
+ case Type_Proc:
+ new_type = t_rawptr;
+ break; // NOTE(bill): Just a pointer
// Odin specific
case Type_Slice:
@@ -2194,6 +2201,10 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type, ProcCal
return new_type;
}
+ if (is_type_pointer(single_type)) {
+ // NOTE(bill): Force a cast to prevent a possible type cycle
+ return t_rawptr;
+ }
if (build_context.ODIN_OS == "windows") {
if (build_context.ODIN_ARCH == "amd64") {
@@ -2450,6 +2461,24 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
}
}
}
+ if (pt->tags & ProcTag_optional_second) {
+ if (optional_ok) {
+ error(proc_type_node, "A procedure type cannot have both an #optional_ok tag and #optional_second");
+ }
+ optional_ok = true;
+ if (result_count != 2) {
+ error(proc_type_node, "A procedure type with the #optional_second tag requires 2 return values, got %td", result_count);
+ } else {
+ bool ok = false;
+ if (proc_type_node->file && proc_type_node->file->pkg) {
+ ok = proc_type_node->file->pkg->scope == ctx->info->runtime_package->scope;
+ }
+
+ if (!ok) {
+ error(proc_type_node, "A procedure type with the #optional_second may only be allowed within 'package runtime'");
+ }
+ }
+ }
type->Proc.node = proc_type_node;
type->Proc.scope = c->scope;
@@ -2590,12 +2619,11 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
}
Type *make_optional_ok_type(Type *value, bool typed) {
- // LEAK TODO(bill): probably don't reallocate everything here and reuse the same one for the same type if possible
- gbAllocator a = heap_allocator();
+ gbAllocator a = permanent_allocator();
Type *t = alloc_type_tuple();
- array_init(&t->Tuple.variables, a, 0, 2);
- array_add (&t->Tuple.variables, alloc_entity_field(nullptr, blank_token, value, false, 0));
- array_add (&t->Tuple.variables, alloc_entity_field(nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1));
+ array_init(&t->Tuple.variables, a, 2);
+ t->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, value, false, 0);
+ t->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1);
return t;
}