steep 1.5.0.pre.3 → 1.5.0.pre.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +1 -1
- data/lib/steep/ast/types/factory.rb +9 -4
- data/lib/steep/type_construction.rb +52 -58
- data/lib/steep/type_inference/logic_type_interpreter.rb +4 -0
- data/lib/steep/version.rb +1 -1
- data/sig/steep/type_construction.rbs +14 -2
- 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: cfb1de89ec50042cf06306ab17717671e8b6a8451ea2885b4af8085226f7994e
|
4
|
+
data.tar.gz: 1b67eb25821061afe42c8c4dd644b30370e866ac9ef8066cb77031799c981145
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f0b3400822be747c45ed1d5c2cdfbddf8c0fdf70963061b66308464a18a95e493cc94ad406bbc444f618f562e0f95f276600c27e3ec2269f01504727b0528c7
|
7
|
+
data.tar.gz: 45b2a32802ea5ab504a8c3ee04f714a87b27227ffa66282d64243e3161aa0628001f1925e3ad7aaf09fcd0fbddc4def36e9b9940c76a87b195c2f51b19006bf9
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.5.0.pre.4 (2023-07-06)
|
6
|
+
|
7
|
+
### Type checker core
|
8
|
+
|
9
|
+
* Fix unreachability test ([#842](https://github.com/soutaro/steep/pull/842))
|
10
|
+
* Make type of `case` node `untyped` rather than `nil` ([#841](https://github.com/soutaro/steep/pull/841))
|
11
|
+
* Fix `#partition_union` ([#840](https://github.com/soutaro/steep/pull/840))
|
12
|
+
* Fix type-case ([#839](https://github.com/soutaro/steep/pull/839))
|
13
|
+
|
5
14
|
## 1.5.0.pre.3 (2023-07-05)
|
6
15
|
|
7
16
|
### Type checker core
|
data/Gemfile.lock
CHANGED
@@ -358,16 +358,21 @@ module Steep
|
|
358
358
|
partition_union(unfold)
|
359
359
|
end
|
360
360
|
when AST::Types::Union
|
361
|
-
|
362
|
-
|
363
|
-
|
361
|
+
truthy_types = [] #: Array[AST::Types::t]
|
362
|
+
falsy_types = [] #: Array[AST::Types::t]
|
363
|
+
|
364
|
+
type.types.each do |type|
|
365
|
+
truthy, falsy = partition_union(type)
|
366
|
+
|
367
|
+
truthy_types << truthy if truthy
|
368
|
+
falsy_types << falsy if falsy
|
364
369
|
end
|
365
370
|
|
366
371
|
[
|
367
372
|
truthy_types.empty? ? nil : AST::Types::Union.build(types: truthy_types),
|
368
373
|
falsy_types.empty? ? nil : AST::Types::Union.build(types: falsy_types)
|
369
374
|
]
|
370
|
-
when AST::Types::Any, AST::Types::Boolean
|
375
|
+
when AST::Types::Any, AST::Types::Boolean, AST::Types::Top, AST::Types::Logic::Base
|
371
376
|
[type, type]
|
372
377
|
when AST::Types::Nil
|
373
378
|
[nil, type]
|
@@ -1398,8 +1398,11 @@ module Steep
|
|
1398
1398
|
when :true, :false
|
1399
1399
|
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1400
1400
|
|
1401
|
-
|
1401
|
+
case
|
1402
|
+
when hint && check_relation(sub_type: ty, super_type: hint).success? && !hint.is_a?(AST::Types::Any) && !hint.is_a?(AST::Types::Top)
|
1402
1403
|
add_typing(node, type: hint)
|
1404
|
+
when condition
|
1405
|
+
add_typing(node, type: ty)
|
1403
1406
|
else
|
1404
1407
|
add_typing(node, type: AST::Types::Boolean.new)
|
1405
1408
|
end
|
@@ -1920,18 +1923,9 @@ module Steep
|
|
1920
1923
|
cond_vars.delete(name)
|
1921
1924
|
end
|
1922
1925
|
|
1923
|
-
var_name = :"_a#{SecureRandom.alphanumeric(4)}"
|
1924
|
-
var_cond, value_node =
|
1925
|
-
|
1926
|
-
unless constr.context.type_env[value_node]
|
1927
|
-
constr = constr.update_type_env do |env|
|
1928
|
-
env.assign_local_variable(var_name, cond_type, nil)
|
1929
|
-
end
|
1930
|
-
cond = var_cond
|
1931
|
-
else
|
1932
|
-
value_node = nil
|
1933
|
-
end
|
1934
|
-
end
|
1926
|
+
var_name = :"_a[#{SecureRandom.alphanumeric(4)}]"
|
1927
|
+
var_cond, value_node = transform_condition_node(cond, var_name)
|
1928
|
+
constr = constr.update_type_env {|env| env.assign_local_variable(var_name, cond_type, nil) }
|
1935
1929
|
|
1936
1930
|
next_branch_reachable = true
|
1937
1931
|
|
@@ -1949,12 +1943,12 @@ module Steep
|
|
1949
1943
|
false_branch_reachable = false
|
1950
1944
|
|
1951
1945
|
tests.each do |test|
|
1952
|
-
test_node = test.updated(:send, [test, :===,
|
1946
|
+
test_node = test.updated(:send, [test, :===, var_cond])
|
1953
1947
|
test_type, test_constr = test_constr.synthesize(test_node, condition: true).to_ary
|
1954
1948
|
truthy, falsy = interpreter.eval(node: test_node, env: test_constr.context.type_env)
|
1955
1949
|
|
1956
|
-
truthy_env = truthy.env
|
1957
|
-
falsy_env = falsy.env
|
1950
|
+
truthy_env = propagate_type_env(var_name, value_node, truthy.env)
|
1951
|
+
falsy_env = propagate_type_env(var_name, value_node, falsy.env)
|
1958
1952
|
|
1959
1953
|
test_envs << truthy_env
|
1960
1954
|
|
@@ -2003,11 +1997,6 @@ module Steep
|
|
2003
1997
|
types = branch_results.map(&:type)
|
2004
1998
|
constrs = branch_results.map(&:constr)
|
2005
1999
|
|
2006
|
-
cond_type = when_constr.context.type_env[var_name]
|
2007
|
-
cond_type ||= when_constr.context.type_env[cond_vars.first || raise] unless cond_vars.empty?
|
2008
|
-
cond_type ||= when_constr.context.type_env[value_node] if value_node
|
2009
|
-
cond_type ||= typing.type_of(node: node.children[0])
|
2010
|
-
|
2011
2000
|
if !next_branch_reachable
|
2012
2001
|
# Exhaustive
|
2013
2002
|
_, _, _, loc = deconstruct_case_node!(node)
|
@@ -2030,9 +2019,6 @@ module Steep
|
|
2030
2019
|
branch_results = [] #: Array[Pair]
|
2031
2020
|
|
2032
2021
|
condition_constr = constr
|
2033
|
-
clause_constr = constr
|
2034
|
-
|
2035
|
-
next_branch_reachable = true
|
2036
2022
|
|
2037
2023
|
whens.each do |when_clause|
|
2038
2024
|
when_clause_constr = condition_constr
|
@@ -2043,7 +2029,6 @@ module Steep
|
|
2043
2029
|
*tests, body = when_clause.children
|
2044
2030
|
|
2045
2031
|
branch_reachable = false
|
2046
|
-
false_branch_reachable = false
|
2047
2032
|
|
2048
2033
|
tests.each do |test|
|
2049
2034
|
test_type, condition_constr = condition_constr.synthesize(test, condition: true)
|
@@ -2054,12 +2039,9 @@ module Steep
|
|
2054
2039
|
condition_constr = condition_constr.update_type_env { falsy_env }
|
2055
2040
|
body_envs << truthy_env
|
2056
2041
|
|
2057
|
-
branch_reachable ||=
|
2058
|
-
false_branch_reachable ||= !falsy.unreachable
|
2042
|
+
branch_reachable ||= !truthy.unreachable
|
2059
2043
|
end
|
2060
2044
|
|
2061
|
-
next_branch_reachable &&= false_branch_reachable
|
2062
|
-
|
2063
2045
|
if body
|
2064
2046
|
branch_results <<
|
2065
2047
|
when_clause_constr
|
@@ -4490,16 +4472,27 @@ module Steep
|
|
4490
4472
|
end
|
4491
4473
|
|
4492
4474
|
def union_type_unify(*types)
|
4493
|
-
types.
|
4494
|
-
unless no_subtyping?(sub_type: type1, super_type: type2)
|
4495
|
-
next type2
|
4496
|
-
end
|
4475
|
+
types = types.reject {|t| t.is_a?(AST::Types::Bot) }
|
4497
4476
|
|
4498
|
-
|
4499
|
-
|
4500
|
-
|
4477
|
+
if types.empty?
|
4478
|
+
AST::Types::Bot.new
|
4479
|
+
else
|
4480
|
+
types.inject do |type1, type2|
|
4481
|
+
next type2 if type1.is_a?(AST::Types::Any)
|
4482
|
+
next type1 if type2.is_a?(AST::Types::Any)
|
4501
4483
|
|
4502
|
-
|
4484
|
+
unless no_subtyping?(sub_type: type1, super_type: type2)
|
4485
|
+
# type1 <: type2
|
4486
|
+
next type2
|
4487
|
+
end
|
4488
|
+
|
4489
|
+
unless no_subtyping?(sub_type: type2, super_type: type1)
|
4490
|
+
# type2 <: type1
|
4491
|
+
next type1
|
4492
|
+
end
|
4493
|
+
|
4494
|
+
union_type(type1, type2)
|
4495
|
+
end
|
4503
4496
|
end
|
4504
4497
|
end
|
4505
4498
|
|
@@ -5029,33 +5022,19 @@ module Steep
|
|
5029
5022
|
with_new_typing(typing.parent || raise)
|
5030
5023
|
end
|
5031
5024
|
|
5032
|
-
def
|
5025
|
+
def transform_condition_node(node, var_name)
|
5033
5026
|
case node.type
|
5034
5027
|
when :lvasgn
|
5035
5028
|
name, rhs = node.children
|
5036
|
-
rhs, value_node =
|
5037
|
-
|
5038
|
-
[node.updated(nil, [name, rhs]), value_node]
|
5039
|
-
else
|
5040
|
-
[node, value_node]
|
5041
|
-
end
|
5029
|
+
rhs, value_node = transform_condition_node(rhs, var_name)
|
5030
|
+
[node.updated(nil, [name, rhs]), value_node]
|
5042
5031
|
when :begin
|
5043
5032
|
*children, last = node.children
|
5044
|
-
last, value_node =
|
5045
|
-
|
5046
|
-
[node.updated(nil, children.push(last)), value_node]
|
5047
|
-
else
|
5048
|
-
[node, value_node]
|
5049
|
-
end
|
5050
|
-
when :lvar
|
5051
|
-
[node, nil]
|
5033
|
+
last, value_node = transform_condition_node(last, var_name)
|
5034
|
+
[node.updated(nil, children.push(last)), value_node]
|
5052
5035
|
else
|
5053
|
-
|
5054
|
-
|
5055
|
-
else
|
5056
|
-
var_node = node.updated(:lvar, [var_name])
|
5057
|
-
[var_node, node]
|
5058
|
-
end
|
5036
|
+
var_node = node.updated(:lvar, [var_name])
|
5037
|
+
[var_node, node]
|
5059
5038
|
end
|
5060
5039
|
end
|
5061
5040
|
|
@@ -5109,5 +5088,20 @@ module Steep
|
|
5109
5088
|
end
|
5110
5089
|
end
|
5111
5090
|
end
|
5091
|
+
|
5092
|
+
def propagate_type_env(source, dest, env)
|
5093
|
+
source_type = env[source] or raise
|
5094
|
+
|
5095
|
+
if dest.type == :lvar
|
5096
|
+
var_name = dest.children[0] #: Symbol
|
5097
|
+
env.assign_local_variable(var_name, source_type, nil)
|
5098
|
+
else
|
5099
|
+
if env[dest]
|
5100
|
+
env.replace_pure_call_type(dest, source_type)
|
5101
|
+
else
|
5102
|
+
env
|
5103
|
+
end
|
5104
|
+
end
|
5105
|
+
end
|
5112
5106
|
end
|
5113
5107
|
end
|
data/lib/steep/version.rb
CHANGED
@@ -538,18 +538,30 @@ module Steep
|
|
538
538
|
# Returns a pair of transformed node and the outer most call/non-value node if present.
|
539
539
|
#
|
540
540
|
# ```rb
|
541
|
-
# x = y = foo() # Call `#
|
541
|
+
# x = y = foo() # Call `#transform_condition_node` with the node and var_name `:__foo__`
|
542
542
|
# # => Returns [x = y = __foo__, foo()]
|
543
|
+
#
|
544
|
+
# x # Call `#transform_condition_node` with the node and var_name `:__foo__`
|
545
|
+
# # => Returns [__foo__, x]
|
543
546
|
# ```
|
544
547
|
#
|
545
548
|
# This is typically used for transforming assginment node for case condition.
|
546
549
|
#
|
547
|
-
def
|
550
|
+
def transform_condition_node: (Parser::AST::Node node, Symbol) -> [Parser::AST::Node, Parser::AST::Node]
|
548
551
|
|
549
552
|
def type_name: (AST::Types::t) -> RBS::TypeName?
|
550
553
|
|
551
554
|
def singleton_type: (AST::Types::t) -> AST::Types::t?
|
552
555
|
|
553
556
|
def instance_type: (AST::Types::t) -> AST::Types::t?
|
557
|
+
|
558
|
+
# Propagate an entry of `source` in TypeEnv to `dest`
|
559
|
+
#
|
560
|
+
# `source` is name of a local variable.
|
561
|
+
#
|
562
|
+
# If `dest` is a `lvar` node, it updates local variable entry of TypeEnv.
|
563
|
+
# Otherwise, it updates *pure* call of `dest` if it already exists.
|
564
|
+
#
|
565
|
+
def propagate_type_env: (Symbol source, Parser::AST::Node dest, TypeInference::TypeEnv) -> TypeInference::TypeEnv
|
554
566
|
end
|
555
567
|
end
|
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.4
|
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-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|