immunant / c2rust

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

rewriter: type alias for struct does not support hypothetical lifetimes #926

Open aneksteind opened 1 year ago

aneksteind commented 1 year ago
struct Test<'a>(&'a u8);
type Alias<'a> = Test<'a>;
fn f<'a>(x: Alias<'a>) {}

For the code above if Test gets a hypothetical lifetime parameter, for instance, Alias won't get rewritten. @spernsteiner thinks this has to do with the destructing of the HIR ty being not properly supported.

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

spernsteiner commented 1 year ago

To clarify: in HirTyVisitor::handle_ty, the call to deconstruct_hir_ty returns None, because the HIR type Alias<'a> doesn't have the same shape as the ty::Ty Test<'a> (in which the alias has been unfolded). In this case, we currently just pretty-print the ty::Ty and use that as the rewrite. But that pretty-printed type will not include any hypothetical lifetimes we may have added to the struct.

Here's a clearer example:

struct S {
    y: *mut u8,
}
type A = S;
fn f(x: A) {}

Here, S has a hypothetical lifetime (used in y), and the HIR/ty mismatch described above is triggered on the argument x: A (whose ty::Ty is S, the expansion of the alias).

The current rewrite for this example is:

struct S<'h0> {
    y: &'h0 (u8),
}
type A = S;
fn f(x: S) {}

The type of x has been changed to S, which is missing the hypothetical lifetime that was added to the declaration of S. This happens because we simply pretty-print the Ty, S, and don't add hypothetical lifetimes to it.