Skip to content

Implement singleton binary literal types#10816

Open
williamthome wants to merge 13 commits into
erlang:masterfrom
williamthome:singleton-binary-literal-types
Open

Implement singleton binary literal types#10816
williamthome wants to merge 13 commits into
erlang:masterfrom
williamthome:singleton-binary-literal-types

Conversation

@williamthome

Copy link
Copy Markdown
Contributor

This is an implementation of singleton binary literal types as described in erlang/eep#84.

Erlang's type system supports singleton types for atoms ('foo') and
integers (42), but not for binaries. This adds Phase 1 support for
binary literal types like <<"hello">> in -type, -spec, and -callback
declarations.

In this phase, Dialyzer treats <<"foo">> structurally as <<_:24>>
(by bit size). Full value tracking is planned for Phase 2.

Changes:
- Parser: grammar rule for `<< string >>` producing {bin_type, Anno, Binary}
- Linter: accept {bin_type, _, Value} in type positions
- Pretty printer: render bin_type back as <<"...">>
- Dialyzer: from_form maps to t_bitstr(0, BitSize), t_form_to_string
- Syntax tools: binary_literal_type node type with constructor/accessor/revert
- Documentation: abstract format and type spec reference updated
- Tests: erl_lint, erl_pp, syntax_tools, and dialyzer test data
Extend Dialyzer to track binary literal values, not just bit sizes.
<<"foo">> is now a distinct tracked value rather than just <<_:24>>,
enabling type narrowing, map key tracking, and set operations.

Uses the qualifier field of #c{} (unused for binary types) to store
an ordset of known binary values, following the same pattern as atom
and integer singleton sets.

Changes in erl_types.erl:
- ?bitstr_vals macro and t_binary_val/1 constructor
- from_form uses t_binary_val for value-level precision
- t_from_term tracks binary values (not just bitstring sizes)
- t_sup_aux: union of binary value sets with SET_LIMIT widening
- t_inf_aux: intersection with value sets and structural types
- t_subtract_aux: element-wise subtraction of value sets
- is_singleton_type: recognizes single-value binary sets
- separate_key: expands binary value sets for map key tracking
- t_to_string/t_elements: render and expand value sets
Add a unit test in erl_types_SUITE that directly exercises
type_form_to_remote_modules with {bin_type, _, _} forms, verifying
that binary literal types are correctly treated as leaf types with
no module dependencies.

Also extend the small_SUITE bin_type integration test with a type
that combines a binary literal and a remote type reference
(<<"hello">> | binary:part()), exercising the full Dialyzer pipeline
through get_modules_mentioned.
Fix missing binary_literal_type clauses in erl_prettypr:lay_2/2,
erl_syntax:concrete/1, and erl_syntax:is_literal/1 that would crash
or return wrong results for binary literal type nodes.

Add comprehensive tests for binary val type operations in erl_types,
empty binary edge cases in erl_pp and erl_lint, and concrete/is_literal
coverage in syntax_tools.
Dialyzer's check_record_fields/3 was missing a clause for {bin_type, _, _}
forms, causing a function_clause crash when analyzing records with binary
literal type fields (e.g., -record(msg, {tag :: <<"hello">>})).
Support <<"..."/utf8>>, <<"..."/utf16>>, <<"..."/utf32>>, <<"..."/latin1>>,
and ~"..." sigil syntax in type specifications. Only the parser needed
changes since {bin_type, Anno, Bin} stores the final binary value.
Reuse existing non-terminals (opt_bit_type_list, sigil) instead of
duplicating grammar structure. Reduces 3 rules to 2 and unifies
builder functions, while producing identical AST output.
@github-actions

github-actions Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

CT Test Results

    6 files    257 suites   2h 8m 27s ⏱️
4 202 tests 4 101 ✅ 101 💤 0 ❌
5 371 runs  5 245 ✅ 126 💤 0 ❌

Results for commit eeaacb5.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

The t_from_term change now tracks exact binary values (like atoms),
producing more precise type names in Dialyzer output:

- <<>> becomes <<"">>
- <<_:8>> becomes <<"f">> or <<"*">> for known values
- <<_:16>> becomes <<"hi">> for known values
- Binary map keys show as singleton values (e.g., <<"50">>)

Also fix make_bitstr_vals to properly compute Unit/Base from filtered
values after intersection, rather than assuming uniform sizes.
The CI license-header check requires headers on modified files.
The test comparator skips %-prefixed lines, so headers are safe.
@IngelaAndin IngelaAndin added the team:VM Assigned to OTP team VM label Mar 9, 2026
@bjorng bjorng added the team:LG Assigned to OTP language group label Mar 9, 2026
@rickard-green rickard-green added the stalled waiting for input by the Erlang/OTP team label May 4, 2026
@yordis

yordis commented May 8, 2026

Copy link
Copy Markdown

hey @williamthome are you still actively trying to get this one in? I was about to contribute the same feature and I found your PR, so I wonder if you can't continue the work or what is left (also, CI is failing)

@williamthome

Copy link
Copy Markdown
Contributor Author

hey @williamthome are you still actively trying to get this one in? I was about to contribute the same feature and I found your PR, so I wonder if you can't continue the work or what is left (also, CI is failing)

Hey @yordis! Well, not actively trying; I'm awaiting a review of erlang/eep#84 before making any code changes or fixes

@yordis

yordis commented May 8, 2026

Copy link
Copy Markdown

@IngelaAndin @bjorng can you help with the situation?

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

Labels

stalled waiting for input by the Erlang/OTP team team:LG Assigned to OTP language group team:VM Assigned to OTP team VM

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants