aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-07-06 16:20:46 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-07-06 16:20:46 -0400
commit1cf7511dc9d449473748675a5e734e81ea7c85c2 (patch)
treee3703a3d1c89d8be15a721ba5b9e037a0da5db44 /src
parent6d793c0ea3679fe420199676e92e435c81617258 (diff)
downloadzig-1cf7511dc9d449473748675a5e734e81ea7c85c2.tar.gz
zig-1cf7511dc9d449473748675a5e734e81ea7c85c2.zip
add compile error notes for where struct definitions are
closes #1202
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp37
-rw-r--r--src/analyze.hpp1
-rw-r--r--src/ir.cpp47
3 files changed, 74 insertions, 11 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ca582dfc4c..643a85634e 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -212,6 +212,43 @@ static uint8_t bits_needed_for_unsigned(uint64_t x) {
return (upper >= x) ? base : (base + 1);
}
+AstNode *type_decl_node(TypeTableEntry *type_entry) {
+ switch (type_entry->id) {
+ case TypeTableEntryIdInvalid:
+ zig_unreachable();
+ case TypeTableEntryIdStruct:
+ return type_entry->data.structure.decl_node;
+ case TypeTableEntryIdEnum:
+ return type_entry->data.enumeration.decl_node;
+ case TypeTableEntryIdUnion:
+ return type_entry->data.unionation.decl_node;
+ case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdMetaType:
+ case TypeTableEntryIdVoid:
+ case TypeTableEntryIdBool:
+ case TypeTableEntryIdUnreachable:
+ case TypeTableEntryIdInt:
+ case TypeTableEntryIdFloat:
+ case TypeTableEntryIdPointer:
+ case TypeTableEntryIdArray:
+ case TypeTableEntryIdComptimeFloat:
+ case TypeTableEntryIdComptimeInt:
+ case TypeTableEntryIdUndefined:
+ case TypeTableEntryIdNull:
+ case TypeTableEntryIdOptional:
+ case TypeTableEntryIdErrorUnion:
+ case TypeTableEntryIdErrorSet:
+ case TypeTableEntryIdFn:
+ case TypeTableEntryIdNamespace:
+ case TypeTableEntryIdBlock:
+ case TypeTableEntryIdBoundFn:
+ case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
+ return nullptr;
+ }
+ zig_unreachable();
+}
+
bool type_is_complete(TypeTableEntry *type_entry) {
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
diff --git a/src/analyze.hpp b/src/analyze.hpp
index c2730197e2..5168509fe0 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -202,5 +202,6 @@ uint32_t get_coro_frame_align_bytes(CodeGen *g);
bool fn_type_can_fail(FnTypeId *fn_type_id);
bool type_can_fail(TypeTableEntry *type_entry);
bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type);
+AstNode *type_decl_node(TypeTableEntry *type_entry);
#endif
diff --git a/src/ir.cpp b/src/ir.cpp
index 204ebb332a..3ad7c77645 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -82,6 +82,7 @@ struct ConstCastSliceMismatch;
struct ConstCastErrUnionErrSetMismatch;
struct ConstCastErrUnionPayloadMismatch;
struct ConstCastErrSetMismatch;
+struct ConstCastTypeMismatch;
struct ConstCastOnly {
ConstCastResultId id;
@@ -92,6 +93,7 @@ struct ConstCastOnly {
ConstCastOptionalMismatch *optional;
ConstCastErrUnionPayloadMismatch *error_union_payload;
ConstCastErrUnionErrSetMismatch *error_union_error_set;
+ ConstCastTypeMismatch *type_mismatch;
ConstCastOnly *return_type;
ConstCastOnly *async_allocator_type;
ConstCastOnly *null_wrap_ptr_child;
@@ -100,6 +102,11 @@ struct ConstCastOnly {
} data;
};
+struct ConstCastTypeMismatch {
+ TypeTableEntry *wanted_type;
+ TypeTableEntry *actual_type;
+};
+
struct ConstCastOptionalMismatch {
ConstCastOnly child;
TypeTableEntry *wanted_child;
@@ -8128,15 +8135,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
}
// pointer const
- if (wanted_type->id == TypeTableEntryIdPointer &&
- actual_type->id == TypeTableEntryIdPointer &&
- (actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
- (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
- (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
- actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&
- actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&
- actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment)
- {
+ if (wanted_type->id == TypeTableEntryIdPointer && actual_type->id == TypeTableEntryIdPointer) {
ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
if (child.id != ConstCastResultIdOk) {
@@ -8145,8 +8144,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
result.data.pointer_mismatch->child = child;
result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type;
result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type;
+ return result;
+ }
+ if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
+ (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
+ (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
+ actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&
+ actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&
+ actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment)
+ {
+ return result;
}
- return result;
}
// slice const
@@ -8341,6 +8349,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
}
result.id = ConstCastResultIdType;
+ result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1);
+ result.data.type_mismatch->wanted_type = wanted_type;
+ result.data.type_mismatch->actual_type = actual_type;
return result;
}
@@ -10154,6 +10165,21 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg);
break;
}
+ case ConstCastResultIdType: {
+ AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type);
+ AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type);
+ if (wanted_decl_node != nullptr) {
+ add_error_note(ira->codegen, parent_msg, wanted_decl_node,
+ buf_sprintf("%s declared here",
+ buf_ptr(&cast_result->data.type_mismatch->wanted_type->name)));
+ }
+ if (actual_decl_node != nullptr) {
+ add_error_note(ira->codegen, parent_msg, actual_decl_node,
+ buf_sprintf("%s declared here",
+ buf_ptr(&cast_result->data.type_mismatch->actual_type->name)));
+ }
+ break;
+ }
case ConstCastResultIdFnAlign: // TODO
case ConstCastResultIdFnCC: // TODO
case ConstCastResultIdFnVarArgs: // TODO
@@ -10163,7 +10189,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
case ConstCastResultIdFnGenericArgCount: // TODO
case ConstCastResultIdFnArg: // TODO
case ConstCastResultIdFnArgNoAlias: // TODO
- case ConstCastResultIdType: // TODO
case ConstCastResultIdUnresolvedInferredErrSet: // TODO
case ConstCastResultIdAsyncAllocatorType: // TODO
case ConstCastResultIdNullWrapPtr: // TODO