Open Morriar opened 5 years ago
There are 3 places in definition_validator where we check whether a method was defined in a DSL, and skip some checks if so:
The reasoning for this IIRC was because it made some things easier to roll out internally, and also because for some DSL-synthesized methods (like T::Struct props) there's no syntax to specify override
when it's required (because a parent method had abstract
).
Unfortunately that skips out on a lot of good checks that we should probably be doing.
@aisamanra can you chime in? do you have more context than I do here?
Input
See classes
Error1
,Error2
, andError3
.→ View on sorbet.run%7D%20%23%20WRONG%3A%20Should%20error%2C%20as%20nilable%20Object%20is%20not%20covariant%20with%20A%0A%20%20attr_reader%20%3Aa%0A%0A%20%20sig%20%7B%20void%20%7D%0A%20%20def%20initialize%0A%20%20%20%20%40a%20%3D%20T.let(nil%2C%20T.nilable(Object))%0A%20%20end%0Aend%0A%0Aclass%20Error3%20%3C%20Foo%0A%20%20extend%20T%3A%3ASig%0A%0A%20%20sig%20%7B%20override.returns(T.nilable(B))%7D%20%23%20WRONG%3A%20Should%20error%2C%20as%20nilable%20B%20is%20not%20covariant%20with%20A%0A%20%20attr_reader%20%3Aa%0A%0A%20%20sig%20%7B%20void%20%7D%0A%20%20def%20initialize%0A%20%20%20%20%40a%20%3D%20T.let(nil%2C%20T.nilable(B))%0A%20%20end%0Aend%0A%0A%23%20The%20following%20tests%20should%20still%20work%20once%20fixed%3A%0A%0Aclass%20Ok1%20%3C%20Foo%0A%20%20extend%20T%3A%3ASig%0A%0A%20%20sig%20%7B%20override.returns(B)%7D%20%23%20Ok%2C%20covariance%0A%20%20attr_reader%20%3Aa%0A%0A%20%20sig%20%7B%20params(b%3A%20B).void%20%7D%0A%20%20def%20initialize(b)%0A%20%20%20%20%40a%20%3D%20T.let(b%2C%20B)%0A%20%20end%0Aend%0A%0Aclass%20Ok2%20%3C%20Foo%0A%20%20extend%20T%3A%3ASig%0A%0A%20%20sig%20%7B%20override.returns(B)%7D%20%23%20Ok%0A%20%20def%20a%0A%20%20%20%20B.new%0A%20%20end%0Aend%0A%0A%23%20This%20already%20work%20well%20with%20concrete%20methods%3A%0A%0Aclass%20Ok3%20%3C%20Foo%0A%20%20extend%20T%3A%3ASig%0A%0A%20%20sig%20%7B%20override.returns(T.nilable(B))%7D%20%23%20Ok%3A%20errors%20as%20it%20should%0A%20%20def%20a%0A%20%20%20%20B.new%0A%20%20end%0Aend%0A%0Aclass%20Ok4%20%3C%20Foo%0A%20%20extend%20T%3A%3ASig%0A%0A%20%20sig%20%7B%20override.returns(Object)%7D%20%23%20Ok%3A%20errors%20as%20it%20should%0A%20%20def%20a%0A%20%20%20%20B.new%0A%20%20end%0Aend%0A%0Aclass%20Ok5%20%3C%20Foo%0A%20%20extend%20T%3A%3ASig%0A%0A%20%20sig%20%7B%20override.returns(Unrelated)%7D%20%23%20Ok%3A%20errors%20as%20it%20should%0A%20%20def%20a%0A%20%20%20%20Unrelated.new%0A%20%20end%0Aend)
Observed output
Only the error from classes
OkX
are found by the static checker:Expected behavior
I would expect Sorbet to catch the bad redefinitions for the return type of
attr_reader :a
in Error 1, 2, and 3.This works correctly with the runtime checker.