Skip to content

Commit 5970279

Browse files
committed
transpiler: materialize local new_const consts via factories
1 parent e621cbe commit 5970279

File tree

3 files changed

+101
-3
lines changed

3 files changed

+101
-3
lines changed

TODO.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,23 @@ Work on tasks defined in TODO.md. Repeat the following steps, don’t stop until
12091209
- `tests/transpile_tests/run_parity_matrix.sh --work-root /tmp/rusty-parity-matrix-27-10-2-1775515714 --keep-work-dirs`
12101210
- [x] *done* Guardrail check against wrong-approach section (`docs/rusty-cpp-transpiler.md` §11): maintained deterministic first-head discipline, recorded canonical matrix artifacts before opening the next implementation leaf, and avoided crate-specific rewrites/scripts.
12111211
- [ ] Leaf 4.15.4.3.3.3.3.3.27.11: Collapse the post-27.10.2 deterministic Stage D constexpr constructor/template family generically (starting with `ArrayVec<rusty::Vec<uint8_t>, 10>::new_const()` literal-type/copy fallout rooted at `runner.cpp:4293`), add fixture-agnostic regressions, then re-run full seven-crate matrix.
1212-
- [ ] Leaf 4.15.4.3.3.3.3.3.27.11.1: Implement generic transpiler/runtime fixes for the first deterministic 27.10.2 head (no crate-specific scripts): align const-constructor/literal-surface lowering so non-literal container types are not forced into invalid `constexpr` materialization patterns while preserving valid const-generic behavior.
1212+
- [x] *done* Leaf 4.15.4.3.3.3.3.3.27.11.1: Implement generic transpiler/runtime fixes for the first deterministic 27.10.2 head (no crate-specific scripts): align const-constructor/literal-surface lowering so non-literal container types are not forced into invalid `constexpr` materialization patterns while preserving valid const-generic behavior.
1213+
- [x] *done* Scope/plan analysis for 27.11.1:
1214+
- implementation size stayed under the <1000 LOC budget (small, shape-gated transpiler lowering + focused regressions), so no additional leaf decomposition was needed.
1215+
- [x] *done* Implemented generic const-constructor materialization fix in `transpiler/src/codegen.rs`:
1216+
- for block-local `const` items initialized by zero-arg `new_const()` constructor calls, emit factory-form local constants (`const auto NAME = []() -> Ty { return Ty::new_const(); };`) and lower path uses to `NAME()` so each use materializes a fresh value.
1217+
- this avoids invalid C++ `constexpr` object requirements and const-lvalue copy constraints on non-literal/non-copyable payload types without introducing crate-specific rewrites.
1218+
- [x] *done* Added focused fixture-agnostic transpiler regressions in `transpiler/src/codegen.rs`:
1219+
- `test_leaf41543333333327111_local_new_const_uses_factory_materialization`
1220+
- `test_leaf41543333333327111_local_scalar_const_stays_constexpr`
1221+
- [x] *done* Re-probed `arrayvec` parity after 27.11.1 (`tests/transpile_tests/run_parity_matrix.sh --crate arrayvec --work-root /tmp/rusty-parity-matrix-27-11-1-1775516598 --keep-work-dirs`):
1222+
- prior deterministic first hard error family at `runner.cpp:4293` (`constexpr ArrayVec<rusty::Vec<uint8_t>, 10> OF_U8 = ...::new_const()` literal/copy fallout) is removed from the first slot.
1223+
- new deterministic Stage D first hard error now starts at `runner.cpp:4317` (`cannot convert Vec<int> to Vec<unsigned char>` in `test_arrayvec_const_constructible`), with adjacent downstream diagnostics continuing after that head.
1224+
- canonical artifacts: `/tmp/rusty-parity-matrix-27-11-1-1775516598/arrayvec/{baseline.txt,build.log,run.log,matrix.log}`.
1225+
- [x] *done* Verification for 27.11.1:
1226+
- `cargo test -p rusty-cpp-transpiler`
1227+
- `tests/transpile_tests/run_parity_matrix.sh --crate arrayvec --work-root /tmp/rusty-parity-matrix-27-11-1-1775516598 --keep-work-dirs`
1228+
- [x] *done* Guardrail check against wrong-approach section (`docs/rusty-cpp-transpiler.md` §11): maintained deterministic first-head discipline, used shared AST-aware shape-gated lowering (no text patching / no blanket rewrites), and avoided crate-specific scripts.
12131229
- [ ] Leaf 4.15.4.3.3.3.3.3.27.11.2: Re-run full seven-crate parity matrix after 27.11.1, record first deterministic failure head with canonical artifacts, and update active-frontier docs/TODO status (or mark Leaf 4 complete if all seven pass).
12141230
- [ ] Leaf 5: Verification matrix (required)
12151231
- [x] *done* Add an integration parity matrix test that runs `parity-test --stop-after run` for `either`, `tap`, `cfg-if`, `take_mut`, `arrayvec`, `semver`, and `bitflags`

