Repository navigation
Delete rules for vector<vector<T>> and for nested containers - #530
Conversation
commit faa6d928c58b144648a61c1c3c2847397c45bfbc
Merge: 943b49750 72bb583d7
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 15:43:19 2026 +0100
Merge branch 'master' into issue-15
commit 943b49750111c5053cde8e92866386960c158654
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 15:39:03 2026 +0100
Don't clone entire row on global access
commit 434c7bbf506a7fa95f529c67ef1870556b3532dc
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:56:15 2026 +0100
Add UB tests
commit 03d04950cd299eabd790fb7db25cc496bcb59e27
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:50:20 2026 +0100
Update docs
commit 1240976194f7676d7870e607492aab8c973997d3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:45:05 2026 +0100
Add reinterpret for nested pointers
commit 97cfa97bbf59db6f73e7b424fc6bbe25344a12a2
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:44:20 2026 +0100
Update tests
commit b0f2819648b1583f42c216250acb9ac3a2b38e6f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:36:14 2026 +0100
Fix pointer subscript
commit 8d675d13945efee622952b052e02b27ae5d3877c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:15:56 2026 +0100
Fix imbricated access for array
commit ce937c1eb124111e194abd5f200a3cefc28de1ab
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:08:56 2026 +0100
Update tests
commit 3a0358fa56d2db56c5579a95a0cfbb568ab9f8b3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:03:34 2026 +0100
Drop boxing for multi dimensional arrays
commit 9118872d0ca88012d31204091d9b43e049474a79
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 14:00:09 2026 +0100
Add library support for multi dimensional containers
commit c157d41ba52103a960a018c1f340bac20528c05c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 13:59:53 2026 +0100
Drop Value from imbricated containers
commit 6b083f6235f153f2cd8eb0948b783d9f14a30239
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 13 13:53:58 2026 +0100
Delete vector<vector> rules
commit 78d6570714b4eacb601f613e98c89306d17447ab
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Oct 12 21:35:16 2026 +0100
Fix list initializers for unions (#514)
commit e7d20118c6ddf771c25a9a5b90c0c82e1138de02
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Oct 12 15:15:52 2026 +0100
Format rules (#528)
commit ba095717c5fee13684d9e865095e892b15565361
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Oct 12 10:39:46 2026 +0100
Name anonymous records (#521)
commit cd5b552d100b47110bdba4db8d8368a24b62dfd7
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Oct 12 10:21:23 2026 +0100
Delete abstract_structs_ (#526)
We don't need extra state to translate abstract structs.
commit eacf79e9fa09adcfaba29698aba496dc8fe9458a
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Oct 12 10:20:27 2026 +0100
Escape Rust keywords (#519)
commit 6627b2f75b2f6e9620130ba8fe6d0d29f4e87387
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Oct 12 10:19:57 2026 +0100
Call printf rule when the format string is not static (#508)
commit d343b2777a8d0c56c398a533f9c8a3412bb2024c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 11 21:11:14 2026 +0100
Skip elidable constructors (#525)
commit 6e47d5b61b3a027b84f5c48926e4520ff12c1f22
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 11 15:59:50 2026 +0100
Fix woff2 build after #523 (#524)
I realized that #523 fully works only with the new AST matcher because
of const types: string matcher matches strings which is broken for const
pointers in general. Until the AST matcher lands I fixed the string
matcher.
commit 80c214f82b8620fece91c7842b76118cce30d0a8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 11 13:51:19 2026 +0100
Remove converter hack around std::map::iterator (#523)
The old code special cased `std::map::iterator` (which is just a sugar
for `std::pair<const K, V>`) to generate `i.first()` and `i.second()`
instead of `i.0` and `i.1`.
This PR removes the hack by saving a pair in `libcc2rs::MapIter` which
can be accessed with `.0` and `.1`. It also fixes a translation bug:
```cpp
for (auto i : m) {
i.second = -1;
assert(i.second == -1);
}
for (const auto &i : m) {
assert(i.second != -1);
}
```
commit a447c09c3d45100afa8ddeaeb38f2ac5ed144807
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 11 08:15:51 2026 +0100
[NFC] Pass Converter to Mapper (#450)
The current string matcher must save string rules for user defined
types. For example `std::vector<UserDefinedRecord>` works by first
applying the string rule for vector then the string rule for
UserDefinedRecord.
The new AST matcher (#447) won't need string rules for user defined
types. After applying the rule for vector it will ask Converter to print
UserDefinedRecord.
I also added a test that fails with a current matcher and will pass with
the AST matcher: `std::vector<S *const *>`. There is no string rule for
`S * const *` and the current matcher panics.
commit 79fd877916655b1f46140a98aa85a2a31d1fb1e9
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 11 08:14:21 2026 +0100
Translate va_list references and pointers (#522)
commit 2411760b3e1e819b20d341b5eaf545129314594c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 11 08:11:22 2026 +0100
Write mutable fields through const objects (#520)
commit 86861510dfea6a3807cb0c5d86d8555c6fecbfb0
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sat Oct 10 12:41:58 2026 +0100
Fix clang 24 build
commit 69fdca5d94c4b078d0d7f2e466baa3cc8ed04227
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 12:24:22 2026 +0100
Selectively load rules in the same TU as the translated code (#451)
Part of #447. This only loads the rules into cpp2rust, AST matching
comes in a future PR:
> To implement this, rules are included in the translated TU. Only the
rules that parse are kept. If the TU never included <map> then there are
no rules for map. This is faster than the string matching approach.
cpp_rule_indexer runs at build time to build an index of rules. This
index is used by rule_loader to lazily load the rules into the converter
for doing AST matching.
There are 2 index files: one for C code and one for C++ code. Both live
in build/rules_index. C translated code only loads the C index, C++
translated code loads both indexes.
Example of index:
```
key: std/vector/push_back
requires: std/vector
dir: vector
text:
template <typename T1> void f14(std::vector<T1> &o, T1 &&value) {
return o.push_back(std::move(value));
}
key: std/basic_ifstream/rdbuf
requires: std/basic_ifstream, std/basic_filebuf
dir: ifstream
text:
std::filebuf *f4(const std::ifstream &o) { return o.rdbuf(); }
```
`key` is generated using the dependent name of the rules for templates
and using the concrete name for non-templates. `text` is extracted from
the file and appended into the translated TU if it needs the rule.
`requires` only loads the rule in the TU if the translated code uses all
the dependencies, basic_ifstream and basic_fielbuf in the example.
This makes the translation fast. With 100K dummy rules, it takes on
avergage 20ms per invocation to selectively load the rules. With full
loading of all the 100K dummy rules, it takes 5 seconds on average.
commit ebb7f176804416fd5996346e93e7e91e97b3d70d
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sat Oct 10 11:54:35 2026 +0100
fix tests
commit 4701d294776ee363faa76e9df50b394e16926ad3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 11:37:07 2026 +0100
Skip explicit specializations of template functions (#517)
commit ce92121d0f63fe70f543474626fba7f9059b1d17
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 11:35:34 2026 +0100
Set computed expression type for default args and init lists (#516)
commit b0cddeb77da7b1d55619dace8006ec7488a2f15a
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 11:34:51 2026 +0100
Fix lambda calls, parameters, captures and namespace-scope lambdas (#501)
In VisitCallExpr convert the arguments of the operator call in Unboxed
context to avoid unnecessary Value boxes
Use ConvertVarDeclSkipInit to convert the params of the operator call so
that it can add mut where needed
PushConstInitializer(false) before converting the body of lambda to fix
translation of global lambdas
Call the move constructor when the lambda is moved
Fix generic lambdas with no specialisations in libcc2rs-macros
Fix lambda in lambda syntax in libcc2rs-macros
commit b7476ab50a67316c81eea3c0753166afb3597629
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 08:16:03 2026 +0100
Fix signed printing of integers (#511)
commit 99206c57f4947c6a3ba3646f8a7bac00fd4033e0
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 08:12:55 2026 +0100
Translate unsafe Default in unsafe context (#509)
commit 43d63624f52cb770996cc3c3e9062032416657a5
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 08:09:33 2026 +0100
Fix delete for const pointers (#513)
commit 5c0309a5b38288016ccd9cdc7cead0d11f13010f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 08:09:16 2026 +0100
Push init type in materialized temporaries (#512)
commit 32c5b1f830f258a3245e819e278340e663960601
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 08:03:30 2026 +0100
Make const variables that need destruction mut in unsafe (#515)
commit 2ae262e13dd8669ef90320279d5654ca54ffab42
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Oct 10 07:59:33 2026 +0100
Accept the j format specifier and escape braces in printf (#518)
commit e6c335eadc1f30dd56a6970871d6030f31efa8f8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 19:05:28 2026 +0100
Fix variables named _ (#502)
commit e986cc86236699bb95923a94f4e33a14484d84f5
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 18:57:15 2026 +0100
Fix Default for floating types and floating to boolean casts (#505)
commit 1757106b8a31eb0d60bca8ad340f7b7a8dda91d2
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 18:56:24 2026 +0100
Fix converter crashes around freshness (#503)
commit 29ff9cd90b3aaad2772cd0e11193254fa49bf9fc
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 18:55:43 2026 +0100
Fix Default for enums with bool underlying type (#504)
commit c5fbc922ed8901a79c280acddd4e796366e2919e
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 18:55:00 2026 +0100
Extend arity of function pointer arguments (#507)
commit ab5265de2b8f07e6867c2d9befb89c737ff07cd5
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 18:54:42 2026 +0100
Fix const_cast for references (#506)
commit 0834e8884eff3fd872620efc008d631424b560d0
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 13:56:05 2026 +0100
Translate self referencing initialiser (#498)
Fixes the original issue reported in #248. Self-refrencing in
constructors is not handled here.
It translates:
```cpp
struct list_head list = { &list };
```
to:
```rs
let list: Value<list_head> = <Value<list_head>>::default();
*list.borrow_mut() = list_head {
next: (list.as_pointer()),
};
```
That is, first create a default value, then assign it the
self-referencing initialiser. Types that have defaults with side-effects
are not supported.
commit c4276ba0126554ed86e08248a47bbf27a584cfaa
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 11:00:49 2026 +0100
Fix lambdas that receive pack captures (#500)
commit fcee2ce0b70eef2eade0900e850ef8adfb3c0f6c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 9 10:59:56 2026 +0100
Translate generic lambdas (#499)
commit dd4b7eb7df84c4a1e59b7ce3ea6c1ceb0f489c99
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Oct 8 20:50:25 2026 +0100
Simplify lambda translation by using macros to infer copy/move/destruct automatically
commit e8961cf10534a76a3b6fd14d5eb71268b3f28d83
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 19:40:33 2026 +0100
Allow move-only types to implement FnPtrArg (#476)
commit 5741a8d62b82990d6ce658277eaebaea01f54d33
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 15:53:55 2026 +0100
Translate moveable/copyable/destroyable lambdas (#458)
commit fd1f8c804a2384290e92468a143699e09ff1f09e
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Oct 8 15:51:20 2026 +0100
Fix bug in printf %c
commit f4f82ae467383dafd7eb1f8ec51d026609823736
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 13:59:09 2026 +0100
Translate C99 flexible array member (#473)
commit 478bd1823ff5e886104917e643fe138a76087641
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 13:50:31 2026 +0100
Translate comparison operators that don't return bool (#496)
commit cf6b6a01824f9fbb38c94a15b6c4f434619bf79e
Author: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Thu Oct 8 12:16:57 2026 +0100
Remove unnecessary `unsafe` from time refcount rules (#495)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
commit 8dfc4d2cd7d645e98e193e585d00be3046b8c122
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 12:07:44 2026 +0100
Add standard-version ifdefs in rules (#448)
Part of #447
commit abb9792bb41c863de58df7f63ec01c3743812855
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 12:03:32 2026 +0100
Hoist static locals to module scope (#491)
commit c700ce65458ceb0c8c928426567c549a67ca6355
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 12:02:04 2026 +0100
Fix array pointer dereference and temporary array materialisation (#487)
commit 5d79b189c7815c3614e92d0999fbb152e9743eb8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 11:59:19 2026 +0100
Fix mismatched usize/u64 array element type (#494)
Closes #320
commit 5a49110f7e24f3de5fbf8ace789546b1fe4fb9bb
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 10:38:26 2026 +0100
Print float literals at full precision (#483)
commit 0d92094f6e16a2347d6b195a066dc32bb3eb3565
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 09:39:27 2026 +0100
Emit clang-computed sizeof values in refcount (#490)
commit 5eb6fd10f26d5e76373f9fd52ecdb3ef634901b3
Author: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Thu Oct 8 09:12:51 2026 +0100
Fix `std::find` refcount rule when the first iterator has a non-zero offset (#493)
The refcount `std::find` rule compared a relative `enumerate` index
against the absolute `a1.get_offset()`. If `a0` didn't start at offset
0, the bound was too large, so the search could run past `last`.
- Fixes #456
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
commit 6d6f83cd35c5405e810f87d9f6f57b42645145c5
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:31:38 2026 +0100
Skip explicit template instantiation declarations (#481)
commit 9e57ef73a63a12907ceb82dc3a43e269900f0ef5
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:31:23 2026 +0100
Distinguish declarations from one macro expansion in decl IDs (#485)
commit cb82dad9d013188ae6b804fbe002b10a236f0bcb
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:31:08 2026 +0100
Translate references to functions as function pointers (#486)
commit 585798adfccdc40f5bf6b3e6f0bfb614935469ab
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:22:17 2026 +0100
Translate only the taken branch of constant if conditions (#488)
```cpp
template <typename T> unsigned long long widen(T v) {
if (sizeof(T) > 4) {
T hi = v;
hi <<= 32;
return hi;
}
return v;
}
```
The code inside if is not compilable. `hi <<= 32` is a compilation error
in rust when T = int.
commit f68ce854f8ed9dda46a0a10426fd73f194be6411
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:18:40 2026 +0100
Translate out-of-line copy constructors (#489)
commit 2e92ab3ca0851db6665cffbade334cf21ce1e71a
Author: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Thu Oct 8 08:17:10 2026 +0100
Preserve first-element semantics in max_element translations (#479)
`std::max_element` returns the first iterator when multiple elements
share the maximum, but the Rust translations selected the last. This
affected vector rules f42/f94 and algorithm rule f8.
- Fixes #454
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
commit 9190c3c3ac9d3790bd29142b85776da1a9df8baa
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:16:06 2026 +0100
Treat u8 literals by their element type (#492)
Pre C++-20 u8 literals were `const char*`, post C++-20 they are `const
char8_t*`
commit cca70e234b8521adcd8318155985ebe8bdd9a69d
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:13:28 2026 +0100
Translate transparent init lists (#484)
commit 6661085aa791ee81f84a0ac61d2a1cf863918fde
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Oct 8 08:05:41 2026 +0100
Return 0 when main falls off its end (#482)
commit 4e953e4c75abd7d07e11d23aa11ed0e92c997199
Author: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Wed Oct 7 20:53:57 2026 +0100
Initialize empty `std::string` values with a null terminator (#478)
The `std::string` rules model strings as null-terminated vectors, but
default initialization produced an empty vector. Operations such as
`length()` then incorrectly assume a terminator exists.
- **Type rules:** Initialize default strings with `vec![0]` in both
unsafe and refcount models.
- **Regression coverage:** Add a default-constructed string case that
checks `length()`.
```cpp
std::string empty;
assert(empty.length() == 0);
```
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #455
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
commit 488bee6f7003caaebabe7991c79dcf521f68a079
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 19:38:24 2026 +0100
Don't use uninstantiated copy constructor (#477)
commit 5911673b6df4c1453e81b1515c40c699df93cffe
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 14:59:13 2026 +0100
Translate SourceLocExpr (#468)
commit 9263f5d4b685fc1350123db700b985c6f876cbac
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 14:58:23 2026 +0100
Move reinterpret cast OOB tests in tests/ub (#475)
commit 8c3cee8e90107ec713f1c4dc6dcb5e169a147552
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 12:30:11 2026 +0100
Access unions through `Ptr<Self>` (#474)
Fixes #311
commit d546c8cd3e8f0c815ca3f3032c52ff2b78d6645f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 12:27:14 2026 +0100
Visit linkage spec decls and skip class template specializations (#467)
commit 4efff884ff53c32c606f3c0bf3d564adfe44cd08
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 12:26:15 2026 +0100
Add i128/u128 inc/dec and i64 Ptr add/sub (#466)
commit 485d6bbf90187d202876d34e234ea90bbc41cdea
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 12:16:38 2026 +0100
Evaluate static_assert conditions in constant context (#469)
commit 6f6d359e163f95473000f925c0fcc5c63ca09493
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 11:09:23 2026 +0100
Emit bool values for enums with bool underlying type (#470)
commit eb92b55fd0581f03f11ae226c4eef7292de6fac2
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 10:54:40 2026 +0100
Update derives for unions and opaque records (#471)
commit 8e6b297b2acc7e35415c8dc4f5a6e6d3960ba50f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 10:51:56 2026 +0100
Fix lvalue and address of conditional operator (#472)
commit 9f80cb2f9928940a190563563738403e1727cce8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 10:48:42 2026 +0100
Translate noexcept expressions (#462)
Rust has no equivalent for noexcept, let clang do the computation.
commit a16b44fed42761a06ab2737431f12932e3b8e085
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 10:47:16 2026 +0100
Use fresh rvalues for comma operands and materialized temporaries (#461)
Fixes miscompilations, rvalue comma operands should be cloned, not
moved.
commit 405fdc480adb337295e739c0b97b6728c933b8e1
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 10:44:48 2026 +0100
Name user-defined literal operators (#463)
commit 55e814ab60200a3a3668661210517159e20eb540
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Oct 7 10:44:00 2026 +0100
Skip methods with undeduced return type (#465)
commit e3fd97157eb0012b7c7de209d475e372f647d2da
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 6 22:07:09 2026 +0100
Evaluate default arguments lazily and support reference defaults (#459)
The old `arg.unwrap(default_value)` pattern unconditionally evaluated
default_value. This is wrong if default_value has side effects and the
default value is never used.
Also fix default arguments bound to reference arguments.
commit d8aa9c42b23f6e743cebad0c583eeaace2cad44b
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Oct 6 21:15:12 2026 +0100
Translate delete nullptr as no-op (#457)
delete nullptr is no-op in C++. It's wrong to translate it to
`drop(Box::from_raw(null()))` because it triggers unsafe precondition
violation.
Skip the drop call when the deleted pointer is nullptr.
commit 004a9050788593c01ef9158bf2978e9e100788d3
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Tue Oct 6 11:09:59 2026 +0100
Unbox local vectors and issue straight [] accesses instead of going through Ptr
commit d6ced87e1e5a2dae4501b43ab0e85793ee4e1081
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Tue Oct 6 09:06:59 2026 +0100
Unbox holders of std::unique_ptr
commit 8067fe934468f0aada39460d7c87e029149bc285
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 22:28:08 2026 +0100
Move instead of clone for returned vars
commit cfdccf1d04b04d564b2c4536d7d9290f96c3342e
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 21:58:38 2026 +0100
Address taken analysis: dig into initializer lists
commit 373a36f4747f9276a4e0653efa799613a84fb59b
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 18:00:04 2026 +0100
Unbox struct locals and optimize compound ptr assignments to not copy the pointer
Around 40% speedup on Brunsli
commit f0f836e29ac3552eefa7c484fcd6f128f21caf8d
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 15:13:15 2026 +0100
Replace `ptr.offset(x).op` with `offset!(ptr, x).op` in the rules
The latter is more efficient
commit d7fec13190e6c322faa3bcc006960d456b18c2e8
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 15:01:59 2026 +0100
Fail format CI if clippy issues a warning
commit ccf088359ccfb06daecd65cf11ba49ea29b63b52
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 14:59:14 2026 +0100
fix clippy warnings
commit 3ba181cc374684c8d1cd3f1566843e63b4fdf4a1
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 14:56:05 2026 +0100
Remove unneeded Value<T> boxing from constructors
commit 0753f651c0752d56b964b2a3117b08d89472d229
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 14:33:37 2026 +0100
Add lightweight analysis that gathers non-address taken variables
Remove Value<T> boxing in those cases
commit b41990ed6f5baca2570285e769faa444e5777f06
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Oct 5 13:39:33 2026 +0100
Switch char to i8 (#452)
Fixes #246
commit 9e032ae9ca050c099ecd6b2ee154d24874102086
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Oct 4 19:48:49 2026 +0100
Fix testsuite compilation
commit 67fbc74348849bf4d42df74016754b6549e393cd
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Oct 4 18:28:25 2026 +0100
fix tests
commit 89e83a88f7f2a08687790f5e48db4259a3b7f237
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 4 18:26:41 2026 +0100
Translate lambdas using FnPtr (#439)
Fixes #314.
commit 8be9b75ef58d40f460b1d50080f7cdbb19f86de8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 4 18:09:09 2026 +0100
Dedup conversion operator names (#445)
char8_t and char are both translated to u8. This breaks conversion
operators: to_u8 (char8_t) vs to_u8 (char). Dedup the names to avoid
name collisions.
commit 91f76f55aa14af1c26b656acff0c71013d4e8966
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Oct 4 11:08:03 2026 +0100
Move C specific rules in src.c (#449)
Part of #447.
commit 42533cb9860779d8bbd2693a2214eec6f2a3e807
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 2 11:59:37 2026 +0100
Respect signedness for integer literals (#446)
commit 5e045731bd7ae9e8588e36899295e75c80a516ef
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 2 10:47:50 2026 +0100
Fix mismatched u64/usize pointers and references (#444)
commit 4f7fe3b64e40d1d11f69efaf03920deacd215aa4
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Oct 2 10:11:46 2026 +0100
fix test
commit 93ca13844e100e935bd1a73ea29b1348db3debd1
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Oct 2 09:55:31 2026 +0100
Use the `Default` default implementation more often
commit f6154ccc7163a4c069d31742d4db7b420ee71f5e
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Oct 2 08:56:03 2026 +0100
Add a DeepClone macro to remove manual Clone implementations
FIxes #216
commit f3700559de071679c614dcad16404f5b3461eab1
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Oct 2 08:40:00 2026 +0100
Add `offset!(ptr, idx)` macro to create temporary pointers without ref counting overhead
commit 251c0677fbc781e4ecd2e4aa69ad10ee2dc5fd7c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 2 08:20:44 2026 +0100
Translate static member templates (#440)
commit 6d59ab88f299a453d77f9f6e6630d9e8688d4659
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Oct 2 08:15:40 2026 +0100
Fix u64/usize mismatch in array init and ctor call (#442)
commit 0383cd5b894c1545fdea048d01327d69c378ce5b
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Oct 1 22:07:57 2026 +0100
Update to Rust 1.99 (#443)
commit 63dd17e631ed9144c7755d01778ee3630acba83f
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Wed Sep 30 19:34:10 2026 +0100
Reduce the number of temporary variabkes created by using braces
Rust 2024 treates the last expr as temporary, allowing us to write
*x.borrow_mut() = { *x.borrow() +1 }
without causing borrowing errors
We must careful only with side effects and evaluation orders
commit ce687c40e84bb232b13583066962e1b6cc55ab47
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Wed Sep 30 18:59:47 2026 +0100
Add a macro to derive ByteRepr automatically
Shrinks the translated code
Part of #216
commit 619be59e0df1de36bcd316841f93403aacb7632f
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Wed Sep 30 18:06:48 2026 +0100
Remove Value<> boxing from struct fields except arrays/vectors (#437)
commit aa9e5746c20cca6f0eabd481dd9adb38a4ecd908
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 30 14:46:08 2026 +0100
Add extra tests for struct fields, PR #437 (#438)
commit 6a1926705ab5146cea7050f5203b3bce33e7b5eb
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 30 09:13:52 2026 +0100
[NFC] Split responsibilities of Mapper (#434)
Mapper grew too big. It has 4 responsibilities at the same time:
1. Map expressions or types to a rust string
2. Match expressions or types against translation rules
3. Answer queries about the translation rules (ParamIsPointer,
IsLibcPassthrough, etc)
4. Print string representation of expressions or types
Only the first should be in Mapper, the rest should be split.
For (2) I plan to add a new tree matcher instead of the current string
matcher. To make the transition smooth I extracted the matching logic
form Mapper into `cpp2rust/converter/rules/matcher.h`.
For (3) I added `cpp2rust/converter/rules/registry.h` which keeps the
`exprs_` and `rules_` multimaps + handles queries about the translation
rules.
For (4) I added `cpp2rust/converter/printer.h` which should BTW
disappear after we switch to tree matching instead of string matching.
This is a building block for fixing #435
commit edd15e8cbf509beeb3c58ce23a26532137f3fe23
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Wed Sep 30 09:02:15 2026 +0100
fix test output
commit eaac2eb6fdeb726709461a85346e8a2179c40231
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Wed Sep 30 08:55:59 2026 +0100
fix build with clang 24
commit 44deda0d72b763a030abe9fe2bfc109c9d6b6591
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 29 22:30:20 2026 +0100
Avoid extremely long names in overloaded methods (#431)
```diff
- pub unsafe fn apply_Optionunsafefnpmuti32_i32__i32_const(
- &self,
- mut f: Option<unsafe fn(*mut i32, i32)>,
- mut x: i32,
- ) -> i32 {
+ pub unsafe fn apply_11(&self, mut f: Option<unsafe fn(*mut i32, i32)>, mut x: i32) -> i32 {
```
This generates more readable names and avoid special-casing characters
in the mangled name.
Also it fixes a problem in the codegen where a template is visited
before the type it's instantiated with.
commit ee38fdab975a2b224c712d08c49476bc0728377e
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 29 15:21:54 2026 +0100
Derive VaArg and FnPtrArg for cloneable records (#432)
commit 90ddea537e3265ad7c7a252b799bf95271b34471
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 29 15:14:54 2026 +0100
Avoid collision between user-defined record and libcc2rs (#433)
The other option is to use fully qualified names in the output, for
example libcc2rs::Ptr, but that's too verbose.
commit c8329a61aea05cc9d9ce96638f77f1fa856731ff
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 28 21:44:26 2026 +0100
Handle multi-dimensional arrays in codegen (#428)
commit 3a9064ff4f7c63b826945d68aac1639a158298ea
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 28 21:34:59 2026 +0100
Translate access of static member through object (#430)
```cpp
struct S {
static int static_member = 0;
}
assert(S{}.static_member == 0);
assert(S::static_member == 0);
```
Both are valid C++. Same for static methods.
commit 9ba0d6974c5bff4952f69a7bd768ca3a02eb50ee
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 28 21:33:40 2026 +0100
Move builtin types in rules/ (#429)
Removes the awkward handling of builtin types from addBuiltinTypes.
Remove unneeded casts between builtin pointer types.
Also useful for a future PR where I plan to replace string rule matching
with structured tree matching.
commit e3c65269c67a403f1a8f839f355027c41c28305e
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 28 21:30:58 2026 +0100
Drop helper structs in algorithm rules (#427)
commit 047cb7c66d99149cb20e642b6214e52f6ddef176
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 28 18:45:22 2026 +0100
Don't clone whole global arrays on a read
commit 1f5e1f5d6cbaca09f82ef0982cbc21dc21d7bafc
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 28 08:51:09 2026 +0100
libcc2rs: various optimizations that yield about 10% speedup on Brunsli
Inline a few hot functions
Rearrange PtrKind to simplify the generated code
commit 825b71c16665cdb4a199e102d2baaf4a328814a5
Author: João Gouveia <joaotalonegouveia@tecnico.ulisboa.pt>
Date: Mon Sep 28 08:34:44 2026 +0100
Use fully-qualified syntax for decay calls (#426)
Addresses the second issue mentioned in #425
commit 83af9de94d1eb37bcd77775ffb66dcac6438cb49
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 27 10:43:05 2026 +0100
Fix build of testsuite
commit 2b2612f305810ec01de1cd4f2ba5bc52cef0193b
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 27 10:20:25 2026 +0100
Fix compilation after `ninja format` has been run
commit 4a4238166a79a018ac6a778efe23ef0fd6d1b812
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 27 09:59:32 2026 +0100
Remove a few spurious clones before Ptr::to_any
commit 58a2a29b43ac13b747f031f392e12cdbe932a9f4
Author: João Gouveia <joaotalonegouveia@tecnico.ulisboa.pt>
Date: Sun Sep 27 09:45:47 2026 +0100
Fix void pointer comparisons (#424)
`AnyPtr` comparisons rely on the equals method of the `ErasedPtr` trait.
For `Ptr`, this method is as follows:
```rust
fn equals(&self, other: &dyn ErasedPtr) -> bool {
other.as_any().downcast_ref::<Ptr<T>>() == Some(self)
}
```
This implementation causes `AnyPtr` equality checks to succeed only when
the underlying `ErasedPtr`s have the same pointee type, since
`.as_any().downcast_ref::<Ptr<T>>()` returns `None` otherwise.
I do not believe this behavior is correct. Two pointers cast to `void *`
compare equal if they point to the same address, regardless of their
original types.
This patch adds two unit tests covering this bug and addresses it by
comparing the two `ErasedPtrs` through their byte representations.
commit ba061bfe0afb8aeb214bd7387cd9ad889979340f
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Sep 25 18:00:59 2026 +0100
[unsage] Fix missing transmute in function pointer cast
Fixes test fn_ptr_typedef_cast.c
commit 3086a02129a93771649fa720d12fae855a57435a
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Sep 25 17:56:16 2026 +0100
Fix string.h translation with glibc >= 2.43
commit da79fe9efc8c77b094b76b54aa8d7abd07740ba4
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Sep 25 17:27:11 2026 +0100
Build all of Rust in the build directory and avoid double build on format
commit bce8f54006312d4642382983fc0581e5738657ca
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Sep 25 16:41:52 2026 +0100
Move shims from libcc2rs into rules (#421)
We used `libcc2rs/src/libc_shims` to define various shims for
interacting with libc from refcount: CFile, CFdSet, networking structs,
etc. This will soon get very big with the addition of new rules.
I moved each shim in the corresponding rule dir, for example
`rules/stdio/shim.rs`, `rules/select/shim.rs`, etc. This way, shims stay
small and separated.
libcc2rs gathers all shim.rs files form rules/ at build time and
compiles them.
commit 2a8276e92a0392c1dd6583fd10c8fb3d5cb0efd7
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Fri Sep 25 16:21:59 2026 +0100
Translate concepts and requires expressions (#347)
They are evaluated by clang. Only the result of the evaluation is
translated.
Furthermore, static_assert is no-op because it's evaluated at compile
time. Same for concept declaration.
commit 483abe62b6ff4eaa9fc506d9fb4f8f19de146c00
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Sep 24 21:34:12 2026 +0100
Add lambda testsuite (#423)
commit 1b519b63b8784121c0ff8697ea73e97b74029e67
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 22:34:34 2026 +0100
Add support for rules that receive argument packs (#416)
Add support for rules like `std::vector<T1>::emplace_back(Args&&....)`
and `std::unique_ptr<T>::make_unique(Args&&...)`. This also deletes the
emplace back plugin.
This sets the stage for adding other argument pack rules like
`std::construct_at` or `std::map::try_emplace`.
Rust does not support forwarding argument packs. So emplace_back is
translated as `v.push(T::new(arg1, arg2, ...))`, i.e. it builds the
object at the call site. For things that might not build the object
using the provided arguments, like try_emplace, we will use the
following translation that conditionally builds the object:
`m.entry(key).or_insert_with(|| T::new(arg1, arg2, ...))`.
I used a new node in Rules IR, called init, which rule-preprocessor
creates when encountering a pack that builds an object. cpp2rust reads
the init node and creates a construct expression which is then
translated in order to create `T::new(arg1, arg2, ...)`.
commit 6fbeb0cf6aa3ed1c26c691b45437d36f39d67741
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 21:55:12 2026 +0100
Translate in-class initializers in Default trait (#332)
commit 578694b8b2b09a30a71480d8b533ca2bd21fc150
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 21:39:10 2026 +0100
Use copy_from/move_from to translate copy/move ctor (#418)
If possible, use the `copy_from`/`move_from` idiomatic name instead of
`S_pmutS_rv`. This is only possible when the copy/move constructor is
unique (no other copy/move constructor exists) and when no other method
in the class is called copy_from/move_from.
Do the same for copy/move assignment: copy_assign and move_assign.
commit aa7c10462a7d9623830933934499d0faa509bb88
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 21:13:37 2026 +0100
Translate if constexpr (#345)
commit 98cc1b796f9db0913c4b90fdfc1bf5f76710065e
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 21:04:04 2026 +0100
Use idiomatic S::new for ctor instead of S::S (#420)
commit aa071d8f43fe7e7f42a1bff9662d1bb39262a925
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 21:03:09 2026 +0100
Generate to_bool instead of operator__Bool (#419)
commit 43df4b9738d30aaa9b79c9b395cfff54bf724660
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 23 21:02:16 2026 +0100
Translate std::launder (#417)
Initially I wanted to special case this in the converter like std::move
and std::forward. However since this is just a passthrough rule that
receives a pointer and returns a pointer + does not change the value
category of the argument, I put this in rules.
commit ed10067a1b04e549f299cd8483cb427c9e23c443
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Tue Sep 22 17:22:34 2026 +0100
Refactor how function pointer casts work by creating a trampoline automatically
Simplifies the generated code at the expense of more runtime library code
commit 8173b259fc1fcf4c690374629aaf7179f8a5e870
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 22 14:18:19 2026 +0100
Add rules for __builtin_abort/nanf/inff/clzl (#415)
commit 511e5b752e2bb09d6dc2993e8fd2cee2d8580799
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 22 10:27:27 2026 +0100
Handle transparent std calls (#414)
Similar to move and forward, handle move_if_noexcept and as_const in
codegen. They have no effect at runtime.
commit d9b33e5eb95565ad3785594266126926778e0065
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 22 08:31:23 2026 +0100
Translate std::forward (#413)
Similar to `std::move`, `std::forward` performs a cast and helps the AST
choose the right overload. It has no effect at runtime.
commit aabc367196e0c46d80737bb2dc04c141675a2efa
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 21 21:10:47 2026 +0100
Translate friend operators (#412)
commit b398a1b7d01cdb3242292cd9e497417a94d1319b
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 21 13:48:04 2026 +0100
Fix late instantiated virtual methods (#411)
#394 translates records that contain declared but not defined methods.
That did not cover virtual methods in derived records. This PR solves
that.
cpp2rust generated an empty `impl Base for Derived {}` when no virtual
method had a definition. Then, when an out-of-line definition was
encountered, cpp2rust refused it because multiple `impl Base for Derived
{}` are not allowed by rustc. This resulted in usages of undefiend
methods because neither the record visitor nor the out-of-line method
visitor generated the methods.
The fix is to defer the `impl Base for Derived {}` block at the end of
the file, similar to how methods on Ptr are deferred. At the end of the
file, where every TU was visited, we know all the methods that have
definitions.
commit 174ebb6f2a32c6ebccfa1924d19f8ce664b13dd9
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 21 11:13:43 2026 +0100
optimize reinterpret casts to avoid heap allocation on dereferences
Also add fast paths for common operations (aligned access, deref u8)
commit 9934ac78bb2dc4ad2b6f6a57873d1b35ab583e50
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 21 10:31:49 2026 +0100
optimize function pointers to avoid heap allocation
commit 6a43cf98cc90fa7f95938ce7ef8595c896018bb9
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 21 09:42:56 2026 +0100
optimize vaarg handling
commit 8f54ac90cb04e550c22b9a86c16a4b84b82e196e
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 21 09:28:25 2026 +0100
fix test
commit a40ebe7df024940b95f842f7b941a87b76c28dff
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Mon Sep 21 09:26:37 2026 +0100
optimizations to libcc2rs related with strings
Reduces heap allocations in the common case
commit 7a801325da28170bcf72dc69e10e4dabf36c9f84
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 20 22:06:45 2026 +0100
Replace Ptr::delete_array with Ptr::delete
There's no need to catch all those UB cases; we can refine into working code.
commit b5aa8518d98a4f68607f191c0cc71c91be3acf20
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 20 21:43:53 2026 +0100
Remove Ptr::to_strong() and add Ptr::decay() (#410)
To decay a pointer, we would previously translate first to a strong reference and then call `as_pointer`.
This patch avoids that by 1) decaying pointers whenever possible and by using `decay` as a more efficient
way to decay pointers (does only a weak clone).
commit 50d844d21bbcef8d98c09a0b866f670f4d83134f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 18:59:25 2026 +0100
Translate operators that receive by value arguments (#408)
commit 4edecf6d25d9c32c3a083503fc162e7a5422d793
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 18:42:16 2026 +0100
Fix address of static method (#409)
commit 325c11ff0744d7cc6027415e095967e6c5b11d8a
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 20 16:55:18 2026 +0100
fix compilation of assert with C++11
commit 352ac8a41af4c090bc542b3279ad4a459a33970c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:50:54 2026 +0100
Don't add default impl for declared but not defined default ctor (#405)
commit 4d5177b768b934f679d908145b51f908a9535794
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:50:17 2026 +0100
Don't translate partial specializations (#406)
Only the full specialization is translated.
commit 2a8929229fdb8ac4dc06768cba72345a771a1fe3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:49:53 2026 +0100
Convert operand as lvalue in array-to-pointer decay (#404)
commit 74c683000708a4c6480b93cb49a6830331c8d093
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:43:51 2026 +0100
Define constexpr cpp2rust_assert_fail (#401)
Calling assert in constexpr context requires cpp2rust_assert_fail to be
constexpr defined.
commit 444164c4982971f47c4bee31b94046e9586c31e8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:42:01 2026 +0100
Translate inner templates (#400)
commit 6c870265d3794e8794ed0e76455688a4015cc572
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:41:16 2026 +0100
Fix address of conditional operand (#403)
commit 582e0f6d2ce5124757be2e58e110b0f42aab0dfa
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:40:03 2026 +0100
Translate empty unions in unsafe (#402)
Unions cannot be empty in unsafe, add a dummy u8 member.
commit d9a10be01b671557ef3cc1a38a774b0a184fb834
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 15:39:04 2026 +0100
Translate unary plus (#399)
commit 3b4667707b49c5c9fe19f4071a061498ae447c68
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 13:59:24 2026 +0100
Don't use uninstantiated default argument (#398)
commit e348a4fbe5b7c6ef0ca984c9b3bd43fa41fc496a
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 13:57:55 2026 +0100
Fix temporary receivers (#397)
commit 28b0d414ac2b524e7a4756a6e96da2884a3f77b3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 13:56:51 2026 +0100
Translate nameless copy constructor agrument as _a0 instead of self (#396)
`self` is used only on defaulted copy constructor, i.e. inside the Clone
implementation.
commit e345b15913b921aa8718a6ef8a08e2e823c79155
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 13:00:36 2026 +0100
Translate functional casts (#395)
commit 0fe86a0b58bcbfd2fa323db361d19e8fe54d9549
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 12:58:00 2026 +0100
Translate records that contain declared but not defined methods (#394)
```cpp
struct S {
int a;
void declared_but_never_defined();
];
int main() {
S s{1};
assert(s.a == 1);
}
```
S is a valid record that can be translated to Rust. This PR translates
it like this:
```rs
struct S {
a: i32
}
trait SImpl {
fn declared_but_never_defined(&self) { unimplemented!() }
}
```
The function gets a default `unimplemented` implementation. Other TU
might offer a definition for the declared-only method.
commit 053a8306ef69e4d1f1018c7f3ea14b85056f91b8
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 12:55:02 2026 +0100
Convert delegating constructors (#386)
commit 06dc24e92b154a307fb692920ce314e70a90c24c
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 11:34:56 2026 +0100
Translate classes with mutable fields (#387)
Classes with mutable fields can modify the mutable fields even in const
methods. For this reason, the receiver of const methods in classes that
contain mutable fields should be `&mut` instead of `&`.
commit 3943e3ec711c30507ea088a2a52c7da3192fad78
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 11:03:35 2026 +0100
Translate wide strings (#381)
commit cadf6a850bc3a96c79e592930889045179e93eff
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 10:56:16 2026 +0100
Fix translation of out-of-line template static methods (#393)
commit de1698661c793e9ecad732a2dc49a4e8598e3bd3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 10:50:39 2026 +0100
Unbox initializer list in refcount (#392)
commit 4dcdf6181cbbfc49123ef0980735160291928df3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 10:50:29 2026 +0100
Default initialize reamaining fields in small initializer list (#391)
commit d8a53d495392fdab9b0027350fe3bbebd84f4265
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 10:29:54 2026 +0100
Default initialize object allocated with new (#390)
commit 62e28c9ce8ef3a09d5a39a08a40c3ddc7d35fb70
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 20 10:21:21 2026 +0100
fix #377: modify global variables without cloning the Rc
commit cc7dcb0fe15603053faef87c751709a765ca82d3
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 09:24:06 2026 +0100
Translate variable template declarations (#389)
commit deac5b5bfa5311954a36158d7976517e254acd83
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 08:58:39 2026 +0100
Add rules for operator new and operator delete (#380)
commit e7fb91fbafd54a12bb764ce1847861f4838b0d2d
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 08:57:12 2026 +0100
Ignore explicit casts to reference types (#382)
commit f65bef426f25fc50abf5ff99a4ce6db545f3284a
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 08:56:09 2026 +0100
Handle more patterns in mangler (#384)
commit f9fc65d8de0870e14b44b83bfbb34dcf98c3bb24
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 08:54:32 2026 +0100
Derive Clone when all fields are references (#388)
Also when there are no fields.
commit 21842412bfa0cb40dea1ad50437427c99075bb3e
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 08:53:06 2026 +0100
Don't call destructor for trivially destructible types (#383)
commit deba8923b7fbb7885bd859234811c1aa18ddad4e
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 20 08:51:20 2026 +0100
Implement Ord for Ptr (#385)
commit 754f8181a72a417954a0a53f62695533a9f15aaa
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Sep 18 09:29:51 2026 +0100
fix #193: remove Brotli headers from repo
commit 78fe7c436e26161147214a6b9f1589c11e38d24d
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Fri Sep 18 09:00:40 2026 +0100
cmake fixes
commit d8cc325ba5874fdea9c4905b09d88fe3f1778434
Author: João Gouveia <joaotalonegouveia@tecnico.ulisboa.pt>
Date: Fri Sep 18 08:18:14 2026 +0100
Make rule-preprocessor process a single directory at a time (#372)
Changes `rule-preprocessor` to process a single directory per
invocation, making it possible to parallelize. This matches what is
already the case for `cpp-rule-preprocessor`. Additionally, this drops
`modules.rs` from source control.
commit 00d90a0dc79cf2cbce4e6a99c27b438e301738a6
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Sep 17 15:31:51 2026 +0100
Read global variables without clonning the Rc
Part of #377. Needs to fix the writing as well.
commit e54bd9ba2640d3874095e9868530adb7ed1b425c
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Sep 17 14:56:58 2026 +0100
Fix #114: Rust 2024 compatibility
commit 79e0bd2ac802e6c499c69b4f0f2a97e144589780
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Sep 17 14:42:03 2026 +0100
[unsafe] Fix non-const global initializers and [unsafe, refcount] order of global initialization (#366)
Rust requires initializers of global variables to be const. C++ does not
require that.
To fix this tension, wrap global variables in `std::cell::LazyCell` so
that initialization does not depend on the constness of the initializer.
Another problem that this PR fixes is the moment when global variables
are initialized in both refcount and unsafe. `thread_local` in refcount
and the new `LazyCell` in unsafe initialize the variable on the first
usage. This is wrong if the constructors of the global variables have
side effects that must be visible in the program, for example:
```cpp
#include <cassert>
static int total = 0;
struct S {
S(int x) { total += x; }
};
// there is no explicit usage of a and b inside the program other than the initialization
// however the constructor has side effects that are visible on the total variable
// so the initialization has to happen before entering main, not lazily as thread_local
// and LazyCell normally do
static S a(1);
static S b(10);
int main() {
assert(total == 11);
return 0;
}
```
To fix this, I added a new function that runs before main and forces the
initialization of global variables: `__cpp2rust_init_globals()`.
---------
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
commit 9e771ccf8ea1d2eccd4f3f95e25d5508d06038a9
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Sep 17 13:34:31 2026 +0100
format
commit 69ebb2c47922d9eecdb568d31cc4f2cb85d853a9
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Thu Sep 17 12:31:53 2026 +0100
Don't generate empty thread_locals
Co-authored-by: Francisco Gouveia <francisco.t.gouveia@tecnico.ulisboa.pt>
commit c99fe02d40c1cecf0657d5b688e98b001cc94bc7
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Thu Sep 17 09:56:44 2026 +0100
Translate user defined moves (#369)
This PR translates move constructors as ordinary constructors: `fn
S_pmutS(_a0: *mut S) -> Self`.
The rules for translating and using the move constructors are:
|No | Move Constructor (MC) | Copy Constructor | Result |
| --- | --- | --- | --- |
| 1 | user-written | implicit/defaulted/deleted | translate MC and
always use it |
| 2 | user-written | user-written | translate MC and always use it |
| 3 | implicit/defaulted | implicit/defaulted | don't translate MC and
use `.clone()` on move |
| 4 | implicit/defautled | user-written/deleted | translate MC and
always use it |
For 1 and 2, we always use the translated move constructor because it
might contain custom logic that needs to run on every move. For 3 we use
`.clone()` because it has the same effect as a move would have. For 4
`.clone()` is not available (deleted) or might contain custom logic
(user-written) so we synthesize an implicit/defaulted move constructor
and use it.
`std::move` becomes a transparent construct, i.e. no move decision is
taken at the time of the cast. It's only used by clang to choose the
right constructor. Moves happen on CXXConstructExpr.
Each STL type has move construction rules. Rules that move using
`std::mem::take` have their bodies rewritten as follows:
* record has move constructor => rewrite `std::mem::take` as a call to
the move constructor
* record does not have move constructor and is copyable => convert as
rvalue (without clone)
* record does not have move constructor and is not copyable => convert
as fresh rvalue (with clone)
* record is STL type => use the rule for STL move constructor
* temporary value => convert as rvalue
commit 9138d71748d2826cfe700b361e5d5e75375d3a87
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 16 21:11:15 2026 +0100
Remove duplicated lamda/function pointer rules (#373)
`stable_sort` rules had 2 version of rules: one that takes a lambda and
one that takes a function pointer. This PR removes the duplication by
adding a new trait in libcc2rs: Callable.
Callable is implemented by `Fn` (closures, safe function items, safe
function pointers) and `unsafe fn` pointers. Unsafe functoin items reach
the `Callable` trait to an explicit cast to `unsafe fn` pointers because
they don't implement `Fn`.
commit 20563817f8ff43e353d525d14b52b5daa3d8e11f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 16 21:10:30 2026 +0100
Move function-local records in global scope (#375)
```cpp
template <typename T> int get(T t) { return t.x; }
int main() {
struct Local {
int x;
};
Local l{7};
assert(get(l) == 7);
return 0;
}
```
The `get` function template lives in the global scope while `Local`
(used to instantiate `get`) lives at function scope. In the AST
instantiations live in the global scope as well, so it gets translated
as:
```rs
// Wrong: the global scope has no Local_1. It only exists inside main
pub unsafe fn get_0(mut t: Local_1) -> i32 {
return (t.x as i32);
}
unsafe fn main_0() -> i32 {
pub struct Local_1 {
pub x: i32,
};
let mut l: Local_1 = Local_1 { x: 7 };
assert!(((unsafe { get_0(l,) }) == (7)));
return 0;
}
```
This PR fixes this by moving the definition of `Local_1` at a global
scope:
```rs
// Correct: now Local_1 is visible for the instantiation
pub unsafe fn get_0(mut t: Local_1) -> i32 {
return (t.x as i32);
}
unsafe fn main_0() -> i32 {
let mut l: Local_1 = Local_1 { x: 7 };
assert!(((unsafe { get_0(l,) }) == (7)));
return 0;
}
pub struct Local_1 {
pub x: i32,
};
```
commit 07be1084b140f2ed31a15febfce8895eb9cbee91
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Wed Sep 16 15:38:24 2026 +0100
Delete test banners and the unused address_taken.cpp (#374)
commit ae8355b1fd267abcdd718217fbd940c0570dd8b9
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 15 22:17:38 2026 +0100
Add codegen/types docs (#370)
This doesn't have all the info updated. For example enums are no more
transalted as enum in Rust, I plan to update that in a future PR. For
the moment I would like to get the core of codegen/types merged, then I
will make the appropiate edits.
commit 1d6980f06b38889c69298f09b9c39fb8f21556ee
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Tue Sep 15 15:26:22 2026 +0100
Remove unneeded clones in converter and rules (#371)
This PR removes unneeded clones **in converter** by calling
`SetValueFreshness`/`computed_expr_type_`/`SetFreshType` on every
fressh-value-producing path. It asserts that `computed_expr_type_` is
not Unknown after a conversion to make sure that we did not miss any
path.
PendingDeref carries freshness separately. Producers of PendingDeref set
freshness and consumers act based on that. I also added
`ComputedExprType::Pending` because freshness is unknown until the
consumer of PendingDeref sets it.
This PR also removes unneeded clones **in rules** using the `Access` IR
attribute. Rules no longer clone their arguments. The preprocessor
infers how each argument is used: `borrow, borrow_mut, move, take`. A
`move` (`let s = a0`) consumes the argument, and it's cloned if it's not
already fresh. A `borrow` usage (`a0.len()`) is never cloned.
Besides removing unneeded clones, on the converter side, this fixes
https://github.com/Cpp2Rust/cpp2rust/issues/363. On the rules side,
`rule-preprocessor` infers the access type of each argument
automatically instead on relying on the rule author to encode it
properly. This caught a bug in `std::vector::push_back(T&&)`: the rule
argument took the argument by value and cloned it, instead of moving it.
commit 04f96ff48129eacbeb376f25adf3eb5d7deef55b
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 14 22:13:54 2026 +0100
Skip cast when reference coerces to pointer (#368)
commit d40c5c8b75aec28d784a1b1b44412a864422897f
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 14 15:57:26 2026 +0100
Add more rules for move assignment and constructor (#362)
commit d96ed5a414b2f1214e8af73459bcbead112ebed0
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 14 10:36:21 2026 +0100
Translate nameless C++ params as _a1, _a2, etc (#361)
commit 4290c68af058382c57bf33ce6548091822c95ce9
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Mon Sep 14 10:04:05 2026 +0100
Add move rules for STL containers (#360)
Don't special case the move constructor of unique_ptr inside the
converter. Instead add a rule for it.
Also added move constructs and assignment rules for array, vector, map.
commit c2bf86b6a727262b4c5f316073c2b64b8ad38b66
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 13 18:30:38 2026 +0100
Bump to LLVM 23 (#359)
Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
commit 8ffb93b50e99c4eb9f9cdbe0b13e03ca2aae4de6
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 13 13:51:31 2026 +0100
Fix clang 23 build
commit bf1b2d49004b24387c3af4ddeeb0b50e4109f03c
Author: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
Date: Sun Sep 13 09:14:57 2026 +0100
fix build with clang 24
commit 8275e7eb20d9bce411316e752523f0223bfec711
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 13 08:58:14 2026 +0100
Translate defaulted and implicit comparison operators (#356)
This PR translates defaulted comparison operator such as `==` or `<=>`
and the implicit comparison operators derived from `<=>`.
It asks Sema to define the defaulted/implicit operators and then
cpp2rust translates them as normal methods.
commit 345588146b165049905f33c907a074e81a393e75
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sun Sep 13 08:56:27 2026 +0100
Translate reference to array (#357)
Reference to array is translated as `Ptr<Box<[T]>>` in refcount and
`*const/mut [T; N]` in unsafe.
I added a new ConversionKind called Pointee to translate reference to
array in refcount. The semantics are:
* `FullRefCount`: `Value<Pointee>`
* `Pointee`: the object itself
* `Unboxed`: same as `Pointee`, except arrays which are `[T; N]` intead
`Box<[T]>`
I also added `Ptr::from_string_literal_array` which is similar to
`Ptr::from_string_literal`, the only difference is that that the new
function returns `Ptr<Box<[u8]>>` instead of `Ptr<u8>`.
commit 329a61aace8b1c7707b44abcdb430028365c12f1
Author: Lucian Popescu <lucian.popescu@tecnico.ulisboa.pt>
Date: Sat Sep 12 13:59:07 2026 +0100
Add traits on field-less structs (#354)
Instantiated templates can be generated as structs with zero fields, aka
unit struct.
We need unit structs to be copyable, clonable, defaultable and byterepr
becau…
| HeapArray(Weak<RefCell<Box<[T]>>>), | ||
| StackVec(Weak<RefCell<Vec<T>>>), | ||
| HeapVec(Weak<RefCell<Vec<T>>>), | ||
| Nested(Rc<dyn SliceParent<T>>), |
There was a problem hiding this comment.
this dyn doubles the size of PtrKind. Needs benchmarking.
There was a problem hiding this comment.
The size is the same. It's wrapped in an Rc, same as ReinterpretedView
There was a problem hiding this comment.
I will check if micro already contains benchmarks for arrays, otherwise I will add some
There was a problem hiding this comment.
Nop. size of Rc dyn is 2x size of Rc without dyn.
There was a problem hiding this comment.
Sorry, I meant that it does not increase the size of PtrKind because we already have a Weak<dyn> which is Field
There was a problem hiding this comment.
BTW I benchmarked brunsli and woff2 and I saw a slowdown between 1.2% and 1.4%. I will also benchmark micro
| } | ||
|
|
||
| fn address(&self) -> usize { | ||
| self.kind.address().wrapping_add(self.byte_offset()) |
There was a problem hiding this comment.
Add a few tests that subtract pointers to ensure addresses are being computed correctly across multiple nested levels.
e.g.:
int v[3][4];
assert(&v[0][3] - &v[0][1] == 2);
assert(v[1] - (&v[0][0] + 3) == 1);
There was a problem hiding this comment.
The second assert is UB. It's rejected by clang in constexpr mode: https://godbolt.org/z/T43K6M3v1. The pointers are not from the same array object
|
Is this change expected? --- a/woff2/out/refcount/src/bin/woff2_compress.rs
+++ b/woff2/out/refcount/src/bin/woff2_compress.rs
@@ -640,7 +640,7 @@ pub struct woff2_Font {
pub num_tables: u16,
#[offset(8)]
#[byte_size(48)]
- pub tables: BTreeMap<u32, Value<woff2_Font_Table>>,
+ pub tables: BTreeMap<u32, Value<(Value<u32>, Value<woff2_Font_Table>)>>,
}
#[derive(DeepClone, Record, ByteRepr, VaArg, FnPtrArg, Default)]
#[byte_size(80)]
@@ -651,7 +651,7 @@ pub struct woff2_FontCollection {
pub header_version: u32,
#[offset(8)]
#[byte_size(48)]
- pub tables: BTreeMap<u32, Value<Ptr<woff2_Font_Table>>>,
+ pub tables: BTreeMap<u32, Value<(Value<u32>, Value<Ptr<woff2_Font_Table>>)>>,
#[offset(56)]
#[byte_size(24)]
pub fonts: Value<Vec<woff2_Font>>,
@@ -704,7 +704,8 @@ pub fn ReadTrueTypeFont_33(
{
return false;
}
- let intervals: Value<BTreeMap<u32, Value<u32>>> = Rc::new(RefCell::new(BTreeMap::new()));
+ let intervals: Value<BTreeMap<u32, Value<(Value<u32>, Value<u32>)>>> =
+ Rc::new(RefCell::new(BTreeMap::new()));
let mut i: u16 = 0_u16;
'loop_: while ({ (i as i32) } < { (font.with(|__s| __s.num_tables) as i32) }) {
let table: Value<woff2_Font_Table> = Rc::new(RefCell::new(<woff2_Font_Table>::default())); |
Yes, see #523 |
|
I benchmarked the tests I added in Cpp2Rust/cpp2rust-testsuite#8, numbers only for refcount:
|
Closes #15
Translates
vector<vector<T>>asVec<Vec<T>>instead ofVec<Value<Vec<T>>>. Nested arrays also lose the extra Value. This allows deleting the rules forvector<vector<T>>.This adds a new PtrKind:
root accesses the parent, borrow_slice/borrow_slice_mut are used for reading/writing into the nested row and address is sued for identity.