Skip to content

Generic type variable is not solved when the @param type is a union (generic<A>, nil) #1298

Description

@apiology

Claude: Written by Claude and posted using @apiology's GitHub credentials, while auditing @sg-ignore usage in a downstream project.

When a @param type is a union containing generic<A>, A isn't solved against the union — it appears to bind to the whole argument type, so the return stays a union and every downstream call fails. sorbet-runtime's T.must is this exact shape. The trigger is the union, not nil@param arg [generic<A>, Integer] fails the same way, while a bare @param arg [generic<A>] binds correctly.

# @generic A
# @param arg [generic<A>, nil]
# @return [generic<A>]
def must_nilable(arg)
  raise if arg.nil?

  arg
end

# @param arg [String, nil]
# @return [Integer]
def via_nilable(arg) = must_nilable(arg).length
$ solargraph typecheck --level strong repro.rb
repro.rb:7: Declared return type generic<A> does not match inferred type generic<A>, nil for #must_nilable
repro.rb:15: #via_nilable return type could not be inferred
repro.rb:15: Unresolved call to length on String, nil
3 problems found.

Expected 0 problems. The two line-15 errors are this bug. The line-7 error is #1276 (raise doesn't narrow), not this — an identical helper with no generics at all (@param arg [String, nil] / @return [String]) produces the same complaint, so it's independent.

Possibly the argument-side counterpart of #1272; not fixed by #1273.

Environment: castwide/solargraph master 8fda63384, rbs 4.0.3, Ruby 3.3.12.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions