authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 15:34:22-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 15:34:22-05:00
log662996e4a8826f62f76bdafdb7ccbb1d52210c96
treec0397d9b09c6dd66bd828c4162b8439bc03ec304
parente8a84927ab989d3c8fb6668dd242ada0a8f99585
parentd056c7732b87633ace03dd15668a88eac76b62a5
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'FireFox317-lazy-typeinfo-decls'

Closes #4435 Closes #3893 Closes #2584

6 files changed, 75 insertions(+), 26 deletions(-)

lib/std/meta.zig+4-2
...@@ -437,7 +437,7 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {...@@ -437,7 +437,7 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {
437 },437 },
438 .Pointer => |info| {438 .Pointer => |info| {
439 return switch (info.size) {439 return switch (info.size) {
440 .One, .Many, .C, => a == b,440 .One, .Many, .C => a == b,
441 .Slice => a.ptr == b.ptr and a.len == b.len,441 .Slice => a.ptr == b.ptr and a.len == b.len,
442 };442 };
443 },443 },
...@@ -559,7 +559,9 @@ pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int {...@@ -559,7 +559,9 @@ pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int {
559/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.559/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.
560pub fn refAllDecls(comptime T: type) void {560pub fn refAllDecls(comptime T: type) void {
561 if (!builtin.is_test) return;561 if (!builtin.is_test) return;
562 _ = declarations(T);562 inline for (declarations(T)) |decl| {
563 _ = decl;
564 }
563}565}
564566
565/// Returns a slice of pointers to public declarations of a namespace.567/// Returns a slice of pointers to public declarations of a namespace.
src/all_types.hpp+10
...@@ -369,12 +369,22 @@ enum LazyValueId {...@@ -369,12 +369,22 @@ enum LazyValueId {
369 LazyValueIdFnType,369 LazyValueIdFnType,
370 LazyValueIdErrUnionType,370 LazyValueIdErrUnionType,
371 LazyValueIdArrayType,371 LazyValueIdArrayType,
372 LazyValueIdTypeInfoDecls,
372};373};
373374
374struct LazyValue {375struct LazyValue {
375 LazyValueId id;376 LazyValueId id;
376};377};
377378
379struct LazyValueTypeInfoDecls {
380 LazyValue base;
381
382 IrAnalyze *ira;
383
384 ScopeDecls *decls_scope;
385 IrInst *source_instr;
386};
387
378struct LazyValueAlignOf {388struct LazyValueAlignOf {
379 LazyValue base;389 LazyValue base;
380390
src/analyze.cpp+6
...@@ -1150,6 +1150,7 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent...@@ -1150,6 +1150,7 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
1150 case LazyValueIdInvalid:1150 case LazyValueIdInvalid:
1151 case LazyValueIdAlignOf:1151 case LazyValueIdAlignOf:
1152 case LazyValueIdSizeOf:1152 case LazyValueIdSizeOf:
1153 case LazyValueIdTypeInfoDecls:
1153 zig_unreachable();1154 zig_unreachable();
1154 case LazyValueIdPtrType: {1155 case LazyValueIdPtrType: {
1155 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);1156 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
...@@ -1209,6 +1210,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o...@@ -1209,6 +1210,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o
1209 case LazyValueIdInvalid:1210 case LazyValueIdInvalid:
1210 case LazyValueIdAlignOf:1211 case LazyValueIdAlignOf:
1211 case LazyValueIdSizeOf:1212 case LazyValueIdSizeOf:
1213 case LazyValueIdTypeInfoDecls:
1212 zig_unreachable();1214 zig_unreachable();
1213 case LazyValueIdSliceType:1215 case LazyValueIdSliceType:
1214 case LazyValueIdPtrType:1216 case LazyValueIdPtrType:
...@@ -1230,6 +1232,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type...@@ -1230,6 +1232,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type
1230 case LazyValueIdInvalid:1232 case LazyValueIdInvalid:
1231 case LazyValueIdAlignOf:1233 case LazyValueIdAlignOf:
1232 case LazyValueIdSizeOf:1234 case LazyValueIdSizeOf:
1235 case LazyValueIdTypeInfoDecls:
1233 zig_unreachable();1236 zig_unreachable();
1234 case LazyValueIdSliceType: {1237 case LazyValueIdSliceType: {
1235 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);1238 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
...@@ -1303,6 +1306,7 @@ start_over:...@@ -1303,6 +1306,7 @@ start_over:
1303 case LazyValueIdInvalid:1306 case LazyValueIdInvalid:
1304 case LazyValueIdAlignOf:1307 case LazyValueIdAlignOf:
1305 case LazyValueIdSizeOf:1308 case LazyValueIdSizeOf:
1309 case LazyValueIdTypeInfoDecls:
1306 zig_unreachable();1310 zig_unreachable();
1307 case LazyValueIdSliceType: {1311 case LazyValueIdSliceType: {
1308 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);1312 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
...@@ -1370,6 +1374,7 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ...@@ -1370,6 +1374,7 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ
1370 case LazyValueIdInvalid:1374 case LazyValueIdInvalid:
1371 case LazyValueIdAlignOf:1375 case LazyValueIdAlignOf:
1372 case LazyValueIdSizeOf:1376 case LazyValueIdSizeOf:
1377 case LazyValueIdTypeInfoDecls:
1373 zig_unreachable();1378 zig_unreachable();
1374 case LazyValueIdSliceType:1379 case LazyValueIdSliceType:
1375 case LazyValueIdPtrType:1380 case LazyValueIdPtrType:
...@@ -1412,6 +1417,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV...@@ -1412,6 +1417,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
1412 case LazyValueIdInvalid:1417 case LazyValueIdInvalid:
1413 case LazyValueIdAlignOf:1418 case LazyValueIdAlignOf:
1414 case LazyValueIdSizeOf:1419 case LazyValueIdSizeOf:
1420 case LazyValueIdTypeInfoDecls:
1415 zig_unreachable();1421 zig_unreachable();
1416 case LazyValueIdSliceType: // it has the len field1422 case LazyValueIdSliceType: // it has the len field
1417 case LazyValueIdOptType: // it has the optional bit1423 case LazyValueIdOptType: // it has the optional bit
src/ir.cpp+41-4
...@@ -21221,6 +21221,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins...@@ -21221,6 +21221,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
21221 return ira->codegen->invalid_inst_gen;21221 return ira->codegen->invalid_inst_gen;
21222 if (type_is_invalid(struct_val->type))21222 if (type_is_invalid(struct_val->type))
21223 return ira->codegen->invalid_inst_gen;21223 return ira->codegen->invalid_inst_gen;
21224
21225 // This to allow lazy values to be resolved.
21226 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
21227 source_instr->source_node, struct_val, UndefOk)))
21228 {
21229 return ira->codegen->invalid_inst_gen;
21230 }
21224 if (initializing && struct_val->special == ConstValSpecialUndef) {21231 if (initializing && struct_val->special == ConstValSpecialUndef) {
21225 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);21232 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
21226 struct_val->special = ConstValSpecialStatic;21233 struct_val->special = ConstValSpecialStatic;
...@@ -23626,7 +23633,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig...@@ -23626,7 +23633,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
23626}23633}
2362723634
23628static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val,23635static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val,
23629 ScopeDecls *decls_scope)23636 ScopeDecls *decls_scope, bool resolve_types)
23630{23637{
23631 Error err;23638 Error err;
23632 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);23639 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
...@@ -23637,6 +23644,24 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -23637,6 +23644,24 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
23637 ensure_field_index(type_info_declaration_type, "is_pub", 1);23644 ensure_field_index(type_info_declaration_type, "is_pub", 1);
23638 ensure_field_index(type_info_declaration_type, "data", 2);23645 ensure_field_index(type_info_declaration_type, "data", 2);
2363923646
23647 if (!resolve_types) {
23648 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type,
23649 false, false, PtrLenUnknown, 0, 0, 0, false);
23650
23651 out_val->special = ConstValSpecialLazy;
23652 out_val->type = get_slice_type(ira->codegen, ptr_type);
23653
23654 LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>();
23655 lazy_type_info_decls->ira = ira; ira_ref(ira);
23656 out_val->data.x_lazy = &lazy_type_info_decls->base;
23657 lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls;
23658
23659 lazy_type_info_decls->source_instr = source_instr;
23660 lazy_type_info_decls->decls_scope = decls_scope;
23661
23662 return ErrorNone;
23663 }
23664
23640 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);23665 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
23641 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))23666 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))
23642 return err;23667 return err;
...@@ -24189,7 +24214,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -24189,7 +24214,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
24189 // decls: []TypeInfo.Declaration24214 // decls: []TypeInfo.Declaration
24190 ensure_field_index(result->type, "decls", 3);24215 ensure_field_index(result->type, "decls", 3);
24191 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],24216 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24192 type_entry->data.enumeration.decls_scope)))24217 type_entry->data.enumeration.decls_scope, false)))
24193 {24218 {
24194 return err;24219 return err;
24195 }24220 }
...@@ -24361,7 +24386,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -24361,7 +24386,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
24361 // decls: []TypeInfo.Declaration24386 // decls: []TypeInfo.Declaration
24362 ensure_field_index(result->type, "decls", 3);24387 ensure_field_index(result->type, "decls", 3);
24363 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],24388 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24364 type_entry->data.unionation.decls_scope)))24389 type_entry->data.unionation.decls_scope, false)))
24365 {24390 {
24366 return err;24391 return err;
24367 }24392 }
...@@ -24453,7 +24478,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -24453,7 +24478,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
24453 // decls: []TypeInfo.Declaration24478 // decls: []TypeInfo.Declaration
24454 ensure_field_index(result->type, "decls", 2);24479 ensure_field_index(result->type, "decls", 2);
24455 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],24480 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],
24456 type_entry->data.structure.decls_scope)))24481 type_entry->data.structure.decls_scope, false)))
24457 {24482 {
24458 return err;24483 return err;
24459 }24484 }
...@@ -30391,6 +30416,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {...@@ -30391,6 +30416,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
30391 switch (val->data.x_lazy->id) {30416 switch (val->data.x_lazy->id) {
30392 case LazyValueIdInvalid:30417 case LazyValueIdInvalid:
30393 zig_unreachable();30418 zig_unreachable();
30419 case LazyValueIdTypeInfoDecls: {
30420 LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy);
30421 IrAnalyze *ira = type_info_decls->ira;
30422
30423 if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true)))
30424 {
30425 return err;
30426 };
30427
30428 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
30429 return ErrorNone;
30430 }
30394 case LazyValueIdAlignOf: {30431 case LazyValueIdAlignOf: {
30395 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);30432 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
30396 IrAnalyze *ira = lazy_align_of->ira;30433 IrAnalyze *ira = lazy_align_of->ira;
test/compile_errors.zig+3-20
...@@ -30,10 +30,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -30,10 +30,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",30 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
31 });31 });
3232
33 cases.addTest("dependency loop in top-level decl with @TypeInfo",33 cases.addTest("dependency loop in top-level decl with @TypeInfo when accessing the decls",
34 \\export const foo = @typeInfo(@This());34 \\export const foo = @typeInfo(@This()).Struct.decls;
35 , &[_][]const u8{35 , &[_][]const u8{
36 "tmp.zig:1:20: error: dependency loop detected",36 "tmp.zig:1:20: error: dependency loop detected",
37 "tmp.zig:1:45: note: referenced here",
37 });38 });
3839
39 cases.add("function call assigned to incorrect type",40 cases.add("function call assigned to incorrect type",
...@@ -1346,24 +1347,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1346,24 +1347,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1346 "tmp.zig:8:28: note: referenced here",1347 "tmp.zig:8:28: note: referenced here",
1347 });1348 });
13481349
1349 cases.add("@typeInfo causing depend on itself compile error",
1350 \\const start = struct {
1351 \\ fn crash() bug() {
1352 \\ return bug;
1353 \\ }
1354 \\};
1355 \\fn bug() void {
1356 \\ _ = @typeInfo(start).Struct;
1357 \\}
1358 \\export fn entry() void {
1359 \\ var boom = start.crash();
1360 \\}
1361 , &[_][]const u8{
1362 "tmp.zig:7:9: error: dependency loop detected",
1363 "tmp.zig:2:19: note: referenced here",
1364 "tmp.zig:10:21: note: referenced here",
1365 });
1366
1367 cases.add("enum field value references enum",1350 cases.add("enum field value references enum",
1368 \\pub const Foo = extern enum {1351 \\pub const Foo = extern enum {
1369 \\ A = Foo.B,1352 \\ A = Foo.B,
test/stage1/behavior/type_info.zig+11
...@@ -375,3 +375,14 @@ test "sentinel of opaque pointer type" {...@@ -375,3 +375,14 @@ test "sentinel of opaque pointer type" {
375 const c_void_info = @typeInfo(*c_void);375 const c_void_info = @typeInfo(*c_void);
376 expect(c_void_info.Pointer.sentinel == null);376 expect(c_void_info.Pointer.sentinel == null);
377}377}
378
379test "@typeInfo does not force declarations into existence" {
380 const S = struct {
381 x: i32,
382
383 fn doNotReferenceMe() void {
384 @compileError("test failed");
385 }
386 };
387 comptime expect(@typeInfo(S).Struct.fields.len == 1);
388}