From ac1625bdb654fb148b66d5b7d91d88a38e743cf7 Mon Sep 17 00:00:00 2001 From: Motiejus Date: Mon, 23 Feb 2026 07:20:32 +0000 Subject: [PATCH] sema: fix cross-module constant resolution timeout Guard evalCrossModuleDeclValue mini-sema to prevent recursive resolution and expensive file I/O: - Only attempt cross-module resolution in comptime blocks - Do not propagate source_dir to mini-sema to prevent infinite recursion (e.g. common.zig -> builtin.abi -> ...) Co-Authored-By: Claude Opus 4.6 --- stage0/sema.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/stage0/sema.c b/stage0/sema.c index 0c0bab157a..d6486c9378 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -5808,10 +5808,13 @@ static AirInstRef evalCrossModuleDeclValue( // Create a mini-sema with the imported module's ZIR. // Shares the InternPool so IP indices are valid across both semas. + // Do NOT set source_dir: this prevents recursive cross-module + // resolution (e.g. common.zig -> builtin.abi) from causing + // infinite recursion or expensive file I/O. Sema mini_sema; semaInit(&mini_sema, parent_sema->ip, *import_zir); - mini_sema.source_dir = parent_sema->source_dir; - mini_sema.module_root = parent_sema->module_root; + mini_sema.source_dir = NULL; + mini_sema.module_root = NULL; SemaBlock ct_block; semaBlockInit(&ct_block, &mini_sema, NULL); @@ -5945,8 +5948,10 @@ static AirInstRef zirFieldValComptime( // evaluate its value body using a mini-sema. // This handles patterns like: common.want_aeabi where common is // @import("./common.zig") and want_aeabi is a pub const bool. + // Only attempt in comptime context to avoid expensive file I/O + // on every runtime field_val instruction. if (obj_ip == IP_INDEX_VOID_VALUE && obj_ref >= ZIR_REF_START_INDEX - && sema->source_dir) { + && sema->source_dir && block->is_comptime) { uint32_t obj_inst = obj_ref - ZIR_REF_START_INDEX; ZirInstTag obj_tag = sema->code.inst_tags[obj_inst]; if (obj_tag == ZIR_INST_DECL_VAL || obj_tag == ZIR_INST_DECL_REF) {