Skip to content

Use pointer to vector for rules where vector is method receiver - #551

Open
lucic71 wants to merge 13 commits into
Cpp2Rust:masterfrom
lucic71:vec-decay
Open

lucic71 wants to merge 13 commits into
Cpp2Rust:masterfrom
lucic71:vec-decay

Conversation

@lucic71

@lucic71 lucic71 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Rules where the receiver is a Vec or other record must receive Ptr<Vec<T>>, not Ptr<T>:

- fn f6(a0: Ptr<i8>) -> Ptr<i8> {
-    a0
+ fn f6(a0: Ptr<Vec<i8>>) -> Ptr<i8> {
+    a0.decay()
}

Otherwise they are mis-interpreted as forwarding rules. Forwarding rules are rules for std::move, std::forward, etc, where the argument is just passed-through the body:

// std::move
fn f6(a0: Ptr<T>) -> Ptr<T> { 
  a0
}

This PR also has the nice advantage of dropping unnecessary as Ptr<T> casts; which makes the code more readable:

-    ((n).clone() as Ptr<Option<Value<i32>>>).write((*m.borrow_mut()).take());
+    n.write((*m.borrow_mut()).take());

Comment thread libcc2rs/src/rc.rs
// The elements of a field are reached through the struct.
PtrKind::Field(root, _, FieldShape::Single) => Ptr {
offset: 0,
kind: PtrKind::Field(root.clone(), field_offset(self.offset), FieldShape::Vec),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change doesn't seem related nor useful

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted, it was an attempt to not panic on large offsets

@nunoplopes

Copy link
Copy Markdown
Contributor

I don't like all this decay in the rules.
A rule should receive Ptr if that's what it wants. Cpp2Rust should then decay or convert to pointer as needed. This would avoid having decay in all rules and unnecessary decays.

@lucic71

lucic71 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

I don't like all this decay in the rules. A rule should receive Ptr if that's what it wants. Cpp2Rust should then decay or convert to pointer as needed. This would avoid having decay in all rules and unnecessary decays.

For the rules that I changed, decay always runs. Master does decay in converter which is hacky: it uses string comparisons in ConvertFreshObjects. This branch states the decay in the rule. The number of decays is the same.

Besides that there are two things that get broken with the master approach:

  • no distinction between std::vector::data and std::move, both would be fn f1(a0: T1) -> T1 { a0 }. For move the translation needs to be different and the rule tells that
  • the master check in ConvertFreshObject breaks if the pointer is behind in a typedef (see Add rules for typedefs #552), for example:
std::unique_ptr<std::vector<int>> u;
// the receiver of data() has type
// std::unique_ptr<std::vector<int>>::pointer not std::vector<int>*
// ConvertFreshObject does not recognise this pattern
u->data();

The above example comes from brunsli

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants