diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index 752422c..8257343 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -1641,10 +1641,26 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): local_fn: mlirlite.Function* = self.find_func_in_module(mod, call_name) if local_fn is not None and local_fn.RetTy is not None: call_ret_ty = local_fn.RetTy else: - cf_vpi: mlirlite.LLVMType* = self._lookup_method_ret_ty_via_vpi(pool, cf_sha1, None, cf_bare) + # {sha}.Class.method: the vpi return-annotation cache and the dependency + # text.ll both key methods by class, so the class segment must be passed + # through. Only when it names a registered class: `{sha}.submod.func` has + # the same shape but its symbol is the bare module function. + cf_cls: str = None + cf_mid: str = cf_dot + 1 + if uint64(cf_last) > uint64(cf_mid): + cf_mid_len: sizet = sizet(uint64(cf_last) - uint64(cf_mid)) + cf_cls_buf: bytes = stdlib.malloc(cf_mid_len + 1) + if cf_cls_buf is not None: + string.strncpy(cf_cls_buf, cf_mid, cf_mid_len) + cf_cls_buf[cf_mid_len] = '\0' + if self.Gen.StructGen.get_struct_type(cf_cls_buf) is not None: cf_cls = cf_cls_buf + else: stdlib.free(cf_cls_buf) + cf_use_bare: int = 1 + if cf_cls is not None: cf_use_bare = 0 + cf_vpi: mlirlite.LLVMType* = self._lookup_method_ret_ty_via_vpi(pool, cf_sha1, cf_cls, cf_bare) if cf_vpi is not None: call_ret_ty = cf_vpi else: - cf_ret: mlirlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, cf_sha1, None, cf_bare, 1) + cf_ret: mlirlite.LLVMType* = self._LookupMethodRetTyFromTextLL(pool, cf_sha1, cf_cls, cf_bare, cf_use_bare) if cf_ret is not None: call_ret_ty = cf_ret else: # 编译器内置(ord/chr/min/max):builtins.vp 只是注释桩,没有任何声明, @@ -1659,6 +1675,7 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase): # Dependency text.ll does not exist (module not yet translated): Phase A translates files # in order (main.vp before its imported mbuddytest.vp), so keep the default type without fail-fast. if bi_synth == 0 and self._dep_text_ll_exists(pool, cf_sha1) != 0: self.Gen.TypeGenErr.fatal_error(node, f"Cannot obtain the cross-module function return type precisely (neither vpi nor text.ll hit); the default i32 will truncate pointers: {call_name}", "TypeError") + if cf_cls is not None: stdlib.free(cf_cls) stdlib.free(cf_sha1) stdlib.free(cf_bare) # 迟到的补参:call_name 此时已带定义模块 SHA1 前缀(权威键),补上早期因链式接收者