docs/rusty-cpp-transpiler.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,8 +2439,22 @@ Active work items:
24392439
- verification:
24402440
- `tests/transpile_tests/run_parity_matrix.sh --work-root /tmp/rusty-parity-matrix-27-10-2-1775515714 --keep-work-dirs`
24412441
- guardrail check against wrong-approach checklist (§11): maintained deterministic first-head discipline, recorded canonical matrix artifacts before opening the next implementation leaf, and introduced no crate-specific rewrites.
2442-
52. Current active next leaf is `Leaf 4.15.4.3.3.3.3.3.27.11.1`.
2443-
- focus: collapse the new post-27.10.2 first deterministic constexpr constructor/template head generically, then verify matrix-head movement.
2442+
52. `Leaf 4.15.4.3.3.3.3.3.27.11.1` is complete.
2443+
- plan/scope check: fix stays under the small-change budget (<1000 LOC), so no extra leaf decomposition was needed.
2444+
- implemented generic local const-constructor materialization hardening in `transpiler/src/codegen.rs`:
2445+
- added shape-gated local-const detection for zero-arg `new_const()` constructor calls inside block scope,
2446+
- such local consts now emit as factory-form locals (`const auto NAME = []() -> Ty { return Ty::new_const(); };`) and path uses lower to `NAME()` to materialize fresh values per use.
2447+
- added fixture-agnostic transpiler regressions:
2448+
- `test_leaf41543333333327111_local_new_const_uses_factory_materialization`
2449+
- `test_leaf41543333333327111_local_scalar_const_stays_constexpr`
2450+
- single-crate reprobe (`tests/transpile_tests/run_parity_matrix.sh --crate arrayvec --work-root /tmp/rusty-parity-matrix-27-11-1-1775516598 --keep-work-dirs`) removed the prior deterministic first hard error at `runner.cpp:4293` (`constexpr ArrayVec<rusty::Vec<uint8_t>, 10> OF_U8 = ...::new_const()` non-literal/copy fallout).
2451+
- new deterministic first hard error now starts at `runner.cpp:4317` (`cannot convert Vec<int> to Vec<unsigned char>` in `test_arrayvec_const_constructible`), with canonical artifacts at `/tmp/rusty-parity-matrix-27-11-1-1775516598/arrayvec/{baseline.txt,build.log,run.log,matrix.log}`.
2452+
- verification:
2453+
- `cargo test -p rusty-cpp-transpiler`
2454+
- `tests/transpile_tests/run_parity_matrix.sh --crate arrayvec --work-root /tmp/rusty-parity-matrix-27-11-1-1775516598 --keep-work-dirs`
2455+
- guardrail check against wrong-approach checklist (§11): maintained deterministic first-head discipline, used shared AST-aware shape-gated lowering (no text patching / no blanket rewrites), and introduced no crate-specific scripts.
2456+
53. Current active next leaf is `Leaf 4.15.4.3.3.3.3.3.27.11.2`.
2457+
- focus: re-run full seven-crate parity matrix after 27.11.1 and capture the next deterministic frontier (or close Leaf 4 if all pass).
24442458

