Skip to content

Commit f23a976

Browse files
committed
Makes the declaration slice resolve lazely when using @typeInfo
This way all the declarations in a container won't be resolved untill the user actually uses the decls slice in the builtin TypeInfo union.
1 parent ab4ea5d commit f23a976

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

src/all_types.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,22 @@ enum LazyValueId {
370370
LazyValueIdFnType,
371371
LazyValueIdErrUnionType,
372372
LazyValueIdArrayType,
373+
LazyValueIdTypeInfoDecls,
373374
};
374375

375376
struct LazyValue {
376377
LazyValueId id;
377378
};
378379

380+
struct LazyValueTypeInfoDecls {
381+
LazyValue base;
382+
383+
IrAnalyze *ira;
384+
385+
ScopeDecls *decls_scope;
386+
IrInst *source_instr;
387+
};
388+
379389
struct LazyValueAlignOf {
380390
LazyValue base;
381391

src/analyze.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,7 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
11501150
case LazyValueIdInvalid:
11511151
case LazyValueIdAlignOf:
11521152
case LazyValueIdSizeOf:
1153+
case LazyValueIdTypeInfoDecls:
11531154
zig_unreachable();
11541155
case LazyValueIdPtrType: {
11551156
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
12091210
case LazyValueIdInvalid:
12101211
case LazyValueIdAlignOf:
12111212
case LazyValueIdSizeOf:
1213+
case LazyValueIdTypeInfoDecls:
12121214
zig_unreachable();
12131215
case LazyValueIdSliceType:
12141216
case LazyValueIdPtrType:
@@ -1230,6 +1232,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type
12301232
case LazyValueIdInvalid:
12311233
case LazyValueIdAlignOf:
12321234
case LazyValueIdSizeOf:
1235+
case LazyValueIdTypeInfoDecls:
12331236
zig_unreachable();
12341237
case LazyValueIdSliceType: {
12351238
LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
@@ -1303,6 +1306,7 @@ Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type
13031306
case LazyValueIdInvalid:
13041307
case LazyValueIdAlignOf:
13051308
case LazyValueIdSizeOf:
1309+
case LazyValueIdTypeInfoDecls:
13061310
zig_unreachable();
13071311
case LazyValueIdSliceType: {
13081312
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
13701374
case LazyValueIdInvalid:
13711375
case LazyValueIdAlignOf:
13721376
case LazyValueIdSizeOf:
1377+
case LazyValueIdTypeInfoDecls:
13731378
zig_unreachable();
13741379
case LazyValueIdSliceType:
13751380
case LazyValueIdPtrType:
@@ -1412,6 +1417,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
14121417
case LazyValueIdInvalid:
14131418
case LazyValueIdAlignOf:
14141419
case LazyValueIdSizeOf:
1420+
case LazyValueIdTypeInfoDecls:
14151421
zig_unreachable();
14161422
case LazyValueIdSliceType: // it has the len field
14171423
case LazyValueIdOptType: // it has the optional bit

src/ir.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21192,6 +21192,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
2119221192
return ira->codegen->invalid_inst_gen;
2119321193
if (type_is_invalid(struct_val->type))
2119421194
return ira->codegen->invalid_inst_gen;
21195+
21196+
// This to allow lazy values to be resolved.
21197+
if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
21198+
source_instr->source_node, struct_val, UndefOk)))
21199+
{
21200+
return ira->codegen->invalid_inst_gen;
21201+
}
2119521202
if (initializing && struct_val->special == ConstValSpecialUndef) {
2119621203
struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
2119721204
struct_val->special = ConstValSpecialStatic;
@@ -23597,7 +23604,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
2359723604
}
2359823605

2359923606
static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val,
23600-
ScopeDecls *decls_scope)
23607+
ScopeDecls *decls_scope, bool resolve_types)
2360123608
{
2360223609
Error err;
2360323610
ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
@@ -23608,6 +23615,24 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
2360823615
ensure_field_index(type_info_declaration_type, "is_pub", 1);
2360923616
ensure_field_index(type_info_declaration_type, "data", 2);
2361023617

23618+
if (!resolve_types) {
23619+
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type,
23620+
false, false, PtrLenUnknown, 0, 0, 0, false);
23621+
23622+
out_val->special = ConstValSpecialLazy;
23623+
out_val->type = get_slice_type(ira->codegen, ptr_type);
23624+
23625+
LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>();
23626+
lazy_type_info_decls->ira = ira; ira_ref(ira);
23627+
out_val->data.x_lazy = &lazy_type_info_decls->base;
23628+
lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls;
23629+
23630+
lazy_type_info_decls->source_instr = source_instr;
23631+
lazy_type_info_decls->decls_scope = decls_scope;
23632+
23633+
return ErrorNone;
23634+
}
23635+
2361123636
ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
2361223637
if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))
2361323638
return err;
@@ -24160,7 +24185,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2416024185
// decls: []TypeInfo.Declaration
2416124186
ensure_field_index(result->type, "decls", 3);
2416224187
if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24163-
type_entry->data.enumeration.decls_scope)))
24188+
type_entry->data.enumeration.decls_scope, false)))
2416424189
{
2416524190
return err;
2416624191
}
@@ -24332,7 +24357,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2433224357
// decls: []TypeInfo.Declaration
2433324358
ensure_field_index(result->type, "decls", 3);
2433424359
if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24335-
type_entry->data.unionation.decls_scope)))
24360+
type_entry->data.unionation.decls_scope, false)))
2433624361
{
2433724362
return err;
2433824363
}
@@ -24424,7 +24449,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2442424449
// decls: []TypeInfo.Declaration
2442524450
ensure_field_index(result->type, "decls", 2);
2442624451
if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],
24427-
type_entry->data.structure.decls_scope)))
24452+
type_entry->data.structure.decls_scope, false)))
2442824453
{
2442924454
return err;
2443024455
}
@@ -30361,6 +30386,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
3036130386
switch (val->data.x_lazy->id) {
3036230387
case LazyValueIdInvalid:
3036330388
zig_unreachable();
30389+
case LazyValueIdTypeInfoDecls: {
30390+
LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy);
30391+
IrAnalyze *ira = type_info_decls->ira;
30392+
30393+
if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true)))
30394+
{
30395+
return err;
30396+
};
30397+
30398+
// We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
30399+
return ErrorNone;
30400+
}
3036430401
case LazyValueIdAlignOf: {
3036530402
LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
3036630403
IrAnalyze *ira = lazy_align_of->ira;

test/compile_errors.zig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3030
"tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
3131
});
3232

33-
cases.addTest("dependency loop in top-level decl with @TypeInfo",
34-
\\export const foo = @typeInfo(@This());
33+
cases.addTest("dependency loop in top-level decl with @TypeInfo when accessing the decls",
34+
\\export const foo = @typeInfo(@This()).Struct.decls;
3535
, &[_][]const u8{
3636
"tmp.zig:1:20: error: dependency loop detected",
37+
"tmp.zig:1:45: note: referenced here",
38+
3739
});
3840

3941
cases.add("function call assigned to incorrect type",

0 commit comments

Comments
 (0)