authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 16:20:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-06 16:20:46-04:00
log1cf7511dc9d449473748675a5e734e81ea7c85c2
treee3703a3d1c89d8be15a721ba5b9e037a0da5db44
parent6d793c0ea3679fe420199676e92e435c81617258

add compile error notes for where struct definitions are

closes #1202

4 files changed, 110 insertions(+), 17 deletions(-)

src/analyze.cpp+37
......@@ -212,6 +212,43 @@ static uint8_t bits_needed_for_unsigned(uint64_t x) {
212212 return (upper >= x) ? base : (base + 1);
213213}
214214
215AstNode *type_decl_node(TypeTableEntry *type_entry) {
216 switch (type_entry->id) {
217 case TypeTableEntryIdInvalid:
218 zig_unreachable();
219 case TypeTableEntryIdStruct:
220 return type_entry->data.structure.decl_node;
221 case TypeTableEntryIdEnum:
222 return type_entry->data.enumeration.decl_node;
223 case TypeTableEntryIdUnion:
224 return type_entry->data.unionation.decl_node;
225 case TypeTableEntryIdOpaque:
226 case TypeTableEntryIdMetaType:
227 case TypeTableEntryIdVoid:
228 case TypeTableEntryIdBool:
229 case TypeTableEntryIdUnreachable:
230 case TypeTableEntryIdInt:
231 case TypeTableEntryIdFloat:
232 case TypeTableEntryIdPointer:
233 case TypeTableEntryIdArray:
234 case TypeTableEntryIdComptimeFloat:
235 case TypeTableEntryIdComptimeInt:
236 case TypeTableEntryIdUndefined:
237 case TypeTableEntryIdNull:
238 case TypeTableEntryIdOptional:
239 case TypeTableEntryIdErrorUnion:
240 case TypeTableEntryIdErrorSet:
241 case TypeTableEntryIdFn:
242 case TypeTableEntryIdNamespace:
243 case TypeTableEntryIdBlock:
244 case TypeTableEntryIdBoundFn:
245 case TypeTableEntryIdArgTuple:
246 case TypeTableEntryIdPromise:
247 return nullptr;
248 }
249 zig_unreachable();
250}
251
215252bool type_is_complete(TypeTableEntry *type_entry) {
216253 switch (type_entry->id) {
217254 case TypeTableEntryIdInvalid:
src/analyze.hpp+1
......@@ -202,5 +202,6 @@ uint32_t get_coro_frame_align_bytes(CodeGen *g);
202202bool fn_type_can_fail(FnTypeId *fn_type_id);
203203bool type_can_fail(TypeTableEntry *type_entry);
204204bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type);
205AstNode *type_decl_node(TypeTableEntry *type_entry);
205206
206207#endif
src/ir.cpp+36-11
......@@ -82,6 +82,7 @@ struct ConstCastSliceMismatch;
8282struct ConstCastErrUnionErrSetMismatch;
8383struct ConstCastErrUnionPayloadMismatch;
8484struct ConstCastErrSetMismatch;
85struct ConstCastTypeMismatch;
8586
8687struct ConstCastOnly {
8788 ConstCastResultId id;
......@@ -92,6 +93,7 @@ struct ConstCastOnly {
9293 ConstCastOptionalMismatch *optional;
9394 ConstCastErrUnionPayloadMismatch *error_union_payload;
9495 ConstCastErrUnionErrSetMismatch *error_union_error_set;
96 ConstCastTypeMismatch *type_mismatch;
9597 ConstCastOnly *return_type;
9698 ConstCastOnly *async_allocator_type;
9799 ConstCastOnly *null_wrap_ptr_child;
......@@ -100,6 +102,11 @@ struct ConstCastOnly {
100102 } data;
101103};
102104
105struct ConstCastTypeMismatch {
106 TypeTableEntry *wanted_type;
107 TypeTableEntry *actual_type;
108};
109
103110struct ConstCastOptionalMismatch {
104111 ConstCastOnly child;
105112 TypeTableEntry *wanted_child;
......@@ -8128,15 +8135,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
81288135 }
81298136
81308137 // pointer const
8131 if (wanted_type->id == TypeTableEntryIdPointer &&
8132 actual_type->id == TypeTableEntryIdPointer &&
8133 (actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
8134 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
8135 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
8136 actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&
8137 actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&
8138 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment)
8139 {
8138 if (wanted_type->id == TypeTableEntryIdPointer && actual_type->id == TypeTableEntryIdPointer) {
81408139 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
81418140 actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
81428141 if (child.id != ConstCastResultIdOk) {
......@@ -8145,8 +8144,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
81458144 result.data.pointer_mismatch->child = child;
81468145 result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type;
81478146 result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type;
8147 return result;
8148 }
8149 if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
8150 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
8151 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
8152 actual_type->data.pointer.bit_offset == wanted_type->data.pointer.bit_offset &&
8153 actual_type->data.pointer.unaligned_bit_count == wanted_type->data.pointer.unaligned_bit_count &&
8154 actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment)
8155 {
8156 return result;
81488157 }
8149 return result;
81508158 }
81518159
81528160 // slice const
......@@ -8341,6 +8349,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
83418349 }
83428350
83438351 result.id = ConstCastResultIdType;
8352 result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1);
8353 result.data.type_mismatch->wanted_type = wanted_type;
8354 result.data.type_mismatch->actual_type = actual_type;
83448355 return result;
83458356}
83468357
......@@ -10154,6 +10165,21 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1015410165 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg);
1015510166 break;
1015610167 }
10168 case ConstCastResultIdType: {
10169 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type);
10170 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type);
10171 if (wanted_decl_node != nullptr) {
10172 add_error_note(ira->codegen, parent_msg, wanted_decl_node,
10173 buf_sprintf("%s declared here",
10174 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name)));
10175 }
10176 if (actual_decl_node != nullptr) {
10177 add_error_note(ira->codegen, parent_msg, actual_decl_node,
10178 buf_sprintf("%s declared here",
10179 buf_ptr(&cast_result->data.type_mismatch->actual_type->name)));
10180 }
10181 break;
10182 }
1015710183 case ConstCastResultIdFnAlign: // TODO
1015810184 case ConstCastResultIdFnCC: // TODO
1015910185 case ConstCastResultIdFnVarArgs: // TODO
......@@ -10163,7 +10189,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
1016310189 case ConstCastResultIdFnGenericArgCount: // TODO
1016410190 case ConstCastResultIdFnArg: // TODO
1016510191 case ConstCastResultIdFnArgNoAlias: // TODO
10166 case ConstCastResultIdType: // TODO
1016710192 case ConstCastResultIdUnresolvedInferredErrSet: // TODO
1016810193 case ConstCastResultIdAsyncAllocatorType: // TODO
1016910194 case ConstCastResultIdNullWrapPtr: // TODO
test/compile_errors.zig+36-6
......@@ -1,6 +1,40 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.addCase(x: {
5 const tc = cases.create(
6 "wrong same named struct",
7 \\const a = @import("a.zig");
8 \\const b = @import("b.zig");
9 \\
10 \\export fn entry() void {
11 \\ var a1: a.Foo = undefined;
12 \\ bar(&a1);
13 \\}
14 \\
15 \\fn bar(x: *b.Foo) void {}
16 ,
17 ".tmp_source.zig:6:10: error: expected type '*Foo', found '*Foo'",
18 ".tmp_source.zig:6:10: note: pointer type child 'Foo' cannot cast into pointer type child 'Foo'",
19 "a.zig:1:17: note: Foo declared here",
20 "b.zig:1:17: note: Foo declared here",
21 );
22
23 tc.addSourceFile("a.zig",
24 \\pub const Foo = struct {
25 \\ x: i32,
26 \\};
27 );
28
29 tc.addSourceFile("b.zig",
30 \\pub const Foo = struct {
31 \\ z: f64,
32 \\};
33 );
34
35 break :x tc;
36 });
37
438 cases.add(
539 "enum field value references enum",
640 \\pub const Foo = extern enum {
......@@ -358,9 +392,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
358392 ".tmp_source.zig:3:14: note: other value is here",
359393 );
360394
361
362 cases.add(
363 "invalid cast from integral type to enum",
395 cases.add("invalid cast from integral type to enum",
364396 \\const E = enum(usize) { One, Two };
365397 \\
366398 \\export fn entry() void {
......@@ -372,9 +404,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
372404 \\ E.One => {},
373405 \\ }
374406 \\}
375 ,
376 ".tmp_source.zig:9:10: error: expected type 'usize', found 'E'"
377 );
407 , ".tmp_source.zig:9:10: error: expected type 'usize', found 'E'");
378408
379409 cases.add(
380410 "range operator in switch used on error set",