Skip to content

Type block parameters of map.with_index - #354

Closed
apiology wants to merge 1 commit into
masterfrom
type-with-index-block-params
Closed

apiology wants to merge 1 commit into
masterfrom
type-with-index-block-params

Conversation

@apiology

Copy link
Copy Markdown
Owner

Claude: This PR was written by Claude Code on behalf of @apiology.

Problem: Block parameters of map.with_index lose their types:

# @param items [Array<Integer>]
# @return [Array<Integer>]
# Declared return type ::Array<::Integer> does not match inferred type ::Enumerator<::Array(::Integer, ::Array, ::Integer), undefined> for #doubled
def doubled items
  # Unresolved call to *
  items.map.with_index { |item, _idx| item * 2 }
end

Every receiver whose class declares two or more generics, such as core RBS's Enumerator[Elem, Return], has lost them since castwide/solargraph#1201; names.each_with_index.map { |pair| } types pair as Array(String, Integer), Array<String>.

Solution: Bind a multi-generic receiver's declared parameters by position again, keeping castwide#1201's union binding for Array<A, B> and tuple receivers, so every type comes from a declaration and Chain::Literal, Chain::Array, literal? and tuple? stay untouched.

Not covered: destructuring that tuple into |name, idx| also needs tuple? re-enabled, which apiology/solargraph#341 does.

Since castwide#1201, resolve_generics bound a class's first generic to the
union of every receiver parameter and all later generics to undefined.
That is right for Array<A, B> and tuple receivers, which castwide#1201 treats
as parameterized arrays, but wrong for classes declaring several
generics. Enumerator[Elem, Return] lost Return and got Elem bound to
Elem | Return, so the blocks of map.with_index and each_with_index.map
received no usable element type.

Keep the union for implicit-union and fixed-parameter receivers, and
bind other receivers' declared generics by position again, falling
back to the RBS generic default.
@apiology

Copy link
Copy Markdown
Owner Author

Claude: Closing as a duplicate of castwide/solargraph#1415, Resolve every generic parameter, not only the first. On its head, map.with_index block parameters and result are typed, and each_with_index.map { |pair| } types pair as Array(String, Integer). This PR's with_index specs and its tuple-receiver spec now live there.

@apiology apiology closed this Oct 27, 2026
apiology added a commit that referenced this pull request Oct 27, 2026
Cover the block parameters and result of map.with_index, the pair
yielded by each_with_index.map, and a tuple receiver of a
single-generic class, which positional binding must leave as a union.
Carried over from #354, which this PR supersedes.
apiology added a commit that referenced this pull request Oct 27, 2026
#354 is closing as a duplicate of
castwide#1415, which also clears this finding.
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.

1 participant