aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-04-06 18:07:38 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-04-06 18:07:38 -0400
commit273cebdf4dde46f00eb177b9aa05d8dd1c0606a7 (patch)
treed3c7f4f4bb6ceff2f1fa4e629b8a42b36cf42fcc /src/ir.cpp
parent47f58d6d029cabb46064557f8e047970a2fa52fc (diff)
downloadzig-273cebdf4dde46f00eb177b9aa05d8dd1c0606a7.tar.gz
zig-273cebdf4dde46f00eb177b9aa05d8dd1c0606a7.zip
peer resolve types [N]T, [M]T as []const T
closes #125
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index a1ccce7f2c..79f4a27914 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5857,6 +5857,10 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
return ImplicitCastMatchResultNo;
}
+static bool is_slice(TypeTableEntry *type) {
+ return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
+}
+
static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) {
assert(instruction_count >= 1);
IrInstruction *prev_inst = instructions[0];
@@ -5865,6 +5869,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
}
bool any_are_pure_error = (prev_inst->value.type->id == TypeTableEntryIdPureError);
bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNullLit);
+ bool convert_to_const_slice = false;
for (size_t i = 1; i < instruction_count; i += 1) {
IrInstruction *cur_inst = instructions[i];
TypeTableEntry *cur_type = cur_inst->value.type;
@@ -5932,6 +5937,34 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
} else {
return ira->codegen->builtin_types.entry_invalid;
}
+ } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
+ cur_type->data.array.len != prev_type->data.array.len &&
+ types_match_const_cast_only(cur_type->data.array.child_type, prev_type->data.array.child_type))
+ {
+ convert_to_const_slice = true;
+ prev_inst = cur_inst;
+ continue;
+ } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
+ cur_type->data.array.len != prev_type->data.array.len &&
+ types_match_const_cast_only(prev_type->data.array.child_type, cur_type->data.array.child_type))
+ {
+ convert_to_const_slice = true;
+ continue;
+ } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
+ prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const &&
+ types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
+ cur_type->data.array.child_type))
+ {
+ convert_to_const_slice = false;
+ continue;
+ } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
+ cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const &&
+ types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
+ prev_type->data.array.child_type))
+ {
+ prev_inst = cur_inst;
+ convert_to_const_slice = false;
+ continue;
} else {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("incompatible types: '%s' and '%s'",
@@ -5944,7 +5977,10 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
return ira->codegen->builtin_types.entry_invalid;
}
}
- if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
+ if (convert_to_const_slice) {
+ assert(prev_inst->value.type->id == TypeTableEntryIdArray);
+ return get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
+ } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)
{
@@ -6038,10 +6074,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}
-static bool is_slice(TypeTableEntry *type) {
- return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice;
-}
-
static bool is_container(TypeTableEntry *type) {
return type->id == TypeTableEntryIdStruct ||
type->id == TypeTableEntryIdEnum ||