Skip to content

Commit 582fdc2

Browse files
committed
fix dependency loops, pub, tests, use decls, root source
* fix dependency loop detection - closes #679 - closes #1500 * fix `pub` * fix tests * fix use decls * main package file gets a special "" namespace path
1 parent faf7603 commit 582fdc2

18 files changed

+825
-731
lines changed

src-self-hosted/compilation.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub const ZigCompiler = struct {
4747

4848
var lazy_init_targets = std.lazyInit(void);
4949

50-
fn init(loop: *event.Loop) !ZigCompiler {
50+
pub fn init(loop: *event.Loop) !ZigCompiler {
5151
lazy_init_targets.get() orelse {
5252
Target.initializeAll();
5353
lazy_init_targets.resolve();

src/all_types.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,6 @@ struct Tld {
369369

370370
ZigType *import;
371371
Scope *parent_scope;
372-
// set this flag temporarily to detect infinite loops
373-
bool dep_loop_flag;
374372
TldResolution resolution;
375373
};
376374

@@ -380,6 +378,7 @@ struct TldVar {
380378
ZigVar *var;
381379
Buf *extern_lib_name;
382380
Buf *section_name;
381+
bool analyzing_type; // flag to detect dependency loops
383382
};
384383

385384
struct TldFn {

src/analyze.cpp

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,9 @@ static Error resolve_enum_type(CodeGen *g, ZigType *enum_type) {
19001900
if (!enum_type->data.enumeration.reported_infinite_err) {
19011901
enum_type->data.enumeration.is_invalid = true;
19021902
enum_type->data.enumeration.reported_infinite_err = true;
1903-
add_node_error(g, decl_node, buf_sprintf("enum '%s' contains itself", buf_ptr(&enum_type->name)));
1903+
ErrorMsg *msg = add_node_error(g, decl_node,
1904+
buf_sprintf("enum '%s' contains itself", buf_ptr(&enum_type->name)));
1905+
emit_error_notes_for_ref_stack(g, msg);
19041906
}
19051907
return ErrorSemanticAnalyzeFail;
19061908
}
@@ -2071,8 +2073,9 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
20712073
if (struct_type->data.structure.resolve_loop_flag) {
20722074
if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
20732075
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2074-
add_node_error(g, decl_node,
2076+
ErrorMsg *msg = add_node_error(g, decl_node,
20752077
buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name)));
2078+
emit_error_notes_for_ref_stack(g, msg);
20762079
}
20772080
return ErrorSemanticAnalyzeFail;
20782081
}
@@ -2296,7 +2299,9 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
22962299
if (!union_type->data.unionation.reported_infinite_err) {
22972300
union_type->data.unionation.reported_infinite_err = true;
22982301
union_type->data.unionation.is_invalid = true;
2299-
add_node_error(g, decl_node, buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name)));
2302+
ErrorMsg *msg = add_node_error(g, decl_node,
2303+
buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name)));
2304+
emit_error_notes_for_ref_stack(g, msg);
23002305
}
23012306
return ErrorSemanticAnalyzeFail;
23022307
}
@@ -2527,8 +2532,9 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
25272532
return ErrorNone;
25282533

25292534
if (enum_type->data.enumeration.zero_bits_loop_flag) {
2530-
add_node_error(g, enum_type->data.enumeration.decl_node,
2535+
ErrorMsg *msg = add_node_error(g, enum_type->data.enumeration.decl_node,
25312536
buf_sprintf("'%s' depends on itself", buf_ptr(&enum_type->name)));
2537+
emit_error_notes_for_ref_stack(g, msg);
25322538
enum_type->data.enumeration.is_invalid = true;
25332539
return ErrorSemanticAnalyzeFail;
25342540
}
@@ -2800,8 +2806,9 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
28002806
if (struct_type->data.structure.resolve_loop_flag) {
28012807
if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
28022808
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2803-
add_node_error(g, decl_node,
2809+
ErrorMsg *msg = add_node_error(g, decl_node,
28042810
buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name)));
2811+
emit_error_notes_for_ref_stack(g, msg);
28052812
}
28062813
return ErrorSemanticAnalyzeFail;
28072814
}
@@ -3239,7 +3246,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld) {
32393246
}
32403247
ScopeDecls *decls_scope = reinterpret_cast<ScopeDecls *>(scope);
32413248
buf_append_buf(buf, &decls_scope->container_type->name);
3242-
buf_append_char(buf, NAMESPACE_SEP_CHAR);
3249+
if (buf_len(buf) != 0) buf_append_char(buf, NAMESPACE_SEP_CHAR);
32433250
buf_append_buf(buf, tld->name);
32443251
}
32453252

@@ -3775,8 +3782,16 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
37753782

37763783
ZigType *explicit_type = nullptr;
37773784
if (var_decl->type) {
3778-
ZigType *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type);
3779-
explicit_type = validate_var_type(g, var_decl->type, proposed_type);
3785+
if (tld_var->analyzing_type) {
3786+
ErrorMsg *msg = add_node_error(g, var_decl->type,
3787+
buf_sprintf("type of '%s' depends on itself", buf_ptr(tld_var->base.name)));
3788+
emit_error_notes_for_ref_stack(g, msg);
3789+
explicit_type = g->builtin_types.entry_invalid;
3790+
} else {
3791+
tld_var->analyzing_type = true;
3792+
ZigType *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type);
3793+
explicit_type = validate_var_type(g, var_decl->type, proposed_type);
3794+
}
37803795
}
37813796

