Repository navigation
fix(resolve): infer expression-body method returns; keep generic receivers typed through field/method hops - #330
Merged
Conversation
…ivers typed through field/method hops Three linked gaps behind Moneta's `getTexts().title` / `loadScreenData(..).text.scenes` Gaps: - find_method_return_type read only a declared `: Type`, so `fun f() = <expr>` had no return type and callers fell through to a bare-name scan that picked an arbitrary same-named function (a silent wrong target, not just a Gap). The type is now inferred from the expression body behind the existing resolution-cycle guard. - cst_symbol's known-type gate looked the WHOLE inferred string up as a type name, so any generic call-result receiver (`Box<out Texts>`) lost its receiver_type. It now gates on, and records, the type's own name. - infer_navigation_expr_type returned a field's/method's raw declared type (`T`) without substituting the receiver's type arguments, and build_type_arg_subst kept `out`/`in` projections. Field and method hops now share resolve_field_type_on / resolve_method_return_type_on with the chain strategies; StrExt::strip_variance is the one canonical projection strip. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Generic method lookup, projection semantics, qualified-type validation, and implicit Unit returns can currently produce incorrect resolution.
Review effort: Balanced
Findings: 1
Open (5)
What changed in this PR
Adds expression-body return inference and preserves generic receiver typing through member chains.
Changes:
- Infers undeclared expression-body method return types with cycle protection.
- Adds variance stripping and generic type substitution across field/method hops.
- Retains normalized receiver types during CST symbol classification.
| File | Description |
|---|---|
src/str_ext.rs |
Adds variance projection stripping. |
src/str_ext_tests.rs |
Tests variance stripping. |
src/resolver/infer.rs |
Infers expression-body returns. |
src/resolver/infer_tests.rs |
Tests inference and cycles. |
src/indexer/node_ext.rs |
Reuses variance normalization. |
src/indexer/infer/type_subst.rs |
Normalizes projected type arguments. |
src/indexer/infer/expr_type.rs |
Applies generic-aware member resolution. |
src/indexer/infer/cst_symbol.rs |
Normalizes classified receiver types. |
src/indexer/infer/cst_symbol_tests.rs |
Tests generic receiver chains. |
src/indexer/infer/chain.rs |
Shares substituted field/method resolution. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ype gate, Unit returns, lookup key) - in/star projections bind nothing; out reads as its type (build_type_arg_subst, first_type_arg_raw share readable_type_argument) - the known-type gate validates a qualified path as a whole (resolve_type_path_declarations), not by its leaf - a Kotlin fn with a block body or no body and no declared type returns Unit - the call branch of infer_navigation_expr_type looks the method up by class name Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Problem
Moneta's
getTexts().titleandloadScreenData(..).text.sceneschains missed. Three linked gaps:find_method_return_typeread only a declared: Type, sofun f() = <expr>had no return type. Callers fell through to a bare-name scan that picked an arbitrary same-named function (149getTextsin the corpus) — a silent wrong target, not just a Gap. The type is now inferred from the expression body behind the existing resolution-cycle guard.cst_symbol's known-type gate looked the whole inferred string up as a type name, so any generic call-result receiver (Box<out Texts>) lost itsreceiver_type. It now gates on, and records, the type's own name.infer_navigation_expr_typereturned a member's raw declared type (T) without substituting the receiver's type arguments, andbuild_type_arg_substkeptout/inprojections. Field and method hops now shareresolve_field_type_on/resolve_method_return_type_onwith the chain strategies;StrExt::strip_varianceis the one canonical projection strip.Tests (each red before the fix)
method_return_type_is_inferred_from_an_expression_body(with a decoygetTexts)expression_body_return_inference_terminates_on_a_self_referential_methodgeneric_call_result_receiver_keeps_its_base_type_as_receiver_typeproperty_of_a_type_parameter_resolves_to_the_receivers_type_argumentstrip_variance_removes_only_a_leading_projectioncargo test(2019),clippy -D warnings,fmtcleanMeasurement (Moneta,
resolution-accuracy, 13,325 files)Member recall flat at 92.0%, but absolute resolved +14.5k (746.9k → 761.4k); member refs 166k → 209k because many references now carry a receiver type (previously untyped → counted as bare/NameScan).
text/title/scenesGaps stay high for that reason plus a separate root cause (the inferred receiver type loses its origin file) being fixed in the follow-up stack — see the design indocs/superpowers/specs/2026-08-24-qualified-resolution-unification-design.md(deferreddeclaring_urinote).Does not fix: bare-name collisions on inferred receiver types,
TfromfirstOrNull,TransformedText.🤖 Generated with Claude Code