You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add built-in trait bounds (Copy, Eq, Send) on generic type parameters with monomorphization-time checking, spec updates, integration tests, and LSP diagnostics for bound violations.
@@ -651,7 +652,8 @@ Ion supports a **local, Hindley–Milner-inspired inference**:
651
652
The inference engine is intentionally limited:
652
653
653
654
- No higher-rank polymorphism.
654
-
- No complex trait constraints; only simple, **structural**`Send` constraints. For a generic type `Wrapper<T>`, each monomorphized instantiation `Wrapper<U>` is `Send` if and only if all of its fields (with `T` replaced by `U`) are `Send`.
655
+
- Generic type parameters may declare optional **trait bounds** (`Copy`, `Eq`, `Send`). Bounds are checked at monomorphization: each concrete instantiation must satisfy every bound on the corresponding parameter. There are no user-defined traits; bounds name structural capabilities checked by the compiler (see Section 4.8).
656
+
- Structural `Send` still applies per instantiation even without an explicit bound: for a generic type `Wrapper<T>`, each monomorphized `Wrapper<U>` is `Send` if and only if all of its fields (with `T` replaced by `U`) are `Send`.
655
657
656
658
#### 4.5 Type Casting and Array Assignment
657
659
@@ -677,6 +679,25 @@ The inference engine is intentionally limited:
677
679
-**Match guards**: `pattern if expr => { ... }` where `expr` must be `bool`.
678
680
-**Struct-style enum variants**: `enum E { Ok { value: int }; }` with matching literals and patterns.
679
681
682
+
#### 4.8 Trait Bounds on Generics
683
+
684
+
Generic functions, structs, enums, and type aliases may declare bounds on type parameters:
Syntax: `identifier : Bound [ + Bound ... ]` after each type parameter name. Bounds are **built-in identifiers** only; there is no `trait` declaration syntax.
692
+
693
+
| Bound | Meaning (structural) |
694
+
|-------|----------------------|
695
+
|`Copy`| Type is copied rather than moved at the ownership level (primitives, references, function pointers). |
696
+
|`Eq`| Type supports `==` and `!=` with correct semantics (primitives, `String`, references, arrays and tuples of `Eq` types, structs and enums whose fields or payloads are all `Eq`). |
697
+
|`Send`| Type may cross thread boundaries (Section 7.3). |
698
+
699
+
At each monomorphization site (generic call, struct or enum construction, type-alias substitution), the compiler substitutes concrete types for parameters and rejects any instantiation where a concrete type does not satisfy a declared bound. Unknown bound names are rejected at the declaration site.
700
+
680
701
### 5. Ownership and Borrowing
681
702
682
703
#### 5.1 Ownership
@@ -715,7 +736,7 @@ fn main() {
715
736
716
737
By default, Ion types are **move-only**. For a small subset of primitive types (e.g., `int`, `bool`, pointers), the implementation may treat moves as cheap copies, but the semantic model is still “move”.
717
738
718
-
Ion does not expose a `Copy`marker to user code; whether a move is implemented as a copy is an implementation detail.
739
+
Whether a move is implemented as a copy is an implementation detail. The `Copy`bound on generic parameters (Section 4.8) names types that are copied rather than moved at the ownership level.
719
740
720
741
After an `if` statement, ownership is merged from branches that can reach the following code. Branches that always `return`, `break`, or `continue` are omitted from the merge. If two fall-through paths disagree on whether a binding is still valid, the compiler reports an error.
721
742
@@ -1253,7 +1274,7 @@ and [docs/ABI.md](docs/ABI.md). Features listed below are either intentionally
1253
1274
constrained in the beta subset or unstable until a later release documents a
1254
1275
stronger contract.
1255
1276
1256
-
-No trait bounds on generics
1277
+
-Trait bounds are limited to built-in `Copy`, `Eq`, and `Send` (no user-defined traits)
1257
1278
- String `for...in` iterates bytes (`u8`), not Unicode code points or graphemes
1258
1279
-`if`/`else` merge: ownership after an `if` is merged from branches that can fall through to the following code. A move in a branch that always `return`s, `break`s, or `continue`s does not block use after the `if`. If two fall-through paths disagree (one moved, one valid), it is still an error.
1259
1280
-`while`/`for` loops: a non-copy variable moved anywhere in the loop body is an error (repeated iteration would need the binding again); copy types and borrows are unchanged. For read-only scans over an owned `Vec<T>`, prefer `Vec::get_ref` (Section 8.2) or index/handle helpers; `Vec::get` move-out still requires consume-once or put-back per iteration.
0 commit comments