Skip to content

Bitstring comprehension result types exclude binaries #15857

Description

@lukaszsamson

Existing issue

  • I have searched existing issues and could not find a duplicate.

Elixir and Erlang/OTP versions

Erlang/OTP 28 [erts-16.4.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]

Interactive Elixir (1.21.0-dev)

Operating system

any

Current behavior

Bitstring comprehension returns union of concatanated types (

{opt_union(into_type, intersection), context}
). In case of bitstring fragments that happen to concatanate to full aligned bytes the result falls out of the union type:
bitstring() and not binary() <> bitstring() and not binary() = bitstring()

Repro:

    defmodule Bits do
      def build(items) do
        bits = for _ <- items, into: <<0::4>>, do: <<1::4>>

        case bits do
          x when is_binary(x) -> {:binary, x}
          x -> {:bits, x}
        end
      end
    end

    IO.inspect(Enum.map([[], [1], [1, 2], [1, 2, 3]], &Bits.build/1))

Result:
the code works fine and prints:

[
  bits: <<0::size(4)>>,
  binary: <<1>>,
  bits: <<1, 1::size(4)>>,
  binary: <<1, 17>>
]

Both case branches are needed but the code emits a false positive warning:

warning: the following clause will never match:

    x when is_binary(x) ->

because it attempts to match on the result of:

    bits

which has type:

    bitstring() and not binary()

where "x" was given the type:

    # type: binary()
    # from: iex:26
    is_binary(x)

└─ iex:26: Bits.build/1

Note this issue is distinct from #15465, #15451 and the unaddressed TODO in

# TODO: Use the collectable protocol for the output

Expected behavior

Bitstring comprehension result should not be inferred as bitstring() and not binary()

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions