Skip to content

Commit 662996e

Browse files
committed
Merge branch 'FireFox317-lazy-typeinfo-decls'
Closes #4435 Closes #3893 Closes #2584
2 parents e8a8492 + d056c77 commit 662996e

File tree

6 files changed

+75
-26
lines changed

6 files changed

+75
-26
lines changed

lib/std/meta.zig

+4-2
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {
437437
},
438438
.Pointer => |info| {
439439
return switch (info.size) {
440-
.One, .Many, .C, => a == b,
440+
.One, .Many, .C => a == b,
441441
.Slice => a.ptr == b.ptr and a.len == b.len,
442442
};
443443
},
@@ -559,7 +559,9 @@ pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int {
559559
/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.
560560
pub fn refAllDecls(comptime T: type) void {
561561
if (!builtin.is_test) return;
562-
_ = declarations(T);
562+
inline for (declarations(T)) |decl| {
563+
_ = decl;
564+
}
563565
}
564566

565567
/// Returns a slice of pointers to public declarations of a namespace.

src/all_types.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,22 @@ enum LazyValueId {
369369
LazyValueIdFnType,
370370
LazyValueIdErrUnionType,
371371
LazyValueIdArrayType,
372+
LazyValueIdTypeInfoDecls,
372373
};
373374

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

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

src/analyze.cpp

+6
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

+41-4
Original file line numberDiff line numberDiff line change
@@ -21221,6 +21221,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
2122121221
return ira->codegen->invalid_inst_gen;
2122221222
if (type_is_invalid(struct_val->type))
2122321223
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+
}
2122421231
if (initializing && struct_val->special == ConstValSpecialUndef) {
2122521232
struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
2122621233
struct_val->special = ConstValSpecialStatic;
@@ -23626,7 +23633,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
2362623633
}
2362723634

2362823635
static 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)
2363023637
{
2363123638
Error err;
2363223639
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
2363723644
ensure_field_index(type_info_declaration_type, "is_pub", 1);
2363823645
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+
2364023665
ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
2364123666
if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))
2364223667
return err;
@@ -24189,7 +24214,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2418924214
// decls: []TypeInfo.Declaration
2419024215
ensure_field_index(result->type, "decls", 3);
2419124216
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)))
2419324218
{
2419424219
return err;
2419524220
}
@@ -24361,7 +24386,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2436124386
// decls: []TypeInfo.Declaration
2436224387
ensure_field_index(result->type, "decls", 3);
2436324388
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)))
2436524390
{
2436624391
return err;
2436724392
}
@@ -24453,7 +24478,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2445324478
// decls: []TypeInfo.Declaration
2445424479
ensure_field_index(result->type, "decls", 2);
2445524480
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)))
2445724482
{
2445824483
return err;
2445924484
}
@@ -30391,6 +30416,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
3039130416
switch (val->data.x_lazy->id) {
3039230417
case LazyValueIdInvalid:
3039330418
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+
}
3039430431
case LazyValueIdAlignOf: {
3039530432
LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
3039630433
IrAnalyze *ira = lazy_align_of->ira;

test/compile_errors.zig

+3-20
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ 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",
3738
});
3839

3940
cases.add("function call assigned to incorrect type",
@@ -1346,24 +1347,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13461347
"tmp.zig:8:28: note: referenced here",
13471348
});
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-
13671350
cases.add("enum field value references enum",
13681351
\\pub const Foo = extern enum {
13691352
\\ A = Foo.B,

test/stage1/behavior/type_info.zig

+11
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,14 @@ test "sentinel of opaque pointer type" {
375375
const c_void_info = @typeInfo(*c_void);
376376
expect(c_void_info.Pointer.sentinel == null);
377377
}
378+
379+
test "@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+
}

0 commit comments

Comments
 (0)