steep 0.35.0 → 0.36.0
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 +6 -0
- data/lib/steep/ast/types/logic.rb +20 -1
- data/lib/steep/subtyping/check.rb +21 -0
- data/lib/steep/type_construction.rb +50 -23
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -0
- data/lib/steep/version.rb +1 -1
- 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: 5203340eb3b3534da5f1071cc497bbe7a481553e909088277c83dbfe5e5c0bbc
|
4
|
+
data.tar.gz: 11863c0ea9b692de6fba552ec01645525240c025c598235f9b3bf88e35571ed5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9897fecb7ca5b60da9eeb236e5f06af1a9b2fa2a2df2bd87d07f7a496f0f05b988b30db2e294797304c6d7f0e8fe478cdc1d41049cbaf2e56c45108444b2c721
|
7
|
+
data.tar.gz: fa2dca2cd37d74e39878ab3da7a5453a714f50e921fcd1c0e75054bf083a11003cb5799f4f92531a10bce6074dce3cce88c90daeb214b9fb45d7f5612e294fb3
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.36.0 (2020-11-16)
|
6
|
+
|
7
|
+
* Flow-sensitive typing improvements with `||` and `&&` ([#260](https://github.com/soutaro/steep/pull/260))
|
8
|
+
* Type-case improvement ([#259](https://github.com/soutaro/steep/pull/259))
|
9
|
+
* Subtyping between `bool` and logic types ([#258](https://github.com/soutaro/steep/pull/258))
|
10
|
+
|
5
11
|
## 0.35.0 (2020-11-14)
|
6
12
|
|
7
13
|
* Support third party RBS repository ([#231](https://github.com/soutaro/steep/pull/231), [#254](https://github.com/soutaro/steep/pull/254), [#255](https://github.com/soutaro/steep/pull/255))
|
@@ -18,7 +18,7 @@ module Steep
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def ==(other)
|
21
|
-
other.class ==self.class
|
21
|
+
other.class == self.class
|
22
22
|
end
|
23
23
|
|
24
24
|
alias eql? ==
|
@@ -57,6 +57,25 @@ module Steep
|
|
57
57
|
@location = location
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
61
|
+
class Env < Base
|
62
|
+
attr_reader :truthy, :falsy
|
63
|
+
|
64
|
+
def initialize(truthy:, falsy:, location: nil)
|
65
|
+
@truthy = truthy
|
66
|
+
@falsy = falsy
|
67
|
+
end
|
68
|
+
|
69
|
+
def ==(other)
|
70
|
+
other.is_a?(Env) && other.truthy == truthy && other.falsy == falsy
|
71
|
+
end
|
72
|
+
|
73
|
+
alias eql? ==
|
74
|
+
|
75
|
+
def hash
|
76
|
+
self.class.hash ^ truthy.hash ^ falsy.hash
|
77
|
+
end
|
78
|
+
end
|
60
79
|
end
|
61
80
|
end
|
62
81
|
end
|
@@ -127,6 +127,24 @@ module Steep
|
|
127
127
|
Result::Failure.new(error: error, trace: trace)
|
128
128
|
end
|
129
129
|
|
130
|
+
def true_type?(type)
|
131
|
+
case type
|
132
|
+
when AST::Types::Literal
|
133
|
+
type.value == true
|
134
|
+
else
|
135
|
+
AST::Builtin::TrueClass.instance_type?(type)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def false_type?(type)
|
140
|
+
case type
|
141
|
+
when AST::Types::Literal
|
142
|
+
type.value == false
|
143
|
+
else
|
144
|
+
AST::Builtin::FalseClass.instance_type?(type)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
130
148
|
def check0(relation, self_type:, assumption:, trace:, constraints:)
|
131
149
|
# puts relation
|
132
150
|
trace.type(relation.sub_type, relation.super_type) do
|
@@ -146,6 +164,9 @@ module Steep
|
|
146
164
|
when relation.sub_type.is_a?(AST::Types::Bot)
|
147
165
|
success(constraints: constraints)
|
148
166
|
|
167
|
+
when relation.sub_type.is_a?(AST::Types::Logic::Base) && (true_type?(relation.super_type) || false_type?(relation.super_type))
|
168
|
+
success(constraints: constraints)
|
169
|
+
|
149
170
|
when relation.super_type.is_a?(AST::Types::Boolean)
|
150
171
|
check(
|
151
172
|
Relation.new(sub_type: relation.sub_type, super_type: AST::Types::Union.build(types: [AST::Builtin.true_type, AST::Builtin.false_type])),
|
@@ -1476,7 +1476,18 @@ module Steep
|
|
1476
1476
|
.for_branch(right)
|
1477
1477
|
.synthesize(right)
|
1478
1478
|
|
1479
|
-
|
1479
|
+
truthy_env, _ = interpreter.eval(env: truthy_env, type: right_type, node: right)
|
1480
|
+
|
1481
|
+
env = if right_type.is_a?(AST::Types::Bot)
|
1482
|
+
falsey_env
|
1483
|
+
else
|
1484
|
+
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
type = case
|
1488
|
+
when left_type.is_a?(AST::Types::Logic::Base) && right_type.is_a?(AST::Types::Logic::Base)
|
1489
|
+
AST::Types::Logic::Env.new(truthy: truthy_env, falsy: env)
|
1490
|
+
when check_relation(sub_type: left_type, super_type: AST::Types::Boolean.new).success?
|
1480
1491
|
union_type(left_type, right_type)
|
1481
1492
|
else
|
1482
1493
|
union_type(right_type, AST::Builtin.nil_type)
|
@@ -1484,13 +1495,7 @@ module Steep
|
|
1484
1495
|
|
1485
1496
|
add_typing(node,
|
1486
1497
|
type: type,
|
1487
|
-
constr: constr.update_lvar_env
|
1488
|
-
if right_type.is_a?(AST::Types::Bot)
|
1489
|
-
falsey_env
|
1490
|
-
else
|
1491
|
-
context.lvar_env.join(falsey_env, constr.context.lvar_env)
|
1492
|
-
end
|
1493
|
-
end)
|
1498
|
+
constr: constr.update_lvar_env { env })
|
1494
1499
|
end
|
1495
1500
|
|
1496
1501
|
when :or
|
@@ -1502,24 +1507,31 @@ module Steep
|
|
1502
1507
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing)
|
1503
1508
|
truthy_env, falsey_env = interpreter.eval(env: constr.context.lvar_env, type: left_type, node: left)
|
1504
1509
|
|
1505
|
-
|
1510
|
+
left_type, _ = checker.factory.unwrap_optional(left_type)
|
1506
1511
|
right_type, constr = constr
|
1507
1512
|
.update_lvar_env { falsey_env }
|
1508
1513
|
.tap {|constr| typing.add_context_for_node(right, context: constr.context) }
|
1509
1514
|
.for_branch(right)
|
1510
|
-
.synthesize(right, hint:
|
1515
|
+
.synthesize(right, hint: left_type)
|
1511
1516
|
|
1512
|
-
|
1517
|
+
_, falsey_env = interpreter.eval(env: falsey_env, type: right_type, node: right)
|
1518
|
+
|
1519
|
+
env = if right_type.is_a?(AST::Types::Bot)
|
1520
|
+
truthy_env
|
1521
|
+
else
|
1522
|
+
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1523
|
+
end
|
1524
|
+
|
1525
|
+
type = case
|
1526
|
+
when left_type.is_a?(AST::Types::Logic::Base) && right_type.is_a?(AST::Types::Logic::Base)
|
1527
|
+
AST::Types::Logic::Env.new(truthy: env, falsy: falsey_env)
|
1528
|
+
else
|
1529
|
+
union_type(left_type, right_type)
|
1530
|
+
end
|
1513
1531
|
|
1514
1532
|
add_typing(node,
|
1515
1533
|
type: type,
|
1516
|
-
constr: constr.update_lvar_env
|
1517
|
-
if right_type.is_a?(AST::Types::Bot)
|
1518
|
-
truthy_env
|
1519
|
-
else
|
1520
|
-
context.lvar_env.join(truthy_env, constr.context.lvar_env)
|
1521
|
-
end
|
1522
|
-
end)
|
1534
|
+
constr: constr.update_lvar_env { env })
|
1523
1535
|
end
|
1524
1536
|
|
1525
1537
|
when :if
|
@@ -1584,6 +1596,18 @@ module Steep
|
|
1584
1596
|
|
1585
1597
|
cond_type, constr = constr.synthesize(cond)
|
1586
1598
|
_, cond_vars = interpreter.decompose_value(cond)
|
1599
|
+
unless cond_vars.empty?
|
1600
|
+
first_var = cond_vars.to_a[0]
|
1601
|
+
var_node = cond.updated(
|
1602
|
+
:lvar,
|
1603
|
+
[
|
1604
|
+
ASTUtils::Labeling::LabeledName.new(name: first_var, label: 0)
|
1605
|
+
]
|
1606
|
+
)
|
1607
|
+
else
|
1608
|
+
first_var = nil
|
1609
|
+
var_node = cond
|
1610
|
+
end
|
1587
1611
|
|
1588
1612
|
when_constr = constr
|
1589
1613
|
whens.each do |clause|
|
@@ -1593,9 +1617,15 @@ module Steep
|
|
1593
1617
|
test_envs = []
|
1594
1618
|
|
1595
1619
|
tests.each do |test|
|
1596
|
-
test_node = test.updated(:send, [test, :===,
|
1620
|
+
test_node = test.updated(:send, [test, :===, var_node])
|
1597
1621
|
test_type, test_constr = test_constr.synthesize(test_node)
|
1598
1622
|
truthy_env, falsy_env = interpreter.eval(type: test_type, node: test_node, env: test_constr.context.lvar_env)
|
1623
|
+
truthy_env = cond_vars.inject(truthy_env) do |env, var|
|
1624
|
+
env.assign!(var, node: test_node, type: env[first_var])
|
1625
|
+
end
|
1626
|
+
falsy_env = cond_vars.inject(falsy_env) do |env, var|
|
1627
|
+
env.assign!(var, node: test_node, type: env[first_var])
|
1628
|
+
end
|
1599
1629
|
test_envs << truthy_env
|
1600
1630
|
test_constr = test_constr.update_lvar_env { falsy_env }
|
1601
1631
|
end
|
@@ -1625,10 +1655,6 @@ module Steep
|
|
1625
1655
|
types = branch_pairs.map(&:type)
|
1626
1656
|
constrs = branch_pairs.map(&:constr)
|
1627
1657
|
|
1628
|
-
unless els
|
1629
|
-
constrs << when_constr
|
1630
|
-
end
|
1631
|
-
|
1632
1658
|
if when_constr.context.lvar_env[cond_vars.first].is_a?(AST::Types::Bot)
|
1633
1659
|
# Exhaustive
|
1634
1660
|
if els
|
@@ -1636,6 +1662,7 @@ module Steep
|
|
1636
1662
|
end
|
1637
1663
|
else
|
1638
1664
|
unless els
|
1665
|
+
constrs << when_constr
|
1639
1666
|
types << AST::Builtin.nil_type
|
1640
1667
|
end
|
1641
1668
|
end
|
data/lib/steep/version.rb
CHANGED
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: 0.
|
4
|
+
version: 0.36.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|