steep 1.5.0.pre.4 → 1.5.0.pre.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +1 -1
- data/lib/steep/ast/types/factory.rb +1 -1
- data/lib/steep/diagnostic/ruby.rb +17 -1
- data/lib/steep/type_construction.rb +78 -25
- data/lib/steep/type_inference/context.rb +3 -1
- data/lib/steep/version.rb +1 -1
- data/sig/shims/parser/nodes.rbs +5 -0
- data/sig/steep/diagnostic/ruby.rbs +25 -0
- data/smoke/diagnostics/test_expectations.yml +0 -12
- data/smoke/type_case/test_expectations.yml +6 -6
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ed79428764aa83fbd2e7f3c5a8e52ff863b4e65bef05aae43ba9ca4b7c9d2f4e
         | 
| 4 | 
            +
              data.tar.gz: be79772ce19f152e3048ae565802640cae96f1bfca98adf60eab47a28ab3ccad
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: aa071be8eaf425a2a36ffed4c8d0a97446997f9cbf85c9dc4190b5bf26c9bf5f66c7106ab27b96378d05e246a6327689ef491dedbd16ad7cb9eb8d8079b3818d
         | 
| 7 | 
            +
              data.tar.gz: d7f842d51c84a2f48bdfd79a07de3e6265dd746497aa9661871f12b062832c2a24f46b37ce1ddb614ac5ba1c65f4c408e9e1eafec27fd69d7158514fe77e0fec
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,13 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            ## master
         | 
