immunant / c2rust

Migrate C code to Rust
https://c2rust.com/
Other
3.91k stars 229 forks source link

rewriter: struct type parameter rewrites swallow constraints #927

Closed aneksteind closed 1 year ago

aneksteind commented 1 year ago
          Will this swallow constraints, rewriting `struct Foo<T: Clone>(...)` into `struct Foo<T>(...)`?

_Originally posted by @spernsteiner in https://github.com/immunant/c2rust/pull/915#discussion_r1191645091_

The proposed solution to this is to use Rewrite::Sub to extract the existing type parameters (plus their predicates using span operations) to leave the type constraints untouched. For lifetimes, the generic parameter spans can be rewritten on a per-parameter basis using Rewrite::PrintTy

spernsteiner commented 1 year ago

Currently, given a declaration with constraints like struct S<'a: 'static, T: Clone> { ... }, we rewrite the generics <...> with something like TyGenericParams([PrintTy("'a"), PrintTy("'h0"), PrintTy("T")]). This produces <'a, 'h0, T>, losing the constraints 'a: 'static and T: Clone. We could instead produce TyGenericParams([Sub(0, span0), PrintTy("'h0"), Sub(1, span1)]), where span0 is the span of the argument 'a: 'static at index 0 and span1 is the span of T: Clone. Then when the rewrite is applied, it will splice in the text from those spans and produce the correct result <'a: 'static, 'h0, T: Clone>.