diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-04-06 18:07:38 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-04-06 18:07:38 -0400 |
| commit | 273cebdf4dde46f00eb177b9aa05d8dd1c0606a7 (patch) | |
| tree | d3c7f4f4bb6ceff2f1fa4e629b8a42b36cf42fcc /src/ir.cpp | |
| parent | 47f58d6d029cabb46064557f8e047970a2fa52fc (diff) | |
| download | zig-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.cpp | 42 |
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 || |