| 4 4 |  | 
| 5 | 
            +
            ## 1.5.0.pre.5 (2023-07-07)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ### Type checker core
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * Unreachability improvements ([#845](https://github.com/soutaro/steep/pull/845))
         | 
| 10 | 
            +
            * Fix type inference problem ([#843](https://github.com/soutaro/steep/pull/843))
         | 
| 11 | 
            +
             | 
| 5 12 | 
             
            ## 1.5.0.pre.4 (2023-07-06)
         | 
| 6 13 |  | 
| 7 14 | 
             
            ### Type checker core
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
| @@ -767,6 +767,19 @@ module Steep | |
| 767 767 | 
             
                    end
         | 
| 768 768 | 
             
                  end
         | 
| 769 769 |  | 
| 770 | 
            +
                  class UnreachableValueBranch < Base
         | 
| 771 | 
            +
                    attr_reader :type
         | 
| 772 | 
            +
             | 
| 773 | 
            +
                    def initialize(node:, type:, location: node.location.expression)
         | 
| 774 | 
            +
                      super(node: node, location: location)
         | 
| 775 | 
            +
                      @type = type
         | 
| 776 | 
            +
                    end
         | 
| 777 | 
            +
             | 
| 778 | 
            +
                    def header_line
         | 
| 779 | 
            +
                      "The branch may evaluate to a value of `#{type}` but unreachable"
         | 
| 780 | 
            +
                    end
         | 
| 781 | 
            +
                  end
         | 
| 782 | 
            +
             | 
| 770 783 | 
             
                  class UnexpectedSplat < Base
         | 
| 771 784 | 
             
                    attr_reader :type
         | 
| 772 785 |  | 
| @@ -968,7 +981,8 @@ module Steep | |
| 968 981 | 
             
                      {
         | 
| 969 982 | 
             
                        ImplicitBreakValueMismatch => :warning,
         | 
| 970 983 | 
             
                        FallbackAny => :information,
         | 
| 971 | 
            -
                         | 
| 984 | 
            +
                        UnreachableValueBranch => :warning,
         | 
| 985 | 
            +
                        UnreachableBranch => :information,
         | 
| 972 986 | 
             
                        UnknownConstant => :warning,
         | 
| 973 987 | 
             
                        MethodDefinitionMissing => :information,
         | 
| 974 988 | 
             
                        FalseAssertion => :information,
         | 
| @@ -989,6 +1003,7 @@ module Steep | |
| 989 1003 | 
             
                        NoMethod => nil,
         | 
| 990 1004 | 
             
                        ImplicitBreakValueMismatch => nil,
         | 
| 991 1005 | 
             
                        FallbackAny => nil,
         | 
| 1006 | 
            +
                        UnreachableValueBranch => nil,
         | 
| 992 1007 | 
             
                        UnreachableBranch => nil,
         | 
| 993 1008 | 
             
                        UnknownConstant => nil,
         | 
| 994 1009 | 
             
                        MethodDefinitionMissing => nil,
         | 
| @@ -1006,6 +1021,7 @@ module Steep | |
| 1006 1021 | 
             
                        NoMethod => nil,
         | 
| 1007 1022 | 
             
                        ImplicitBreakValueMismatch => nil,
         | 
| 1008 1023 | 
             
                        FallbackAny => nil,
         | 
| 1024 | 
            +
                        UnreachableValueBranch => nil,
         | 
| 1009 1025 | 
             
                        UnreachableBranch => nil,
         | 
| 1010 1026 | 
             
                        UnknownConstant => nil,
         | 
| 1011 1027 | 
             
                        MethodDefinitionMissing => nil,
         | 
| @@ -1883,9 +1883,25 @@ module Steep | |
| 1883 1883 |  | 
| 1884 1884 | 
             
                        if truthy.unreachable
         | 
| 1885 1885 | 
             
                          if true_clause
         | 
| 1886 | 
            +
                            _, _, _, loc = deconstruct_if_node!(node)
         | 
| 1887 | 
            +
             | 
| 1888 | 
            +
                            if loc.respond_to?(:keyword)
         | 
| 1889 | 
            +
                              condition_loc = loc #: NodeHelper::condition_loc
         | 
| 1890 | 
            +
                              case condition_loc.keyword.source
         | 
| 1891 | 
            +
                              when "if"
         | 
| 1892 | 
            +
                                location = condition_loc.begin || condition_loc.keyword
         | 
| 1893 | 
            +
                              when "unless"
         | 
| 1894 | 
            +
                                # `else` token always exists
         | 
| 1895 | 
            +
                                location = condition_loc.else || raise
         | 
| 1896 | 
            +
                              end
         | 
| 1897 | 
            +
                            else
         | 
| 1898 | 
            +
                              location = true_clause.loc.expression
         | 
| 1899 | 
            +
                            end
         | 
| 1900 | 
            +
             | 
| 1886 1901 | 
             
                            typing.add_error(
         | 
| 1887 1902 | 
             
                              Diagnostic::Ruby::UnreachableBranch.new(
         | 
| 1888 | 
            -
                                node: true_clause | 
| 1903 | 
            +
                                node: true_clause,
         | 
| 1904 | 
            +
                                location: location || raise
         | 
| 1889 1905 | 
             
                              )
         | 
| 1890 1906 | 
             
                            )
         | 
| 1891 1907 | 
             
                          end
         | 
| @@ -1893,9 +1909,25 @@ module Steep | |
| 1893 1909 |  | 
| 1894 1910 | 
             
                        if falsy.unreachable
         | 
| 1895 1911 | 
             
                          if false_clause
         | 
| 1912 | 
            +
                            _, _, _, loc = deconstruct_if_node!(node)
         | 
| 1913 | 
            +
             | 
| 1914 | 
            +
                            if loc.respond_to?(:keyword)
         | 
| 1915 | 
            +
                              condition_loc = loc #: NodeHelper::condition_loc
         | 
| 1916 | 
            +
                              case condition_loc.keyword.source
         | 
| 1917 | 
            +
                              when "if"
         | 
| 1918 | 
            +
                                # `else` token always exists
         | 
| 1919 | 
            +
                                location = condition_loc.else || raise
         | 
| 1920 | 
            +
                              when "unless"
         | 
| 1921 | 
            +
                                location = condition_loc.begin || condition_loc.keyword
         | 
| 1922 | 
            +
                              end
         | 
| 1923 | 
            +
                            else
         | 
| 1924 | 
            +
                              location = false_clause.loc.expression
         | 
| 1925 | 
            +
                            end
         | 
| 1926 | 
            +
             | 
| 1896 1927 | 
             
                            typing.add_error(
         | 
| 1897 1928 | 
             
                              Diagnostic::Ruby::UnreachableBranch.new(
         | 
| 1898 | 
            -
                                node: false_clause | 
| 1929 | 
            +
                                node: false_clause,
         | 
| 1930 | 
            +
                                location: location || raise
         | 
| 1899 1931 | 
             
                              )
         | 
| 1900 1932 | 
             
                            )
         | 
| 1901 1933 | 
             
                          end
         | 
| @@ -1961,19 +1993,25 @@ module Steep | |
| 1961 1993 | 
             
                            next_branch_reachable &&= false_branch_reachable
         | 
| 1962 1994 | 
             
                            body_constr = when_constr.update_type_env {|env| env.join(*test_envs) }
         | 
| 1963 1995 |  | 
| 1964 | 
            -
                             | 
| 1965 | 
            -
                               | 
| 1996 | 
            +
                            branch_result =
         | 
| 1997 | 
            +
                              if body
         | 
| 1966 1998 | 
             
                                body_constr
         | 
| 1967 1999 | 
             
                                  .for_branch(body)
         | 
| 1968 2000 | 
             
                                  .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
         | 
| 1969 2001 | 
             
                                  .synthesize(body, hint: hint)
         | 
| 1970 | 
            -
             | 
| 1971 | 
            -
             | 
| 1972 | 
            -
             | 
| 2002 | 
            +
                              else
         | 
| 2003 | 
            +
                                Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
         | 
| 2004 | 
            +
                              end
         | 
| 1973 2005 |  | 
| 1974 | 
            -
                             | 
| 2006 | 
            +
                            branch_results << branch_result
         | 
| 2007 | 
            +
             | 
| 2008 | 
            +
                            if !branch_reachable && !branch_result.type.is_a?(AST::Types::Bot)
         | 
| 1975 2009 | 
             
                              typing.add_error(
         | 
| 1976 | 
            -
                                Diagnostic::Ruby:: | 
| 2010 | 
            +
                                Diagnostic::Ruby::UnreachableValueBranch.new(
         | 
| 2011 | 
            +
                                  node: clause,
         | 
| 2012 | 
            +
                                  type: branch_result.type,
         | 
| 2013 | 
            +
                                  location: clause.location.keyword
         | 
| 2014 | 
            +
                                )
         | 
| 1977 2015 | 
             
                              )
         | 
| 1978 2016 | 
             
                            end
         | 
| 1979 2017 |  | 
| @@ -2004,9 +2042,14 @@ module Steep | |
| 2004 2042 | 
             
                            # `else` may present even if it's empty
         | 
| 2005 2043 | 
             
                            if loc.else
         | 
| 2006 2044 | 
             
                              if els
         | 
| 2007 | 
            -
                                 | 
| 2008 | 
            -
             | 
| 2009 | 
            -
             | 
| 2045 | 
            +
                                else_result or raise
         | 
| 2046 | 
            +
                                unless else_result.type.is_a?(AST::Types::Bot)
         | 
| 2047 | 
            +
                                  typing.add_error Diagnostic::Ruby::UnreachableValueBranch.new(
         | 
| 2048 | 
            +
                                    node: els,
         | 
| 2049 | 
            +
                                    type: else_result.type,
         | 
| 2050 | 
            +
                                    location: node.loc.else || raise
         | 
| 2051 | 
            +
                                  )
         | 
| 2052 | 
            +
                                end
         | 
| 2010 2053 | 
             
                              end
         | 
| 2011 2054 | 
             
                            end
         | 
| 2012 2055 | 
             
                          else
         | 
| @@ -2042,21 +2085,29 @@ module Steep | |
| 2042 2085 | 
             
                              branch_reachable ||= !truthy.unreachable
         | 
| 2043 2086 | 
             
                            end
         | 
| 2044 2087 |  | 
| 2045 | 
            -
                             | 
| 2046 | 
            -
                               | 
| 2088 | 
            +
                            branch_result =
         | 
| 2089 | 
            +
                              if body
         | 
| 2047 2090 | 
             
                                when_clause_constr
         | 
| 2048 2091 | 
             
                                  .for_branch(body)
         | 
| 2049 2092 | 
             
                                  .update_type_env {|env| env.join(*body_envs) }
         | 
| 2050 2093 | 
             
                                  .tap {|constr| typing.add_context_for_node(body, context: constr.context) }
         | 
| 2051 2094 | 
             
                                  .synthesize(body, hint: hint)
         | 
| 2052 | 
            -
             | 
| 2053 | 
            -
             | 
| 2054 | 
            -
             | 
| 2095 | 
            +
                              else
         | 
| 2096 | 
            +
                                Pair.new(type: AST::Builtin.nil_type, constr: when_clause_constr)
         | 
| 2097 | 
            +
                              end
         | 
| 2098 | 
            +
             | 
| 2099 | 
            +
                            branch_results << branch_result
         | 
| 2055 2100 |  | 
| 2056 2101 | 
             
                            unless branch_reachable
         | 
| 2057 | 
            -
                               | 
| 2058 | 
            -
                                 | 
| 2059 | 
            -
             | 
| 2102 | 
            +
                              unless branch_result.type.is_a?(AST::Types::Bot)
         | 
| 2103 | 
            +
                                typing.add_error(
         | 
| 2104 | 
            +
                                  Diagnostic::Ruby::UnreachableValueBranch.new(
         | 
| 2105 | 
            +
                                    node: when_clause,
         | 
| 2106 | 
            +
                                    type: branch_result.type,
         | 
| 2107 | 
            +
                                    location: when_clause.location.keyword || raise
         | 
| 2108 | 
            +
                                  )
         | 
| 2109 | 
            +
                                )
         | 
| 2110 | 
            +
                              end
         | 
| 2060 2111 | 
             
                            end
         | 
| 2061 2112 | 
             
                          end
         | 
| 2062 2113 |  | 
| @@ -3913,13 +3964,15 @@ module Steep | |
| 3913 3964 | 
             
                        end
         | 
| 3914 3965 |  | 
| 3915 3966 | 
             
                        if hint && !fvs.empty?
         | 
| 3916 | 
            -
                          if  | 
| 3917 | 
            -
                             | 
| 3918 | 
            -
                               | 
| 3967 | 
            +
                          if hint.free_variables.subset?(self_type.free_variables)
         | 
| 3968 | 
            +
                            if check_relation(sub_type: method_type.type.return_type, super_type: hint, constraints: constraints).success?
         | 
| 3969 | 
            +
                              method_type, solved, s = apply_solution(errors, node: node, method_type: method_type) do
         | 
| 3970 | 
            +
                                constraints.solution(checker, variables: fvs, context: ccontext)
         | 
| 3971 | 
            +
                              end
         | 
| 3919 3972 | 
             
                            end
         | 
| 3920 | 
            -
                          end
         | 
| 3921 3973 |  | 
| 3922 | 
            -
             | 
| 3974 | 
            +
                            method_type.block or raise
         | 
| 3975 | 
            +
                          end
         | 
| 3923 3976 | 
             
                        end
         | 
| 3924 3977 |  | 
| 3925 3978 | 
             
                        # Method accepts block
         | 
| @@ -126,7 +126,9 @@ module Steep | |
| 126 126 |  | 
| 127 127 | 
             
                    def upper_bounds
         | 
| 128 128 | 
             
                      table.each_value.with_object({}) do |type_param, bounds|
         | 
| 129 | 
            -
                         | 
| 129 | 
            +
                        if type_param.upper_bound
         | 
| 130 | 
            +
                          bounds[type_param.name] = type_param.upper_bound
         | 
| 131 | 
            +
                        end
         | 
| 130 132 | 
             
                      end
         | 
| 131 133 | 
             
                    end
         | 
| 132 134 |  | 
    
        data/lib/steep/version.rb
    CHANGED
    
    
    
        data/sig/shims/parser/nodes.rbs
    CHANGED
    
    
| @@ -479,6 +479,31 @@ module Steep | |
| 479 479 | 
             
                    def header_line: () -> String
         | 
| 480 480 | 
             
                  end
         | 
| 481 481 |  | 
| 482 | 
            +
                  # The branch is unreachable, but not `bot` type
         | 
| 483 | 
            +
                  #
         | 
| 484 | 
            +
                  # We often have `else` branch to make the code more defensive:
         | 
| 485 | 
            +
                  #
         | 
| 486 | 
            +
                  # ```ruby
         | 
| 487 | 
            +
                  # case value
         | 
| 488 | 
            +
                  # when Integer
         | 
| 489 | 
            +
                  #   # ...
         | 
| 490 | 
            +
                  # when String
         | 
| 491 | 
            +
                  #   # ...
         | 
| 492 | 
            +
                  # else
         | 
| 493 | 
            +
                  #   raise "Cannot happen!"
         | 
| 494 | 
            +
                  # end
         | 
| 495 | 
            +
                  # ```
         | 
| 496 | 
            +
                  #
         | 
| 497 | 
            +
                  # This diagnostic allows writing `raise` or `return`, by checking the type of the branch body is `bot` or not.
         | 
| 498 | 
            +
                  # 
         | 
| 499 | 
            +
                  class UnreachableValueBranch < Base
         | 
| 500 | 
            +
                    attr_reader type: AST::Types::t
         | 
| 501 | 
            +
             | 
| 502 | 
            +
                    def initialize: (node: Parser::AST::Node, type: AST::Types::t, ?location: location) -> void
         | 
| 503 | 
            +
             | 
| 504 | 
            +
                    def header_line: () -> String
         | 
| 505 | 
            +
                  end
         | 
| 506 | 
            +
             | 
| 482 507 | 
             
                  class UnexpectedSplat < Base
         | 
| 483 508 | 
             
                    attr_reader type: untyped
         | 
| 484 509 |  | 
| @@ -120,18 +120,6 @@ | |
| 120 120 | 
             
                message: 'The method parameter has different kind from the declaration `(name:
         | 
| 121 121 | 
             
                  ::String, size: ::Integer) -> void`'
         | 
| 122 122 | 
             
                code: Ruby::DifferentMethodParameterKind
         | 
| 123 | 
            -
            - file: else_on_exhaustive_case.rb
         | 
| 124 | 
            -
              diagnostics:
         | 
| 125 | 
            -
              - range:
         | 
| 126 | 
            -
                  start:
         | 
| 127 | 
            -
                    line: 11
         | 
| 128 | 
            -
                    character: 2
         | 
| 129 | 
            -
                  end:
         | 
| 130 | 
            -
                    line: 11
         | 
| 131 | 
            -
                    character: 26
         | 
| 132 | 
            -
                severity: ERROR
         | 
| 133 | 
            -
                message: The branch is unreachable
         | 
| 134 | 
            -
                code: Ruby::UnreachableBranch
         | 
| 135 123 | 
             
            - file: incompatible_annotation.rb
         | 
| 136 124 | 
             
              diagnostics:
         | 
| 137 125 | 
             
              - range:
         | 
| @@ -13,14 +13,14 @@ | |
| 13 13 | 
             
                code: Ruby::NoMethod
         | 
| 14 14 | 
             
              - range:
         | 
| 15 15 | 
             
                  start:
         | 
| 16 | 
            -
                    line:  | 
| 17 | 
            -
                    character:  | 
| 16 | 
            +
                    line: 11
         | 
| 17 | 
            +
                    character: 0
         | 
| 18 18 | 
             
                  end:
         | 
| 19 | 
            -
                    line:  | 
| 20 | 
            -
                    character:  | 
| 19 | 
            +
                    line: 11
         | 
| 20 | 
            +
                    character: 4
         | 
| 21 21 | 
             
                severity: ERROR
         | 
| 22 | 
            -
                message: The branch  | 
| 23 | 
            -
                code: Ruby:: | 
| 22 | 
            +
                message: The branch may evaluate to a value of `untyped` but unreachable
         | 
| 23 | 
            +
                code: Ruby::UnreachableValueBranch
         | 
| 24 24 | 
             
              - range:
         | 
| 25 25 | 
             
                  start:
         | 
| 26 26 | 
             
                    line: 12
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: steep
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.5.0.pre. | 
| 4 | 
            +
              version: 1.5.0.pre.5
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Soutaro Matsumoto
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023-07- | 
| 11 | 
            +
            date: 2023-07-07 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: parser
         |