diff --git a/stage0/sema.c b/stage0/sema.c index 444d84ea8f..7eedffb7c6 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) {