37823797
assert(!is_export || !is_extern);
@@ -3863,7 +3878,8 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
38633878
if (tld->resolution != TldResolutionUnresolved)
38643879
return;
38653880

3866-
tld->dep_loop_flag = true;
3881+
assert(tld->resolution != TldResolutionResolving);
3882+
tld->resolution = TldResolutionResolving;
38673883
g->tld_ref_source_node_stack.append(source_node);
38683884

38693885
switch (tld->id) {
@@ -3894,27 +3910,31 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
38943910
}
38953911

38963912
tld->resolution = TldResolutionOk;
3897-
tld->dep_loop_flag = false;
38983913
g->tld_ref_source_node_stack.pop();
38993914
}
39003915

3916+
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
3917+
// resolve all the use decls
3918+
for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
3919+
AstNode *use_decl_node = decls_scope->use_decls.at(i);
3920+
if (use_decl_node->data.use.resolution == TldResolutionUnresolved) {
3921+
preview_use_decl(g, use_decl_node);
3922+
resolve_use_decl(g, use_decl_node);
3923+
}
3924+
}
3925+
3926+
auto entry = decls_scope->decl_table.maybe_get(name);
3927+
return (entry == nullptr) ? nullptr : entry->value;
3928+
}
3929+
39013930
Tld *find_decl(CodeGen *g, Scope *scope, Buf *name) {
39023931
while (scope) {
39033932
if (scope->id == ScopeIdDecls) {
39043933
ScopeDecls *decls_scope = (ScopeDecls *)scope;
39053934

3906-
// resolve all the use decls
3907-
for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
3908-
AstNode *use_decl_node = decls_scope->use_decls.at(i);
3909-
if (use_decl_node->data.use.resolution == TldResolutionUnresolved) {
3910-
preview_use_decl(g, use_decl_node);
3911-
resolve_use_decl(g, use_decl_node);
3912-
}
3913-
}
3914-
3915-
auto entry = decls_scope->decl_table.maybe_get(name);
3916-
if (entry)
3917-
return entry->value;
3935+
Tld *result = find_container_decl(g, decls_scope, name);
3936+
if (result != nullptr)
3937+
return result;
39183938
}
39193939
scope = scope->parent;
39203940
}
@@ -4475,10 +4495,12 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
44754495
Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
44764496
Buf namespace_name = BUF_INIT;
44774497
buf_init_from_buf(&namespace_name, &package->pkg_path);
4478-
if (buf_len(&namespace_name) != 0) buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR);
4479-
buf_append_mem(&namespace_name, buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1,
4480-
buf_len(&noextname) - (buf_len(&resolved_root_src_dir) + 1));
4481-
buf_replace(&namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR);
4498+
if (source_kind == SourceKindNonRoot) {
4499+
if (buf_len(&namespace_name) != 0) buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR);
4500+
buf_append_mem(&namespace_name, buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1,
4501+
buf_len(&noextname) - (buf_len(&resolved_root_src_dir) + 1));
4502+
buf_replace(&namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR);
4503+
}
44824504

44834505
RootStruct *root_struct = allocate<RootStruct>(1);
44844506
root_struct->package = package;
@@ -6806,3 +6828,16 @@ bool ptr_allows_addr_zero(ZigType *ptr_type) {
68066828
}
68076829
return false;
68086830
}
6831+
6832+
void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg) {
6833+
size_t i = g->tld_ref_source_node_stack.length;
6834+
for (;;) {
6835+
if (i == 0)
6836+
break;
6837+
i -= 1;
6838+
AstNode *source_node = g->tld_ref_source_node_stack.at(i);
6839+
if (source_node) {
6840+
msg = add_error_note(g, msg, source_node, buf_sprintf("referenced here"));
6841+
}
6842+
}
6843+
}

src/analyze.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ void semantic_analyze(CodeGen *g);
1414
ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
1515
ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);
1616
ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
17+
void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg);
1718
ZigType *new_type_table_entry(ZigTypeId id);
1819
ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
1920
ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
@@ -49,13 +50,15 @@ bool type_is_nonnull_ptr(ZigType *type);
4950

5051
enum SourceKind {
5152
SourceKindRoot,
53+
SourceKindPkgMain,
5254
SourceKindNonRoot,
5355
};
5456
ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Buf *source_code,
5557
SourceKind source_kind);
5658

5759
ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope);
5860
Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
61+
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name);
5962
void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node);
6063
bool type_is_codegen_pointer(ZigType *type);
6164

src/codegen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7748,7 +7748,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
77487748
g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
77497749
g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
77507750
g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents,
7751-
SourceKindNonRoot);
7751+
SourceKindPkgMain);
77527752

77537753
return ErrorNone;
77547754
}
@@ -7987,7 +7987,7 @@ static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *ba
79877987
zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));
79887988
}
79897989

7990-
return add_source_file(g, package, resolved_path, import_code, SourceKindNonRoot);
7990+
return add_source_file(g, package, resolved_path, import_code, SourceKindPkgMain);
79917991
}
79927992

79937993
static ZigPackage *create_bootstrap_pkg(CodeGen *g, ZigPackage *pkg_with_main) {

0 commit comments

Comments
 (0)