Skip to content

Commit 2e0198c

Browse files
committed
Merge castwide#1228: allow arguments to satisfy RBS interface-typed parameters
castwide#1228 fixes the same underlying bug as the already-merged castwide#1266 (issue castwide#1227: RBS 4.1's Hash#fetch takes its key as the Hash::_Key duck-type interface instead of a generic, causing Solargraph to fall back to the unresolved generic<X> from the block-form overload) but via a different, earlier mechanism: a blanket :allow_unmatched_interface bypass in Pin::Parameter#compatible_arg?, rather than castwide#1266's later structural Conformance check. Verified castwide#1228's own regression test already passes unmodified on this branch without its compatible_arg? change (isolated it into a standalone spec file and ran it against HEAD before resolving the conflict) - castwide#1266's structural interface verification already covers this case, making castwide#1228's code change redundant here. Kept HEAD's compatible_arg? as-is (including literal_arg_matches?, from an earlier-merged PR that castwide#1228's branch, based directly on castwide/master, never saw) and dropped castwide#1228's interface-bypass hunk entirely. Conflict in spec/type_checker/levels/strong_spec.rb: kept castwide#1228's new regression test (issue castwide#1227) as a sibling of HEAD's intersection-type test block (from castwide#1231), which castwide#1228's branch also never saw. .github/workflows/rspec.yml auto-merged cleanly, taking castwide#1228's RBS matrix bump (4.0.0/4.0.1/4.0.2 -> 3.10.0/4.0.3/4.1.1) - core to what this PR is actually testing (RBS 4.1's Hash#fetch signature change). Verified: spec/type_checker/levels/strong_spec.rb, spec/pin/parameter_spec.rb (104 examples, 0 failures, 5 pending), and a broader safety net - spec/type_checker, spec/source, spec/source_map/clip_spec.rb, spec/complex_type, spec/complex_type_spec.rb (807 examples, 0 failures, 35 pending) - all passing locally.
2 parents 0cb1a0e + 20511d9 commit 2e0198c

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

.github/workflows/rspec.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ jobs:
2525
# It currently 404s ("Unavailable version head for ruby"), failing CI:
2626
# https://github.com/castwide/solargraph/actions/runs/25863741955/job/76000137015?pr=1187
2727
ruby-version: ['3.1', '3.2', '3.3', '3.4', '4.0']
28-
rbs-version: ['3.10.0', '4.0.0', '4.0.1', '4.0.2']
28+
rbs-version: ['3.10.0', '4.0.3', '4.1.1']
2929
exclude:
3030
- ruby-version: '3.1'
31-
rbs-version: '4.0.0'
31+
rbs-version: '4.0.3'
3232
- ruby-version: '3.1'
33-
rbs-version: '4.0.1'
34-
- ruby-version: '3.1'
35-
rbs-version: '4.0.2'
33+
rbs-version: '4.1.1'
3634
steps:
3735
- uses: actions/checkout@v3
3836
- name: Set up Ruby

spec/type_checker/levels/strong_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,5 +1291,35 @@ def make
12911291
expect(checker.problems.map(&:message)).to be_empty
12921292
end
12931293
end
1294+
1295+
it 'resolves Hash#fetch return type on Hash{Symbol => Class<X>} without leaking a generic placeholder' do
1296+
# https://github.com/castwide/solargraph/issues/1227
1297+
#
1298+
# As of RBS 4.1.0, Hash#fetch's single-argument overload takes
1299+
# its key as the ::Hash::_Key duck-type interface instead of the
1300+
# generic K (see ruby/rbs core/hash.rbs). Solargraph couldn't
1301+
# prove a Symbol argument satisfies that interface, so it fell
1302+
# back to merging the return types of all of Hash#fetch's
1303+
# overloads (including the unresolved block-form's `generic<X>`)
1304+
# instead of picking the single-argument overload.
1305+
checker = type_checker(%(
1306+
class Foo; end
1307+
1308+
class Holder
1309+
# @return [Hash{Symbol => Class<Foo>}]
1310+
def registry
1311+
{ x: Foo }
1312+
end
1313+
1314+
# @return [Foo]
1315+
def use_it
1316+
# @type [Class<Foo>]
1317+
clazz = registry.fetch(:x)
1318+
clazz.new
1319+
end
1320+
end
1321+
))
1322+
expect(checker.problems.map(&:message)).to eq([])
1323+
end
12941324
end
12951325
end

0 commit comments

Comments
 (0)