Skip to content

Commit

Permalink
Merge pull request #283 from soutaro/fix-is-a-typing
Browse files Browse the repository at this point in the history
Fix type case with cast
  • Loading branch information
soutaro committed Dec 25, 2020
2 parents b610707 + e5ad8b6 commit 5727c3d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
24 changes: 21 additions & 3 deletions lib/steep/type_construction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,25 @@ def type_send_interface(node, interface:, receiver:, receiver_type:, method_name

constr.add_call(call)
else
add_call(
skips = []
skips << receiver if receiver
skips << node.children[0] if node.type == :block
skips << block_params if block_params
skips << block_body if block_body

constr = synthesize_children(node, skips: skips)
if block_params
block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)

constr.type_block_without_hint(
node: node,
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
block_annotations: block_annotations,
block_body: block_body
)
end

constr.add_call(
TypeInference::MethodCall::NoMethodError.new(
node: node,
context: context.method_context,
Expand Down Expand Up @@ -3144,9 +3162,9 @@ def type_block_without_hint(node:, block_annotations:, block_params:, block_body
block_constr = for_block(
block_params: block_params,
block_param_hint: nil,
block_type_hint: nil,
block_type_hint: AST::Builtin.any_type,
block_annotations: block_annotations,
node_type_hint: nil
node_type_hint: AST::Builtin.any_type
)

block_constr.typing.add_context_for_body(node, context: block_constr.context)
Expand Down
15 changes: 10 additions & 5 deletions lib/steep/type_inference/logic_type_interpreter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,16 @@ def eval(env:, type:, node:)

if arg_type.is_a?(AST::Types::Name::Singleton)
receiver_vars.each do |var_name|
var_type = env[var_name]
truthy_type, falsy_type = type_case_select(var_type, arg_type.name)

truthy_env = truthy_env.assign!(var_name, node: node, type: truthy_type)
falsy_env = falsy_env.assign!(var_name, node: node, type: falsy_type)
case var_name
when :_, :__any__, :__skip__
# skip
else
var_type = env[var_name]
truthy_type, falsy_type = type_case_select(var_type, arg_type.name)

truthy_env = truthy_env.assign!(var_name, node: node, type: truthy_type)
falsy_env = falsy_env.assign!(var_name, node: node, type: falsy_type)
end
end
end
end
Expand Down
22 changes: 22 additions & 0 deletions test/type_construction_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7078,6 +7078,28 @@ def self.foo(x)
end
end
end
RUBY

with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)
assert_no_error typing
end
end
end

def test_if_is_a_assign
with_checker(<<RBS) do |checker|
interface _Hello
def to_s: () -> String
end
RBS
source = parse_ruby(<<'RUBY')
# @type var x: _Hello
x = ""
if (_ = x).is_a?(String)
x + ""
end
RUBY

with_standard_construction(checker, source) do |construction, typing|
Expand Down

0 comments on commit 5727c3d

Please sign in to comment.