refine distinct construction semantics

This commit is contained in:
2026-08-02 19:13:13 +02:00
parent b9526b5f06
commit f25f76adff
5 changed files with 88 additions and 36 deletions
+11 -7
View File
@@ -139,8 +139,9 @@
8. distinct types (implemented; see below)
- nominal declarations preserve identity across packages and reuse the backing runtime representation
- construction accepts exactly one value of the immediate backing type; no implicit conversion
crosses the nominal boundary or mixes separate distinct declarations
- construction of a numeric scalar-backed distinct type applies the backing's explicit scalar
cast before wrapping; non-scalar and nested-distinct backings still require the exact immediate type
- no implicit conversion crosses the nominal boundary or mixes separate distinct declarations
- explicit scalar casts extract one declared distinct layer at a time
- scalar-backed values support matching runtime/comptime arithmetic, bitwise, shift, comparison,
compound-assignment, bounds, indexing, reflection, and standard formatting behavior
@@ -1061,15 +1062,17 @@ For-loop captures are immutable and scoped to the loop body. Sequence index capt
## A word on distinct types
Distinct declarations are nominal even when they share a backing type. Construction requires the
exact immediate backing, implicit conversion is forbidden in either direction, and an explicit
scalar cast extracts one layer:
Distinct declarations are nominal even when they share a backing type. A constructor for a
numeric scalar-backed distinct type first performs the backing's explicit scalar cast, while
implicit conversion remains forbidden in either direction. Explicit scalar casts extract one
layer:
```bro
UserID :: distinct u32
OuterID :: distinct UserID
id UserID :: UserID(u32(42))
index usize = 42
id UserID :: UserID(index)
raw u32 :: u32(id)
outer OuterID :: OuterID(id)
inner UserID :: UserID(outer)
@@ -1079,7 +1082,8 @@ Scalar-backed distinct values retain their nominal type across the operations su
backing scalar. Integer forms support checked arithmetic, bitwise operations, shifts, comparisons,
compound assignments, indexing, slicing, and `minval!` / `maxval!`; float forms support arithmetic
and comparisons; boolean forms support equality and inequality. Separate distinct identities and
typed backing operands never mix, though literals receive the distinct context. Runtime and
typed backing operands never mix implicitly or in ordinary operations; crossing between numeric
representations requires an explicit constructor or scalar cast. Runtime and
comptime rules are identical. Reflection reports the immediate backing, while standard formatting
recursively follows nested distinct backings to the final scalar.