authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-03-08 19:57:22+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
log3eb90a110f2c4b6eea82b0fcd7c8cab386594437
tree09250a534089ae7ecd8dcbb0291cec5cd9fe55fa
parent03d392923208550c21f2f3813379830b76c54133

autodoc: add support for pointers and comptime expressions in decl paths


2 files changed, 184 insertions(+), 122 deletions(-)

lib/docs/main.js+105-88
......@@ -144,13 +144,33 @@
144144 return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind);
145145 }
146146
147 function findCteInDeclPath(path) {
148 for (var i = path.length - 1; i >= 0; i -= 1) {
149 const decl = zigAnalysis.decls[path[i]];
150 if ("comptimeExpr" in decl.value) {
151 return decl;
152 }
153
154 if ("declPath" in decl.value) {
155 const res = findCteInDeclPath(decl.value.declPath);
156 if (res !== null) {
157 return res;
158 }
159 }
160 }
161
162 return null;
163 }
164
147165 function resolveValue(value) {
148166 var i = 0;
149167 while(i < 1000) {
150168 i += 1;
151169
152170 if ("declPath" in value) {
153 console.assert(value.declPath.length == 1); // only support declRefs for now
171 if (value.hasCte) {
172 return findCteInDeclPath(value.declPath).value;
173 }
154174 value = zigAnalysis.decls[value.declPath[0]].value;
155175 continue;
156176 }
......@@ -171,30 +191,34 @@
171191 }
172192
173193 if ("declPath" in decl.value) {
174 console.assert(decl.value.declPath.length == 1); // only support declRefs for now
175 decl = zigAnalysis.decls[decl.value.declPath[0]];
194 if (decl.value.hasCte) {
195 decl = findCteInDeclPath(decl.value.declPath);
196 } else {
197 decl = zigAnalysis.decls[decl.value.declPath[0]];
198 }
199
176200 continue;
177201 }
178202
179203 if ("int" in decl.value) {
180 return resolveTypeRefToTypeId(decl.value.int.typeRef);
204 return decl.value.int.typeRef;
181205 }
182206
183207 if ("float" in decl.value) {
184 return resolveTypeRefToTypeId(decl.value.float.typeRef);
208 return decl.value.float.typeRef;
185209 }
186210
187211 if ("array" in decl.value) {
188 return resolveTypeRefToTypeId(decl.value.array.typeRef);
212 return decl.value.array.typeRef;
189213 }
190214
191215 if ("struct" in decl.value) {
192 return resolveTypeRefToTypeId(decl.value.struct.typeRef);
216 return decl.value.struct.typeRef;
193217 }
194218
195219 if ("comptimeExpr" in decl.value) {
196220 const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr];
197 return resolveTypeRefToTypeId(cte.typeRef);
221 return cte.typeRef;
198222 }
199223
200224 if ("call" in decl.value) {
......@@ -205,7 +229,7 @@
205229 console.assert("type" in fn_decl_value); //TODO handle comptimeExpr
206230 const fn_type = zigAnalysis.types[fn_decl_value.type];
207231 console.assert(fn_type.kind === typeKinds.Fn);
208 return resolveTypeRefToTypeId(fn_type.ret);
232 return fn_type.ret;
209233 }
210234
211235 console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
......@@ -215,23 +239,6 @@
215239 console.assert(false);
216240 }
217241
218 function resolveTypeRefToTypeId(ref) {
219 if ("unspecified" in ref) {
220 console.log("found an unspecified type!")
221 return -1;
222 }
223
224 if ("declRef" in ref) {
225 return typeOfDecl(ref.declRef);
226 }
227
228 if ("type" in ref) {
229 return ref.type;
230 }
231
232 console.assert(false);
233 }
234
235242 function render() {
236243 domStatus.classList.add("hidden");
237244 domFnProto.classList.add("hidden");
......@@ -369,7 +376,7 @@
369376 console.assert("type" in value);
370377 var typeObj = zigAnalysis.types[value.type];
371378
372 domFnProtoCode.innerHTML = typeIndexName(value.type, true, true, fnDecl);
379 domFnProtoCode.innerHTML = typeValueName(value, true, true, fnDecl);
373380
374381 var docsSource = null;
375382 var srcNode = zigAnalysis.astNodes[fnDecl.src];
......@@ -462,9 +469,6 @@
462469
463470
464471 var value = typeObj.params[i];
465 var valueType = resolveValue(value);
466 console.assert("type" in valueType);
467 var argTypeIndex = valueType.type;
468472 var html = '<pre>' + escapeHtml(fieldNode.name) + ": ";
469473 if (isVarArgs && i === typeObj.params.length - 1) {
470474 html += '...';
......@@ -482,8 +486,6 @@
482486 } else if ("type" in value) {
483487 var name = zigAnalysis.types[value.type].name;
484488 html += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
485 } else if (argTypeIndex != null) {
486 html += typeIndexName(argTypeIndex, true, true);
487489 } else {
488490 html += '<span class="tok-kw">var</span>';
489491 }
......@@ -654,13 +656,16 @@
654656 }
655657 }
656658
657 function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
658 return typeValueName({ type: typeIndex }, wantHtml, wantLink, fnDecl, linkFnNameDecl);
659 }
660
661659 function typeValueName(typeValue, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
662660 if ("declPath" in typeValue) {
663 console.assert(typeValue.declPath.length == 1);
661 if (typeValue.hasCte) {
662 // TODO: find the cte, print it nicely
663 if (wantLink) {
664 return '<a href=""># CTE TODO #</a>';
665 } else {
666 return "# CTE TODO #";
667 }
668 }
664669 var declIndex = typeValue.declPath[0];
665670 var name = zigAnalysis.decls[declIndex].name;
666671 var declPath = getCanonDeclPath(declIndex);
......@@ -695,12 +700,17 @@
695700 }
696701 }
697702
698 function shouldSkipParamName(typeIndex, paramName) {
699 var typeObj = zigAnalysis.types[typeIndex];
700 if (typeObj.kind === typeKinds.Pointer && getPtrSize(typeObj) === pointerSizeEnum.One) {
701 typeIndex = typeObj.child;
703 function shouldSkipParamName(typeRef, paramName) {
704 var resolvedTypeRef = resolveValue(typeRef);
705 if ("type" in resolvedTypeRef) {
706 var typeObj = zigAnalysis.types[resolvedTypeRef.type];
707 if (typeObj.kind === typeKinds.Pointer &&
708 getPtrSize(typeObj) === pointerSizeEnum.One) {
709 const value = resolveValue(typeObj.child);
710 return typeValueName(value, false, true).toLowerCase() === paramName;
711 }
702712 }
703 return typeIndexName(typeIndex, false, true).toLowerCase() === paramName;
713 return false;
704714 }
705715
706716 function getPtrSize(typeObj) {
......@@ -716,20 +726,25 @@
716726 for (var arg_i = 0; arg_i < callObj.args.length; arg_i += 1) {
717727 if (arg_i !== 0) html += ', ';
718728 var argObj = callObj.args[arg_i];
719 html += getValueText(argObj.type, argObj.value, true, true);
729 html += getValueText(argObj, argObj.value, true, true);
720730 }
721731 html += ')';
722732 return html;
723733 }
724734
725 function getValueText(typeIndex, value, wantHtml, wantLink) {
726 var typeObj = zigAnalysis.types[typeIndex];
735 function getValueText(typeRef, value, wantHtml, wantLink) {
736 var resolvedTypeRef = resolveValue(typeRef);
737 if ("comptimeExpr" in resolvedTypeRef) {
738 return "# CTE TODO #";
739 }
740 console.assert("type" in resolvedTypeRef);
741 var typeObj = zigAnalysis.types[typeRef.type];
727742 switch (typeObj.kind) {
728743 case typeKinds.Type:
729744 return typeIndexName(value, wantHtml, wantLink);
730745 case typeKinds.Fn:
731746 var fnObj = zigAnalysis.fns[value];
732 return typeIndexName(fnObj.type, wantHtml, wantLink);
747 return typeValueName(fnObj, wantHtml, wantLink);
733748 case typeKinds.Int:
734749 if (wantHtml) {
735750 return '<span class="tok-number">' + value + '</span>';
......@@ -923,11 +938,10 @@
923938 if (i != 0) {
924939 payloadHtml += ', ';
925940 }
941
926942 var value = typeObj.params[i];
927943 var paramValue = resolveValue(value);
928 console.assert("type" in paramValue);
929 var argTypeIndex = paramValue.type;
930
944 var isCte = "comptimeExpr" in paramValue;
931945
932946 if (fields != null) {
933947 var paramNode = zigAnalysis.astNodes[fields[i]];
......@@ -956,7 +970,7 @@
956970 var paramName = paramNode.name;
957971 if (paramName != null) {
958972 // skip if it matches the type name
959 if (argTypeIndex == null || !shouldSkipParamName(argTypeIndex, paramName)) {
973 if (!shouldSkipParamName(paramValue, paramName)) {
960974 payloadHtml += paramName + ': ';
961975 }
962976 }
......@@ -975,10 +989,10 @@
975989 payloadHtml += '<span class="tok-kw" style="color:lightblue;">' + escapeHtml(decl.name) + '</span>';
976990 payloadHtml += '</a>';
977991 } else if ("type" in value) {
978 var name = zigAnalysis.types[value.type].name;
992 var name = typeValueName(value, false);
979993 payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
980 } else if (argTypeIndex != null) {
981 payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink);
994 } else if ("comptimeExpr" in value) {
995 payloadHtml += '<span class="tok-kw"> # CTE TODO #</span>';
982996 } else if (wantHtml) {
983997 payloadHtml += '<span class="tok-kw">var</span>';
984998 } else {
......@@ -1152,7 +1166,7 @@
11521166
11531167 function renderValue(decl) {
11541168
1155 var declTypeId = typeOfDecl(decl);
1169 var declTypeRef = typeOfDecl(decl);
11561170 var declValueText = "";
11571171 switch(Object.keys(decl.value)[0]) {
11581172 case "int":
......@@ -1170,7 +1184,7 @@
11701184 }
11711185
11721186 domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' +
1173 escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true) +
1187 escapeHtml(decl.name) + ': ' + typeValueName(declTypeRef, true, true) +
11741188 " = " + declValueText;
11751189
11761190 var docs = zigAnalysis.astNodes[decl.src].docs;
......@@ -1183,9 +1197,9 @@
11831197 }
11841198
11851199 function renderVar(decl) {
1186 var declTypeId = typeOfDecl(decl);
1200 var declTypeRef = typeOfDecl(decl);
11871201 domFnProtoCode.innerHTML = '<span class="tok-kw">var</span> ' +
1188 escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true);
1202 escapeHtml(decl.name) + ': ' + typeValueName(declTypeRef, true, true);
11891203
11901204 var docs = zigAnalysis.astNodes[decl.src].docs;
11911205 if (docs != null) {
......@@ -1221,8 +1235,9 @@
12211235 var value = zigAnalysis.types[declValue.type];
12221236 var kind = value.kind;
12231237 if (kind === typeKinds.Fn) {
1224 //if (allCompTimeFnCallsHaveTypeResult(decl.type, declTypeId)) {
1225 if (resolveTypeRefToTypeId(value.ret) == typeTypeId) {
1238 // TODO: handle CTE return types when we know their type.
1239 const resVal = resolveValue(value.ret);
1240 if ("type" in resVal && resVal.type == typeTypeId) {
12261241 typesList.push(decl);
12271242 } else {
12281243 fnsList.push(decl);
......@@ -1300,7 +1315,7 @@
13001315 var declType = resolveValue(decl.value);
13011316 console.assert("type" in declType);
13021317
1303 tdFnCode.innerHTML = typeIndexName(declType.type, true, true, decl, navLinkDecl(decl.name));
1318 tdFnCode.innerHTML = typeValueName(declType, true, true, decl, navLinkDecl(decl.name));
13041319
13051320 var docs = zigAnalysis.astNodes[decl.src].docs;
13061321 if (docs != null) {
......@@ -1327,35 +1342,37 @@
13271342 } else {
13281343 var field = container.fields[i];
13291344 html += ": ";
1330 if (typeof(field) === 'object') {
1331 if (field.failure === true) {
1332 html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
1333 } else if ("declPath" in field) {
1334 for (var j = field.declPath.length - 1; j >= 0; j--) {
1335 var decl = zigAnalysis.decls[field.declPath[j]];
1336
1337 html += '<a href="'+navLinkDecl(decl.name)+'">';
1338 html += '<span class="tok-kw" style="color:lightblue;">' +
1339 escapeHtml(decl.name) + '</span>';
1340 html += '</a>';
1341 if (j != 0) html += ".";
1345 if (field.failure === true) {
1346 html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
1347 } else if ("declPath" in field) {
1348 for (var j = field.declPath.length - 1; j >= 0; j--) {
1349 var decl = zigAnalysis.decls[field.declPath[j]];
1350
1351 // TODO: handle nested decl paths properly!
1352 if (field.hasCte) {
1353 html += "<a href=\"\"># CTE TODO #</a>";
1354 break;
13421355 }
1343 // at the end of the for loop this is the value of `decl`
1344 //decl = zigAnalysis.decls[field.declPath[0]];
1345
1346 var val = resolveValue(decl.value);
1347 console.assert("type" in val);
1348 var valType = zigAnalysis.types[val.type];
1349 var valTypeName = typeShorthandName(valType);
1350 html += ' ('+ valTypeName +')';
1351 } else if ("type" in field) {
1352 var name = zigAnalysis.types[field.type].name;
1353 html += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
1354 } else {
1355 html += '<span class="tok-kw">var</span>';
1356
1357 html += '<a href="'+navLinkDecl(decl.name)+'">';
1358 html += '<span class="tok-kw" style="color:lightblue;">' +
1359 escapeHtml(decl.name) + '</span>';
1360 html += '</a>';
1361 if (j != 0) html += ".";
13561362 }
1363 // at the end of the for loop this is the value of `decl`
1364 //decl = zigAnalysis.decls[field.declPath[0]];
1365
1366 var val = resolveValue(decl.value);
1367 console.assert("type" in val);
1368 var valType = zigAnalysis.types[val.type];
1369 var valTypeName = typeShorthandName(valType);
1370 html += ' ('+ valTypeName +')';
1371 } else if ("type" in field) {
1372 var name = zigAnalysis.types[field.type].name;
1373 html += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
13571374 } else {
1358 html += typeIndexName(field, true, true);
1375 html += '<span class="tok-kw">var</span>';
13591376 }
13601377 }
13611378
......@@ -1385,7 +1402,7 @@
13851402 tdNameA.setAttribute('href', navLinkDecl(decl.name));
13861403 tdNameA.textContent = decl.name;
13871404
1388 tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
1405 tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true);
13891406
13901407 var docs = zigAnalysis.astNodes[decl.src].docs;
13911408 if (docs != null) {
......@@ -1412,7 +1429,7 @@
14121429 tdNameA.setAttribute('href', navLinkDecl(decl.name));
14131430 tdNameA.textContent = decl.name;
14141431
1415 tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
1432 tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true);
14161433
14171434 var docs = zigAnalysis.astNodes[decl.src].docs;
14181435 if (docs != null) {
src/Autodoc.zig+79-34
......@@ -30,7 +30,7 @@ decl_paths_pending_on_types: std.AutoHashMapUnmanaged(
3030
3131const DeclPathResumeInfo = struct {
3232 file: *File,
33 path: []usize,
33 decl_path: DocData.DeclPath,
3434};
3535
3636var arena_allocator: std.heap.ArenaAllocator = undefined;
......@@ -347,7 +347,7 @@ const DocData = struct {
347347 Int: struct { name: []const u8 },
348348 Float: struct { name: []const u8 },
349349 Pointer: struct {
350 name: []const u8,
350 size: std.builtin.TypeInfo.Pointer.Size,
351351 child: TypeRef,
352352 },
353353 Array: struct {
......@@ -427,6 +427,20 @@ const DocData = struct {
427427 .Int => |v| try printTypeBody(v, options, w),
428428 .Float => |v| try printTypeBody(v, options, w),
429429 .Type => |v| try printTypeBody(v, options, w),
430 .Pointer => |v| {
431 if (options.whitespace) |ws| try ws.outputIndent(w);
432 try w.print(
433 \\"size": {},
434 \\
435 , .{@enumToInt(v.size)});
436 if (options.whitespace) |ws| try ws.outputIndent(w);
437 try w.print(
438 \\"child":
439 , .{});
440
441 if (options.whitespace) |*ws| ws.indent_level += 1;
442 try v.child.jsonStringify(options, w);
443 },
430444 else => {
431445 std.debug.print(
432446 "TODO: add {s} to `DocData.Type.jsonStringify`\n",
......@@ -458,9 +472,14 @@ const DocData = struct {
458472 }
459473 };
460474
475 const DeclPath = struct {
476 path: []usize, // indexes in `decls`
477 hasCte: bool = false, // a prefix of this path could not be resolved
478 };
479
461480 const TypeRef = union(enum) {
462481 unspecified,
463 declPath: []usize, // indexes in `decls`
482 declPath: DeclPath,
464483 type: usize, // index in `types`
465484 comptimeExpr: usize, // index in `comptimeExprs`
466485
......@@ -490,9 +509,9 @@ const DocData = struct {
490509 , .{ @tagName(self), v });
491510 },
492511 .declPath => |v| {
493 try w.print("{{ \"declPath\": [", .{});
494 for (v) |d, i| {
495 const comma = if (i == v.len - 1) "]}" else ",";
512 try w.print("{{ \"hasCte\": {}, \"declPath\": [", .{v.hasCte});
513 for (v.path) |d, i| {
514 const comma = if (i == v.path.len - 1) "]}" else ",";
496515 try w.print("{d}{s}", .{ d, comma });
497516 }
498517 },
......@@ -509,7 +528,7 @@ const DocData = struct {
509528 @"struct": Struct,
510529 bool: bool,
511530 type: usize, // index in `types`
512 declPath: []usize, // indices in `decl`
531 declPath: DeclPath,
513532 int: struct {
514533 typeRef: TypeRef,
515534 value: usize, // direct value
......@@ -584,9 +603,9 @@ const DocData = struct {
584603 w,
585604 ),
586605 .declPath => |v| {
587 try w.print("{{ \"declPath\": [", .{});
588 for (v) |d, i| {
589 const comma = if (i == v.len - 1) "]}" else ",";
606 try w.print("{{ \"hasCte\": {}, \"declPath\": [", .{v.hasCte});
607 for (v.path) |d, i| {
608 const comma = if (i == v.path.len - 1) "]}" else ",";
590609 try w.print("{d}{s}", .{ d, comma });
591610 }
592611 },
......@@ -676,6 +695,19 @@ fn walkInstruction(
676695 },
677696 };
678697 },
698 .ptr_type_simple => {
699 const ptr = data[inst_index].ptr_type_simple;
700 const type_slot_index = self.types.items.len;
701 const elem_type_ref = try self.walkRef(file, parent_scope, ptr.elem_type);
702 try self.types.append(self.arena, .{
703 .Pointer = .{
704 .size = ptr.size,
705 .child = walkResultToTypeRef(elem_type_ref),
706 },
707 });
708
709 return DocData.WalkResult{ .type = type_slot_index };
710 },
679711 .array_init => {
680712 const pl_node = data[inst_index].pl_node;
681713 const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
......@@ -770,7 +802,7 @@ fn walkInstruction(
770802 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);
771803 var path = try self.arena.alloc(usize, 1);
772804 path[0] = decls_slot_index;
773 return DocData.WalkResult{ .declPath = path };
805 return DocData.WalkResult{ .declPath = .{ .path = path } };
774806 },
775807 .field_val, .field_call_bind, .field_ptr => {
776808 const pl_node = data[inst_index].pl_node;
......@@ -844,8 +876,9 @@ fn walkInstruction(
844876 // the analyzed data corresponding to the top-most decl of this path.
845877 // We are now going to reverse loop over `path` to resolve each name
846878 // to its corresponding index in `decls`.
847 try self.tryResolveDeclPath(file, path.items);
848 return DocData.WalkResult{ .declPath = path.items };
879 var decl_path: DocData.DeclPath = .{ .path = path.items };
880 try self.tryResolveDeclPath(file, &decl_path);
881 return DocData.WalkResult{ .declPath = decl_path };
849882 },
850883 .int_type => {
851884 const int_type = data[inst_index].int_type;
......@@ -893,7 +926,7 @@ fn walkInstruction(
893926
894927 return DocData.WalkResult{ .call = call_slot_index };
895928 },
896 .func => {
929 .func, .func_inferred => {
897930 const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));
898931
899932 try self.ast_nodes.ensureUnusedCapacity(self.arena, fn_info.total_params_len);
......@@ -960,18 +993,18 @@ fn walkInstruction(
960993 return DocData.WalkResult{ .type = self.types.items.len - 1 };
961994 },
962995 .extended => {
963 // TODO: this assumes that we always return a type when analyzing
964 // an extended instruction. Also we willingfully not reserve
965 // a slot for functions (handled right above) despite them
966 // being stored in `types`. The reason why we reserve a slot
967 // in here, is for decl paths and their resolution system.
996 // NOTE: this code + the subsequent defer block are working towards
997 // solving pending decl paths that depend on a type to be analyzed.
998 // When we don't find a type, the defer will run anyway but shouldn't
999 // ever be able to find a match inside `decl_paths_pending_on_types`
1000 // TODO: extract this logic into a function and only call it when appropriate.
9681001 const type_slot_index = self.types.items.len;
9691002 try self.types.append(self.arena, .{ .Unanalyzed = {} });
9701003
9711004 defer {
9721005 if (self.decl_paths_pending_on_types.get(type_slot_index)) |paths| {
973 for (paths.items) |resume_info| {
974 self.tryResolveDeclPath(resume_info.file, resume_info.path) catch {
1006 for (paths.items) |*resume_info| {
1007 self.tryResolveDeclPath(resume_info.file, &resume_info.decl_path) catch {
9751008 @panic("Out of memory");
9761009 };
9771010 }
......@@ -1537,8 +1570,8 @@ fn walkDecls(
15371570
15381571 // Unblock any pending decl path that was waiting for this decl.
15391572 if (self.decl_paths_pending_on_decls.get(decls_slot_index)) |paths| {
1540 for (paths.items) |resume_info| {
1541 try self.tryResolveDeclPath(resume_info.file, resume_info.path);
1573 for (paths.items) |*resume_info| {
1574 try self.tryResolveDeclPath(resume_info.file, &resume_info.decl_path);
15421575 }
15431576
15441577 _ = self.decl_paths_pending_on_decls.remove(decls_slot_index);
......@@ -1560,10 +1593,12 @@ fn tryResolveDeclPath(
15601593 self: *Autodoc,
15611594 /// File from which the decl path originates.
15621595 file: *File,
1563 path: []usize,
1596 decl_path: *DocData.DeclPath,
15641597) error{OutOfMemory}!void {
1598 const path: []usize = decl_path.path;
1599
15651600 var i: usize = path.len;
1566 while (i > 1) {
1601 outer: while (i > 1) {
15671602 i -= 1;
15681603 const decl_index = path[i];
15691604 const string_index = path[i - 1];
......@@ -1580,7 +1615,7 @@ fn tryResolveDeclPath(
15801615 if (!res.found_existing) res.value_ptr.* = .{};
15811616 try res.value_ptr.*.append(self.arena, .{
15821617 .file = file,
1583 .path = path[0 .. i + 1],
1618 .decl_path = .{ .path = path[0 .. i + 1] },
15841619 });
15851620
15861621 return;
......@@ -1590,15 +1625,25 @@ fn tryResolveDeclPath(
15901625 switch (parent.value) {
15911626 else => {
15921627 std.debug.panic(
1593 "TODO: handle `{s}`in walkInstruction.field_val\n \"{s}\":{}",
1628 "TODO: handle `{s}`in tryResolveDecl.field_val\n \"{s}\":{}",
15941629 .{ @tagName(parent.value), parent.name, parent.value },
15951630 );
15961631 },
1632 .comptimeExpr => {
1633 // Since we hit a cte, we leave the remaining strings unresolved
1634 // and completely give up on resolving this decl path.
1635 decl_path.hasCte = true;
1636 break :outer;
1637 },
15971638 .declPath => |dp| {
1598 if (self.pending_decl_paths.getPtr(&dp[0])) |waiter_list| {
1639 if (dp.hasCte) {
1640 decl_path.hasCte = true;
1641 break :outer;
1642 }
1643 if (self.pending_decl_paths.getPtr(&dp.path[0])) |waiter_list| {
15991644 try waiter_list.append(self.arena, .{
16001645 .file = file,
1601 .path = path[0 .. i + 1],
1646 .decl_path = .{ .path = path[0 .. i + 1] },
16021647 });
16031648
16041649 // This decl path is pending completion
......@@ -1610,7 +1655,7 @@ fn tryResolveDeclPath(
16101655 return;
16111656 }
16121657
1613 const final_decl_index = dp[0];
1658 const final_decl_index = dp.path[0];
16141659 // For the purpose of being able to call tryResolveDeclPath again,
16151660 // we momentarily replace the decl index present in `path[i]`
16161661 // with the final decl in `dp`.
......@@ -1619,7 +1664,7 @@ fn tryResolveDeclPath(
16191664 // will not get fully resolved (also in the case that final_decl is
16201665 // not resolved yet).
16211666 path[i] = final_decl_index;
1622 try self.tryResolveDeclPath(file, path);
1667 try self.tryResolveDeclPath(file, decl_path);
16231668 path[i] = decl_index;
16241669 },
16251670 .type => |t_index| switch (self.types.items[t_index]) {
......@@ -1643,7 +1688,7 @@ fn tryResolveDeclPath(
16431688 if (!res.found_existing) res.value_ptr.* = .{};
16441689 try res.value_ptr.*.append(self.arena, .{
16451690 .file = file,
1646 .path = path[0 .. i + 1],
1691 .decl_path = .{ .path = path[0 .. i + 1] },
16471692 });
16481693
16491694 return;
......@@ -1677,8 +1722,8 @@ fn tryResolveDeclPath(
16771722 // attempting to resolve any other decl.
16781723 _ = self.pending_decl_paths.remove(&path[0]);
16791724
1680 for (waiter_list.items) |resume_info| {
1681 try self.tryResolveDeclPath(resume_info.file, resume_info.path);
1725 for (waiter_list.items) |*resume_info| {
1726 try self.tryResolveDeclPath(resume_info.file, &resume_info.decl_path);
16821727 }
16831728 // TODO: this is where we should free waiter_list, but its in the arena
16841729 // that said, we might want to store it elsewhere and reclaim memory asap