Skip to content

fix: preserve inherited generic table fields - #3498

Open
sogav21 wants to merge 1 commit into
LuaLS:masterfrom
sogav21:codex/issue-3443-inherited-generic-table-fields
Open

sogav21 wants to merge 1 commit into
LuaLS:masterfrom
sogav21:codex/issue-3443-inherited-generic-table-fields

Conversation

@sogav21

@sogav21 sogav21 commented Nov 11, 2026

Copy link
Copy Markdown

Fields inherited from a generic class backed by an anonymous table now retain their resolved types. For example, a subclass of GenericSuper<string> with a { value: T } base exposes value as string instead of unknown. The change also preserves field overrides, first-base precedence and unions within a base.

Fixes #3443.

Validation

  • The issue reproduction fails on the pinned baseline and passes with the fix.
  • The full Windows test suite passed, including 19 inference cases and definition/hover regressions.
  • A JSON-RPC hover request returns (field) Specific.value: string.

Developed with AI assistance.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

中文:新增块中调用了 copyToSearched(),但请确认该函数在当前作用域已定义;同时其调用时机(在 pushResult 后)会影响搜索去重逻辑,建议核对与现有 copyToSearched 的使用模式是否一致。
English: The new block calls copyToSearched(), but please confirm this function is defined in the current scope; also its call timing (after pushResult) affects search dedup logic—verify it matches the existing usage pattern of copyToSearched.

中文:vm.compileNode(extend):eachObject() 在遍历基类(可能是递归/循环继承链)时会重复编译并遍历对象;测试中包含 Recursive: Recursive 和互相继承的用例,建议确认无无限递归或性能回退风险。
English: vm.compileNode(extend):eachObject() will recompile and iterate objects when traversing base classes (possibly recursive/circular inheritance chains); tests include Recursive: Recursive and mutual inheritance cases—confirm there is no infinite recursion or performance regression risk.

中文:仅对 extend.type == 'doc.extends.name' 或 'doc.type.sign' 处理匿名表基类,其他 extends 节点类型(如 doc.extends.generic 等)是否也应覆盖?请确认此过滤条件与现有继承解析路径一致。
English: Anonymous table bases are only handled for extend.type == 'doc.extends.name' or 'doc.type.sign'; should other extends node types (e.g. doc.extends.generic) also be covered? Confirm this filter matches existing inheritance resolution paths.

中文:hasTable 逻辑中,copyToSearched() 在首次发现 table 时调用一次,循环结束后若 hasTable 为真又调用一次;请确认这两次调用的语义差异是否必要,避免重复或遗漏去重。
English: In the hasTable logic, copyToSearched() is called once when the first table is found, and again after the loop if hasTable is true; confirm whether the semantic difference of these two calls is necessary to avoid duplication or missing dedup.

中文:searchedFields 与 hasFounded 的更新顺序:在 pushResult 之前设置 hasFounded[fieldKey] = true,若 pushResult 因条件失败会留下错误标记,建议核对与已有分支的一致性。
English: Order of updating searchedFields/hasFounded: hasFounded[fieldKey] = true is set before pushResult; if pushResult fails its condition, an incorrect mark remains—verify consistency with existing branches.

中文:新增测试文件 test/type_inference/inherited_table_fields.lua 已通过 require 引入,但用例中多处重复覆盖相同语义(如 string 结果重复),建议精简以降低维护成本。
English: The new test file test/type_inference/inherited_table_fields.lua is loaded via require, but several cases duplicate the same semantics (e.g. repeated string results); consider trimming to reduce maintenance cost.

中文:变更日志条目格式与现有 * \FIX` ...一致,无误。 English: The changelog entry format matches the existing* `FIX` ...` style; no issue.

@sogav21

sogav21 commented Nov 11, 2026

Copy link
Copy Markdown
Author

Verified these points on d2d307e. copyToSearched is the existing local closure in searchClass. The two calls preserve previously found fields and then commit the current base's fields after all of its table alternatives have been visited. The union and first-base-precedence regressions check those boundaries.

compileNode caches a node before recursive compilation, and named inheritance uses the existing per-search guard. The self-cycle and mutual-cycle tests pass. The parser uses doc.extends.name and doc.type.sign for named bases. Marking a field before pushResult follows the existing parameterized-base branch, where the callback has no success-return contract.

The equal expected type strings cover different generic arguments, indexed fields, sibling instantiations, inheritance depth and overrides. All 19 inference cases, hover/definition regressions, the full Windows suite and a stdio LSP hover passed. The inference suite was also rerun on this published commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inheriting from a generic class, which uses an annotated table definition causes fields to get lost

1 participant