タイミーでバックエンドのテックリードをしている新谷(@euglena1215)です。
タイミーでは RBS の活用を推進する取り組みを少しずつ進めています。意図はこちら
メンバーと雑談していたときに「steep check でコケたときにその名前で調べても全然ヒットしないので型周りのキャッチアップが難しい」という話を聞きました。
いくつかのエラー名でググってみたところ、 Ruby::ArgumentTypeMismatch
や Ruby::NoMethod
など有名なエラーはヒットしますがほとんどのエラーはヒットせず、ヒットするのは Steep リポジトリの該当実装のみでした。
これでは確かにキャッチアップは難しいだろうと感じたので、Steep のエラーリファレンスを作ってみました。ググってヒットするのが目的なのでテックブログとして公開してインデックスされることを期待します。
各エラーの説明は以下のフォーマットで行います。
エラー名
説明: 簡単なエラーの説明
例:
エラーが検出される Ruby コード
steep check を実行して得られるエラーメッセージ
severity:
Steep のエラープリセットに対して、該当エラーの severity がどのように設定されているかの表
Ruby::ArgumentTypeMismatch
説明: メソッドの型が一致しない場合に発生します。
違反例:
'1' + 1
test.rb:1:6: [error] Cannot pass a value of type `::Integer` as an argument of type `::string` │ ::Integer <: ::string │ ::Integer <: (::String | ::_ToStr) │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::ArgumentTypeMismatch │ └ '1' + 1 ~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::BlockBodyTypeMismatch
説明: ブロックの body の返り値の型が期待される型と一致しない場合に発生します。
違反例:
lambda {|x| x + 1 } #: ^(Integer) -> String
test.rb:1:7: [error] Cannot allow block body have type `::Integer` because declared as type `::String` │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::BlockBodyTypeMismatch │ └ lambda {|x| x + 1 } #: ^(Integer) -> String ~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | information | nil |
Ruby::BlockTypeMismatch
説明: ブロックの型が期待される型と一致しない場合に発生します。
違反例:
multi = ->(x, y) { x * y } #: ^(Integer, Integer) -> Integer [1, 2, 3].map(&multi)
test.rb:2:14: [error] Cannot pass a value of type `^(::Integer, ::Integer) -> ::Integer` as a block-pass-argument of type `^(::Integer) -> U(1)` │ ^(::Integer, ::Integer) -> ::Integer <: ^(::Integer) -> U(1) │ (Params are incompatible) │ │ Diagnostic ID: Ruby::BlockTypeMismatch │ └ [1, 2, 3].map(&multi) ~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | information | nil |
Ruby::BreakTypeMismatch
説明: break
の型が期待される型と一致しない場合に発生します。
違反例:
123.tap { break "" }
test.rb:1:10: [error] Cannot break with a value of type `::String` because type `::Integer` is assumed │ ::String <: ::Integer │ ::Object <: ::Integer │ ::BasicObject <: ::Integer │ │ Diagnostic ID: Ruby::BreakTypeMismatch │ └ 123.tap { break "" } ~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | hint | nil |
Ruby::DifferentMethodParameterKind
説明: メソッドのパラメータの種類が一致しない場合に発生します。省略可能な引数の prefix に ?
をつけ忘れることで発生することが多いです。
違反例:
# @type method bar: (name: String) -> void def bar(name: "foo") end
test.rb:2:8: [error] The method parameter has different kind from the declaration `(name: ::String) -> void` │ Diagnostic ID: Ruby::DifferentMethodParameterKind │ └ def bar(name: "foo") ~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::FallbackAny
説明: 型が不明な場合に untyped
が使用されることを示します。一度 []
で値を初期化したのちに再代入するような実装で発生することが多いです。
違反例:
a = []
a << 1
test.rb:1:4: [error] Cannot detect the type of the expression │ Diagnostic ID: Ruby::FallbackAny │ └ a = [] ~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | warning | nil | nil |
Ruby::FalseAssertion
説明: Steep の型アサーションが誤っている場合に発生します。
違反例:
array = [] #: Array[Integer] hash = array #: Hash[Symbol, String]
test.rb:2:7: [error] Assertion cannot hold: no relationship between inferred type (`::Array[::Integer]`) and asserted type (`::Hash[::Symbol, ::String]`) │ Diagnostic ID: Ruby::FalseAssertion │ └ hash = array #: Hash[Symbol, String] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::ImplicitBreakValueMismatch
説明: 引数無し break
の値( nil
)がメソッドの返り値の期待される型と一致しない場合に発生します。
違反例:
class Foo # @rbs () { (String) -> Integer } -> String def foo '' end end Foo.new.foo do |x| break end
test.rb:9:2: [error] Breaking without a value may result an error because a value of type `::String` is expected │ nil <: ::String │ │ Diagnostic ID: Ruby::ImplicitBreakValueMismatch │ └ break ~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | information | nil | nil |
Ruby::IncompatibleAnnotation
説明: 型注釈が不適切または一致しない場合に発生します。
違反例:
a = [1,2,3] if _ = 1 # @type var a: String a + "" end
test.rb:5:2: [error] Type annotation about `a` is incompatible since ::String <: ::Array[::Integer] doesn't hold │ ::String <: ::Array[::Integer] │ ::Object <: ::Array[::Integer] │ ::BasicObject <: ::Array[::Integer] │ │ Diagnostic ID: Ruby::IncompatibleAnnotation │ └ a + "" ~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::IncompatibleArgumentForwarding
説明: 引数に ...
を使ってメソッドの引数を forward する際に、引数の型が一致しない場合に発生します。
違反例:
class Foo # @rbs (*Integer) -> void def foo(*args) end # @rbs (*String) -> void def bar(...) foo(...) end end
test.rb:8:8: [error] Cannot forward arguments to `foo`: │ (*::Integer) <: (*::String) │ ::String <: ::Integer │ ::Object <: ::Integer │ │ Diagnostic ID: Ruby::IncompatibleArgumentForwarding │ └ foo(...) ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | information | nil |
Ruby::IncompatibleAssignment
説明: 代入の際の型が不適切または一致しない場合に発生します。
違反例:
# @type var x: Integer x = "string"
test.rb:2:0: [error] Cannot assign a value of type `::String` to a variable of type `::Integer` │ ::String <: ::Integer │ ::Object <: ::Integer │ ::BasicObject <: ::Integer │ │ Diagnostic ID: Ruby::IncompatibleAssignment │ └ x = "string" ~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | hint | nil |
Ruby::InsufficientKeywordArguments
説明: キーワード引数が不足している場合に発生します。
違反例:
class Foo def foo(a:, b:) end end Foo.new.foo(a: 1)
test.rb:5:8: [error] More keyword arguments are required: b │ Diagnostic ID: Ruby::InsufficientKeywordArguments │ └ Foo.new.foo(a: 1) ~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::InsufficientPositionalArguments
説明: 位置引数が不足している場合に発生します。
違反例:
class Foo def foo(a, b) end end Foo.new.foo(1)
test.rb:5:8: [error] More keyword arguments are required: b │ Diagnostic ID: Ruby::InsufficientKeywordArguments │ └ Foo.new.foo(a: 1) ~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::InsufficientTypeArgument
説明: 型引数に対する型注釈が不足している場合に発生します。
違反例:
class Foo # @rbs [T, S] (T, S) -> [T, S] def foo(x, y) [x, y] end end Foo.new.foo(1, 2) #$ Integer
test.rb:8:0: [error] Requires 2 types, but 1 given: `[T, S] (T, S) -> [T, S]` │ Diagnostic ID: Ruby::InsufficientTypeArgument │ └ Foo.new.foo(1, 2) #$ Integer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::InvalidIgnoreComment
説明: steep:ignore:start
コメントはあるが steep:ignore:end
コメントがないなど、無効なコメントが存在する場合に発生します。
違反例:
# steep:ignore:start
test.rb:1:0: [error] Invalid ignore comment │ Diagnostic ID: Ruby::InvalidIgnoreComment │ └ # steep:ignore:start ~~~~~~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | warning | warning | nil |
Ruby::MethodArityMismatch
説明: キーワード引数なのに順序引数としてメソッドの引数の型を記述しているなど、メソッドの引数の型が一致しない場合に発生します。
違反例:
class Foo # @rbs (Integer x) -> Integer def foo(x:) x end end
test.rb:3:9: [error] Method parameters are incompatible with declaration `(::Integer) -> ::Integer` │ Diagnostic ID: Ruby::MethodArityMismatch │ └ def foo(x:) ~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::MethodBodyTypeMismatch
説明: メソッドの返り値が期待される型と一致しない場合に発生します。
違反例:
class Foo # @rbs () -> String def foo 1 end end
test.rb:3:6: [error] Cannot allow method body have type `::Integer` because declared as type `::String` │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::MethodBodyTypeMismatch │ └ def foo ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | warning | nil |
Ruby::MethodDefinitionMissing
説明: メソッドの型定義が存在するがメソッドの実装が欠落している場合に発生します。
違反例:
class Foo # @rbs! # def bar: () -> void end
test.rb:1:6: [error] Cannot find implementation of method `::Foo#bar` │ Diagnostic ID: Ruby::MethodDefinitionMissing │ └ class Foo ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | nil | hint | nil | nil |
Ruby::MethodParameterMismatch
説明: メソッドのパラメータの型が一致しない場合に発生します。
違反例:
class Foo # @rbs (Integer x) -> Integer def foo(x:) x end end
test.rb:3:10: [error] The method parameter is incompatible with the declaration `(::Integer) -> ::Integer` │ Diagnostic ID: Ruby::MethodParameterMismatch │ └ def foo(x:) ~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | warning | nil |
Ruby::MethodReturnTypeAnnotationMismatch
説明: メソッドの戻り値の型注釈が期待される型と一致しない場合に発生します。
違反例:
class Foo # @rbs () -> String def foo # @type return: Integer 123 end end
test.rb:3:2: [error] Annotation `@type return` specifies type `::Integer` where declared as type `::String` │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::MethodReturnTypeAnnotationMismatch │ └ def foo ~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::MultipleAssignmentConversionError
説明: 複数代入の変換に失敗した場合に発生します。
違反例:
class WithToAry # @rbs () -> Integer def to_ary 1 end end a, b = WithToAry.new()
test.rb:8:8: [error] Cannot convert `::WithToAry` to Array or tuple (`#to_ary` returns `::Integer`) │ Diagnostic ID: Ruby::MultipleAssignmentConversionError │ └ (a, b = WithToAry.new()) ~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::NoMethod
説明: 型定義が存在しないメソッドが呼び出された場合に発生します。
違反例:
"".non_existent_method
test.rb:1:3: [error] Type `::String` does not have method `non_existent_method` │ Diagnostic ID: Ruby::NoMethod │ └ "".non_existent_method ~~~~~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::ProcHintIgnored
説明: Proc
に関する型注釈が無視された場合に発生します。
違反例:
# @type var proc: (^(::Integer) -> ::String) | (^(::String, ::String) -> ::Integer) proc = -> (x) { x.to_s }
test.rb:2:7: [error] The type hint given to the block is ignored: `(^(::Integer) -> ::String | ^(::String, ::String) -> ::Integer)` │ Diagnostic ID: Ruby::ProcHintIgnored │ └ proc = -> (x) { x.to_s } ~~~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | information | nil | nil |
Ruby::ProcTypeExpected
説明: Proc
型が期待される場合に発生します。
違反例:
-> (&block) do # @type var block: Integer end
test.rb:1:4: [error] Proc type is expected but `::Integer` is specified │ Diagnostic ID: Ruby::ProcTypeExpected │ └ -> (&block) do ~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::RBSError
説明: 型アサーションや型適用に書かれたRBS型がエラーを生じる場合に発生します。
違反例:
a = 1 #: Int
test.rb:1:9: [error] Cannot find type `::Int` │ Diagnostic ID: Ruby::RBSError │ └ a = 1 #: Int ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | information | error | information | nil |
Ruby::RequiredBlockMissing
説明: メソッド呼び出し時に必要な block が欠落している場合に発生します。
違反例:
class Foo # @rbs () { () -> void } -> void def foo yield end end Foo.new.foo
test.rb:7:8: [error] The method cannot be called without a block │ Diagnostic ID: Ruby::RequiredBlockMissing │ └ Foo.new.foo ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | hint | nil |
Ruby::ReturnTypeMismatch
説明: return
の型とメソッドの戻り値の型が一致しない場合に発生します。
違反例:
# @type method foo: () -> Integer def foo return "string" end
test.rb:3:2: [error] The method cannot return a value of type `::String` because declared as type `::Integer` │ ::String <: ::Integer │ ::Object <: ::Integer │ ::BasicObject <: ::Integer │ │ Diagnostic ID: Ruby::ReturnTypeMismatch │ └ return "string" ~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | warning | nil |
Ruby::SetterBodyTypeMismatch
説明: セッターメソッドの戻り値の型が期待される型と一致しない場合に発生します。
違反例:
class Foo # @rbs (String) -> String def foo=(value) 123 end end
test.rb:3:6: [error] Setter method `foo=` cannot have type `::Integer` because declared as type `::String` │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::SetterBodyTypeMismatch │ └ def foo=(value) ~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | information | error | nil | nil |
Ruby::SetterReturnTypeMismatch
説明: セッターメソッドの return
の型が期待される型と一致しない場合に発生します。
違反例:
class Foo # @rbs (String) -> String def foo=(value) return 123 end end
test.rb:4:4: [error] The setter method `foo=` cannot return a value of type `::Integer` because declared as type `::String` │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::SetterReturnTypeMismatch │ └ return 123 ~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | information | error | nil | nil |
Ruby::SyntaxError
説明: Ruby の構文エラーが発生した場合に発生します。
違反例:
if x == 1 puts "Hello"
test.rb:2:14: [error] SyntaxError: unexpected token $end │ Diagnostic ID: Ruby::SyntaxError │ └ puts "Hello"
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | hint | hint | nil |
Ruby::TypeArgumentMismatchError
説明: 型引数が期待される型と一致しない場合に発生します。
違反例:
class Foo # @rbs [T < Numeric] (T) -> T def foo(x) x end end Foo.new.foo("") #$ String
test.rb:7:19: [error] Cannot pass a type `::String` as a type parameter `T < ::Numeric` │ ::String <: ::Numeric │ ::Object <: ::Numeric │ ::BasicObject <: ::Numeric │ │ Diagnostic ID: Ruby::TypeArgumentMismatchError │ └ Foo.new.foo("") #$ String ~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::UnexpectedBlockGiven
説明: ブロックが予期されない場面で渡された場合に発生します。
違反例:
[1].at(1) { 123 }
test.rb:1:10: [error] The method cannot be called with a block │ Diagnostic ID: Ruby::UnexpectedBlockGiven │ └ [1].at(1) { 123 } ~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | hint | nil |
Ruby::UnexpectedDynamicMethod
説明: 動的に定義されたメソッドが存在しない場合に発生します。
違反例:
class Foo # @dynamic foo def bar end end
test.rb:1:6: [error] @dynamic annotation contains unknown method name `foo` │ Diagnostic ID: Ruby::UnexpectedDynamicMethod │ └ class Foo ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | information | nil | nil |
Ruby::UnexpectedError
説明: 予期しない一般的なエラーが発生した場合に発生します。
違反例:
class Foo # @rbs () -> String123 def foo end end
test.rb:1:0: [error] UnexpectedError: sig/generated/test.rbs:5:17...5:26: Could not find String123(RBS::NoTypeFoundError) │ ... │ (36 more backtrace) │ │ Diagnostic ID: Ruby::UnexpectedError │ └ class Foo ~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | information | hint | nil |
Ruby::UnexpectedJump
説明: 予期しないジャンプが発生した場合に発生します。
違反例:
break
test.rb:1:0: [error] Cannot jump from here │ Diagnostic ID: Ruby::UnexpectedJump │ └ break ~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::UnexpectedJumpValue
説明: ジャンプの値を渡しても値が無視される場合に発生します。
違反例:
while true next 3 end
test.rb:2:2: [error] The value given to next will be ignored │ Diagnostic ID: Ruby::UnexpectedJumpValue │ └ next 3 ~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::UnexpectedKeywordArgument
説明: 予期しないキーワード引数が渡された場合に発生します。
違反例:
class Foo # @rbs (x: Integer) -> void def foo(x:) end end Foo.new.foo(x: 1, y: 2)
test.rb:7:18: [error] Unexpected keyword argument │ Diagnostic ID: Ruby::UnexpectedKeywordArgument │ └ Foo.new.foo(x: 1, y: 2) ~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::UnexpectedPositionalArgument
説明: 予期しない位置引数が渡された場合に発生します。
違反例:
class Foo # @rbs (Integer) -> void def foo(x) end end Foo.new.foo(1, 2)
test.rb:7:15: [error] Unexpected positional argument │ Diagnostic ID: Ruby::UnexpectedPositionalArgument │ └ Foo.new.foo(1, 2) ~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::UnexpectedSuper
説明: super
を呼び出した際に親クラスに同名のメソッドが定義されていないなど、予期しない場面で super
が使用された場合に発生します。
違反例:
class Foo def foo super end end
test.rb:3:4: [error] No superclass method `foo` defined │ Diagnostic ID: Ruby::UnexpectedSuper │ └ super ~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | information | error | nil | nil |
Ruby::UnexpectedTypeArgument
説明: 予期しない型引数が渡された場合に発生します。
違反例:
class Foo # @rbs [T] (T) -> T def foo(x) x end end Foo.new.foo(1) #$ Integer, Integer
test.rb:8:27: [error] Unexpected type arg is given to method type `[T] (T) -> T` │ Diagnostic ID: Ruby::UnexpectedTypeArgument │ └ Foo.new.foo(1) #$ Integer, Integer ~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | nil | nil |
Ruby::UnexpectedYield
説明: yield
が予期しない場面で使用された場合に発生します。
違反例:
class Foo # @rbs () -> void def foo yield end end
test.rb:4:4: [error] No block given for `yield` │ Diagnostic ID: Ruby::UnexpectedYield │ └ yield ~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | information | nil |
Ruby::UnknownConstant
説明: 未知の定数が参照された場合に発生します。
違反例:
FOO
test.rb:1:0: [error] Cannot find the declaration of constant: `FOO` │ Diagnostic ID: Ruby::UnknownConstant │ └ FOO ~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | hint | nil |
Ruby::UnknownGlobalVariable
説明: 未知のグローバル変数が参照された場合に発生します。
違反例:
$foo
test.rb:1:0: [error] Cannot find the declaration of global variable: `$foo` │ Diagnostic ID: Ruby::UnknownGlobalVariable │ └ $foo ~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | warning | error | hint | nil |
Ruby::UnknownInstanceVariable
説明: 未知のインスタンス変数が参照された場合に発生します。
違反例:
class Foo def foo @foo = 'foo' end end
test.rb:3:4: [error] Cannot find the declaration of instance variable: `@foo` │ Diagnostic ID: Ruby::UnknownInstanceVariable │ └ @foo = 'foo' ~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | information | error | hint | nil |
Ruby::UnreachableBranch
説明: if
,unless
による到達不可能な分岐が存在する場合に発生します。
違反例:
if false 1 end
test.rb:1:0: [error] The branch is unreachable │ Diagnostic ID: Ruby::UnreachableBranch │ └ if false ~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | information | hint | nil |
Ruby::UnreachableValueBranch
説明: case when
による到達不可能な分岐が存在し、分岐の型が bot
でなかった場合に発生します。
違反例:
x = 1 case x when Integer "one" when String "two" end
test.rb:5:0: [error] The branch may evaluate to a value of `::String` but unreachable │ Diagnostic ID: Ruby::UnreachableValueBranch │ └ when String ~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | warning | hint | nil |
Ruby::UnresolvedOverloading
説明: オーバーロードが行われているメソッドに対して型が解決できない場合に発生します。
違反例:
3 + "foo"
test.rb:1:0: [error] Cannot find compatible overloading of method `+` of type `::Integer` │ Method types: │ def +: (::Integer) -> ::Integer │ | (::Float) -> ::Float │ | (::Rational) -> ::Rational │ | (::Complex) -> ::Complex │ │ Diagnostic ID: Ruby::UnresolvedOverloading │ └ 3 + "foo" ~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | error | error | information | nil |
Ruby::UnsatisfiableConstraint
説明: RBSと型注釈の辻褄が合わないなど、どうやっても型制約が満たされない場合に発生します。
違反例:
class Foo # @rbs [A, B] (A) { (A) -> void } -> B def foo(x) end end test = Foo.new test.foo(1) do |x| # @type var x: String end
test.rb:9:0: [error] Unsatisfiable constraint `::Integer <: A(1) <: ::String` is generated through (A(1)) { (A(1)) -> void } -> B(2) │ ::Integer <: ::String │ ::Numeric <: ::String │ ::Object <: ::String │ ::BasicObject <: ::String │ │ Diagnostic ID: Ruby::UnsatisfiableConstraint │ └ test.foo(1) do |x| ~~~~~~~~~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | error | hint | nil |
Ruby::UnsupportedSyntax
説明: Steep としてサポートされていない構文が使用された場合に発生します。
違反例:
(_ = []).[]=(*(_ = nil))
test.rb:1:13: [error] Unsupported splat node occurrence │ Diagnostic ID: Ruby::UnsupportedSyntax │ └ (_ = []).[]=(*(_ = nil)) ~~~~~~~~~~
severity:
all_error | default | strict | lenient | silent |
---|---|---|---|---|
error | hint | information | hint | nil |
狙ったエラーを引き起こすというのは今年の RubyKaigi であった Ruby "enbugging" Quiz に近い感覚でした。難しい。
基本的には Steep リポジトリにあるテストケースを見ながら埋めていったんですが、中にはテストケースがないものもあったので soutaro さんに直接質問をしながら進めていきました。
また、副産物として Steep で使われなくなったが定義として残っているルールを発見し、削除する patch を作れたのも個人的には良かったです。