24452459
### 10.7 Parity Harness and Matrix Command Reference
24462460

transpiler/src/codegen.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,6 +2943,26 @@ impl CodeGen {
29432943
}
29442944
}
29452945

2946+
fn is_local_new_const_constructor_call(&self, expr: &syn::Expr) -> bool {
2947+
if self.block_depth == 0 {
2948+
return false;
2949+
}
2950+
let syn::Expr::Call(call) = self.peel_paren_group_expr(expr) else {
2951+
return false;
2952+
};
2953+
if !call.args.is_empty() {
2954+
return false;
2955+
}
2956+
let syn::Expr::Path(path_expr) = self.peel_paren_group_expr(call.func.as_ref()) else {
2957+
return false;
2958+
};
2959+
path_expr
2960+
.path
2961+
.segments
2962+
.last()
2963+
.is_some_and(|seg| seg.ident == "new_const")
2964+
}
2965+
29462966
fn emit_const(&mut self, c: &syn::ItemConst) {
29472967
if self.is_rust_libtest_metadata_type(&c.ty) {
29482968
let marker =
@@ -2954,6 +2974,25 @@ impl CodeGen {
29542974
));
29552975
return;
29562976
}
2977+
if self.is_local_new_const_constructor_call(&c.expr) {
2978+
let rust_name = c.ident.to_string();
2979+
let cpp_name = self.allocate_local_cpp_name(&rust_name);
2980+
self.register_local_binding(rust_name.clone(), Some((*c.ty).clone()));
2981+
self.record_local_const_binding(&rust_name, false);
2982+
2983+
let ty = self.map_type(&c.ty);
2984+
let expr = self.emit_expr_to_string_with_expected(&c.expr, Some(&c.ty));
2985+
self.writeln(&format!("const auto {} = []() -> {} {{", cpp_name, ty));
2986+
self.indent += 1;
2987+
self.writeln(&format!("return {};", expr));
2988+
self.indent -= 1;
2989+
self.writeln("};");
2990+
2991+
if let Some(scope) = self.local_cpp_bindings.last_mut() {
2992+
scope.insert(rust_name, format!("{}()", cpp_name));
2993+
}
2994+
return;
2995+
}
29572996
let name = &c.ident;
29582997
let ty = self.map_type(&c.ty);
29592998
let expr = self.emit_expr_to_string_with_expected(&c.expr, Some(&c.ty));
@@ -17740,6 +17779,35 @@ mod tests {
1774017779
assert!(out.contains("constexpr int32_t MAX = 100;"));
1774117780
}
1774217781

17782+
#[test]
17783+
fn test_leaf41543333333327111_local_new_const_uses_factory_materialization() {
17784+
let out = transpile_str(
17785+
r#"
17786+
fn f() {
17787+
const OF_U8: ArrayVec<Vec<u8>, 10> = ArrayVec::new_const();
17788+
let mut var = OF_U8;
17789+
var.push(Vec::new());
17790+
}
17791+
"#,
17792+
);
17793+
assert!(out.contains("const auto OF_U8 = []() -> ArrayVec<rusty::Vec<uint8_t>, 10> {"));
17794+
assert!(out.contains("auto var = OF_U8();"));
17795+
assert!(!out.contains("constexpr ArrayVec<rusty::Vec<uint8_t>, 10> OF_U8"));
17796+
}
17797+
17798+
#[test]
17799+
fn test_leaf41543333333327111_local_scalar_const_stays_constexpr() {
17800+
let out = transpile_str(
17801+
r#"
17802+
fn f() {
17803+
const N: usize = 4;
17804+
let _x = N;
17805+
}
17806+
"#,
17807+
);
17808+
assert!(out.contains("constexpr size_t N = 4;"));
17809+
}
17810+
1774317811
#[test]
1774417812
fn test_c_like_enum() {
1774517813
let out = transpile_str("enum Color { Red, Green, Blue }");

0 commit comments

Comments
 (0)