Skip to content

Commit

Permalink
Showing 2 changed files with 15 additions and 1 deletion.
9 changes: 9 additions & 0 deletions spec/compiler/codegen/cast_spec.cr
Original file line number Diff line number Diff line change
@@ -349,4 +349,13 @@ describe "Code gen: cast" do
x.try &.as(Foo)
))
end

it "casts between union types, where union has a tuple type (#3377)" do
codegen(%(
require "prelude"
v = 1 || true || 1.0
(v || {v}).as(Bool | Float64)
))
end
end
7 changes: 6 additions & 1 deletion src/compiler/crystal/codegen/cast.cr
Original file line number Diff line number Diff line change
@@ -155,8 +155,13 @@ class Crystal::CodeGenVisitor
end

def needs_value_cast_inside_union?(value_type, union_type)
# A type needs a special cast if:
# 1. It's a tuple or named tuple
# 2. It's not inside the target union
# 3. There's a compatible type inside the target union
return false unless value_type.is_a?(TupleInstanceType) || value_type.is_a?(NamedTupleInstanceType)
!union_type.union_types.any? &.==(value_type)
!union_type.union_types.any?(&.==(value_type)) &&
union_type.union_types.any? { |ut| value_type.implements?(ut) || ut.implements?(value_type) }
end

def assign_distinct_union_types(target_pointer, target_type, value_type, value)

0 comments on commit 4733360

Please sign in to comment.