def merge(bsig)
if @rest_ty && bsig.rest_ty
rest_ty = @rest_ty.union(bsig.rest_ty)
BlockSignature.new(@lead_tys, [], rest_ty, @blk_ty.union(bsig.blk_ty))
elsif @rest_ty || bsig.rest_ty
rest_ty = @rest_ty || bsig.rest_ty
rest_ty = @opt_tys.inject(rest_ty, &:union)
rest_ty = bsig.opt_tys.inject(rest_ty, &:union)
lead_tys = []
[@lead_tys.size, bsig.lead_tys.size].max.times do |i|
ty1 = @lead_tys[i]
ty2 = bsig.lead_tys[i]
if ty1 && ty2
lead_tys << ty1.union(ty2)
else
rest_ty = rest_ty.union(ty1 || ty2)
end
end
BlockSignature.new(lead_tys, [], rest_ty, @blk_ty.union(bsig.blk_ty))
else
lead_tys = []
n = [@lead_tys.size, bsig.lead_tys.size].min
n.times do |i|
lead_tys << @lead_tys[i].union(bsig.lead_tys[i])
end
opt_tys1 = @lead_tys[n..] + @opt_tys
opt_tys2 = bsig.lead_tys[n..] + bsig.opt_tys
opt_tys = []
[opt_tys1.size, opt_tys2.size].max.times do |i|
if opt_tys1[i] && opt_tys2[i]
opt_tys << opt_tys1[i].union(opt_tys2[i])
else
opt_tys << (opt_tys1[i] || opt_tys2[i])
end
end
BlockSignature.new(lead_tys, opt_tys, nil, @blk_ty.union(bsig.blk_ty))
end
end