Skip to content

Commit c28991c

Browse files
committed
Fix IR generic monomorphization to infer function-pointer types from program signatures when a generic call's first argument is a function identifier, enabling identity(add_one) and similar Copy-bounded instantiations to codegen correctly.
1 parent aa1c3cb commit c28991c

8 files changed

Lines changed: 377 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## 2026-07
44

55
- **VM-style idioms**: `match` on `&Enum` from `Vec::get_ref`; struct field assignment and `+=` on owned/`&mut` paths; method desugaring (`vec.push`, `vec.get_ref`) with correct borrows; nested generic types (`Vec<Vec<int>>`); match-arm control-flow unification (`break`/`return` with value arms); `&str` call-site coercion; enum literals in `Vec::push`/`set` without double-wrapped C; `&mut Struct` field access via `->` in codegen. Integration tests and examples `bytecode_vm`, updated `showcase`, `todo_demo`, `http_server`, `text_summary`. Fix extern call typing so `&T` arguments match `&T` parameters (no erroneous copy-type ref stripping). Fix `Option<T>` match codegen to use the scrutinee type instead of the first registered monomorph. Former negative match-arm rvalue tests now pass as positive runs.
6-
- **Trait bounds follow-up**: ION_SPEC §4.8 `Eq` row documents function pointers; integration test `test_trait_bound_eq_fn_ok`; method-call signature help threads generic bounds through `fn_hover_doc`.
6+
- **Trait bounds follow-up**: ION_SPEC §4.8 `Eq` row documents function pointers; integration test `test_trait_bound_eq_fn_ok`; method-call signature help threads generic bounds through `fn_hover_doc`. Fix IR generic monomorphization when the first type argument is a function identifier (`identity(add_one)`): infer fn-pointer types from program signatures so mangled instantiations are emitted and call sites use the correct name. Integration test `test_trait_bound_copy_fn_ok`; `examples/trait_bounds` exercises `identity(add_one)`.
77

88
## 2026-06
99

examples/trait_bounds/ion.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name = "trait_bounds"
2+
main = "trait_bounds.ion"
3+
output = "trait_bounds"
4+
mode = "single"
5+
out_dir = "target"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Built-in trait bounds on generic parameters: Copy, Eq, Send.
2+
// Bounds are checked at monomorphization; each helper is instantiated with a concrete type.
3+
4+
fn identity<T: Copy>(value: T) -> T {
5+
return value;
6+
}
7+
8+
fn values_equal<T: Eq>(a: T, b: T) -> bool {
9+
return a == b;
10+
}
11+
12+
fn hold_send<T: Send>(value: T) -> int {
13+
let _held: T = value;
14+
return 1;
15+
}
16+
17+
fn add_one(x: int) -> int {
18+
return x + 1;
19+
}
20+
21+
fn main() -> int {
22+
// Copy: int satisfies Copy at instantiation.
23+
let n: int = identity(21);
24+
if n != 21 {
25+
return 1;
26+
}
27+
28+
// Copy: function pointers satisfy Copy; identity(add_one) must monomorphize.
29+
let h: fn(int) -> int = identity(add_one);
30+
if h(4) != 5 {
31+
return 5;
32+
}
33+
34+
// Eq: primitives and function pointers support ==.
35+
if !values_equal(10, 10) {
36+
return 2;
37+
}
38+
let f: fn(int) -> int = add_one;
39+
let g: fn(int) -> int = add_one;
40+
if !values_equal(f, g) {
41+
return 3;
42+
}
43+
44+
// Send: int is safe to pass into a Send-bounded generic.
45+
if hold_send(n) != 1 {
46+
return 4;
47+
}
48+
49+
return 0;
50+
}

0 commit comments

Comments
 (0)