steep 0.35.0 → 0.36.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|