| ... | ... | @@ -3229,39 +3229,42 @@ fn processExportsInner( |
| 3229 | 3229 | } |
| 3230 | 3230 | } |
| 3231 | 3231 | |
| 3232 | | pub fn populateTestFunctions( |
| 3233 | | pt: Zcu.PerThread, |
| 3234 | | main_progress_node: std.Progress.Node, |
| 3235 | | ) Allocator.Error!void { |
| 3232 | pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { |
| 3236 | 3233 | const zcu = pt.zcu; |
| 3237 | 3234 | const gpa = zcu.gpa; |
| 3238 | 3235 | const ip = &zcu.intern_pool; |
| 3236 | |
| 3237 | // Our job is to correctly set the value of the `test_functions` declaration if it has been |
| 3238 | // analyzed and sent to codegen, It usually will have been, because the test runner will |
| 3239 | // reference it, and `std.builtin` shouldn't have type errors. However, if it hasn't been |
| 3240 | // analyzed, we will just terminate early, since clearly the test runner hasn't referenced |
| 3241 | // `test_functions` so there's no point populating it. More to the the point, we potentially |
| 3242 | // *can't* populate it without doing some type resolution, and... let's try to leave Sema in |
| 3243 | // the past here. |
| 3244 | |
| 3239 | 3245 | const builtin_mod = zcu.builtin_modules.get(zcu.root_mod.getBuiltinOptions(zcu.comp.config).hash()).?; |
| 3240 | 3246 | const builtin_file_index = zcu.module_roots.get(builtin_mod).?.unwrap().?; |
| 3241 | | pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) { |
| 3242 | | error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt |
| 3243 | | error.OutOfMemory => |e| return e, |
| 3244 | | }; |
| 3245 | | const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index)); |
| 3246 | | const builtin_namespace = builtin_root_type.getNamespace(zcu).unwrap().?; |
| 3247 | const builtin_root_type = zcu.fileRootType(builtin_file_index); |
| 3248 | if (builtin_root_type == .none) return; // `@import("builtin")` never analyzed |
| 3249 | const builtin_namespace = Type.fromInterned(builtin_root_type).getNamespace(zcu).unwrap().?; |
| 3250 | // We know that the namespace has a `test_functions`... |
| 3247 | 3251 | const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted( |
| 3248 | 3252 | try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls), |
| 3249 | 3253 | Zcu.Namespace.NameAdapter{ .zcu = zcu }, |
| 3250 | 3254 | ).?; |
| 3255 | // ...but it might not be populated, so let's check that! |
| 3256 | if (zcu.failed_analysis.contains(.wrap(.{ .nav_val = nav_index })) or |
| 3257 | zcu.transitive_failed_analysis.contains(.wrap(.{ .nav_val = nav_index })) or |
| 3258 | ip.getNav(nav_index).status != .fully_resolved) |
| 3251 | 3259 | { |
| 3252 | | // We have to call `ensureNavValUpToDate` here in case `builtin.test_functions` |
| 3253 | | // was not referenced by start code. |
| 3254 | | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); |
| 3255 | | defer { |
| 3256 | | zcu.sema_prog_node.end(); |
| 3257 | | zcu.sema_prog_node = std.Progress.Node.none; |
| 3258 | | } |
| 3259 | | pt.ensureNavValUpToDate(nav_index) catch |err| switch (err) { |
| 3260 | | error.AnalysisFail => return, |
| 3261 | | error.OutOfMemory => return error.OutOfMemory, |
| 3262 | | }; |
| 3260 | // The value of `builtin.test_functions` was either never referenced, or failed analysis. |
| 3261 | // Either way, we don't need to do anything. |
| 3262 | return; |
| 3263 | 3263 | } |
| 3264 | 3264 | |
| 3265 | // Okay, `builtin.test_functions` is (potentially) referenced and valid. Our job now is to swap |
| 3266 | // its placeholder `&.{}` value for the actual list of all test functions. |
| 3267 | |
| 3265 | 3268 | const test_fns_val = zcu.navValue(nav_index); |
| 3266 | 3269 | const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); |
| 3267 | 3270 | |
| ... | ... | @@ -3363,17 +3366,8 @@ pub fn populateTestFunctions( |
| 3363 | 3366 | } }); |
| 3364 | 3367 | ip.mutateVarInit(test_fns_val.toIntern(), new_init); |
| 3365 | 3368 | } |
| 3366 | | { |
| 3367 | | assert(zcu.codegen_prog_node.index == .none); |
| 3368 | | zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); |
| 3369 | | defer { |
| 3370 | | zcu.codegen_prog_node.end(); |
| 3371 | | zcu.codegen_prog_node = std.Progress.Node.none; |
| 3372 | | } |
| 3373 | | |
| 3374 | | // The linker thread is not running, so we actually need to dispatch this task directly. |
| 3375 | | @import("../link.zig").linkTestFunctionsNav(pt, nav_index); |
| 3376 | | } |
| 3369 | // The linker thread is not running, so we actually need to dispatch this task directly. |
| 3370 | @import("../link.zig").linkTestFunctionsNav(pt, nav_index); |
| 3377 | 3371 | } |
| 3378 | 3372 | |
| 3379 | 3373 | /// Stores an error in `pt.zcu.failed_files` for this file, and sets the file |