Manual reborrowing trait

⚓ Rust    📅 2025-11-20    👤 surdeus    👁️ 13      

surdeus

Info

This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Manual reborrowing trait

I'm trying to create a custom Reborrow trait for general values, and put it in an associated type, like:

pub trait Reborrow<'a> {
    type Target;

    fn reborrow(&'a self) -> Self::Target;
}

impl<'a, 'b, T: ?Sized> Reborrow<'b> for &'a T {
    type Target = &'a T;

    #[inline(always)]
    fn reborrow(&'b self) -> Self::Target {
        *self
    }
}

trait Interner {
    type GenericArgsSlice<'a>: for<'b> Reborrow<'b, Target = Self::GenericArgsSlice<'b>>
    where
        Self: 'a;
}

struct GenericArg<'tcx>(&'tcx mut &'tcx ());

struct TyCtxt<'tcx>(&'tcx mut &'tcx ());

impl<'tcx> Interner for TyCtxt<'tcx> {
    type GenericArgsSlice<'a>
        = &'tcx [GenericArg<'tcx>]
    where
        Self: 'a;
}

There is also a version with GAT, but it fails even earlier.

This code does not compile:

error[E0477]: the type `TyCtxt<'tcx>` does not fulfill the required lifetime
  --> src/lib.rs:28:11
   |
17 |     type GenericArgsSlice<'a>: for<'b> Reborrow<'b, Target = Self::GenericArgsSlice<'b>>
   |     ------------------------------------------------------------------------------------ definition of `GenericArgsSlice` from trait
...
28 |         = &'tcx [GenericArg<'tcx>]
   |           ^^^^^^^^^^^^^^^^^^^^^^^^
   |
help: copy the `where` clause predicates from the trait
   |
29 -     where
30 -         Self: 'a;
29 +     where Self: 'a;
   |

The thing that causes the error is the combination of the Reborrow constraint and the Self: 'a constraint. If I remove either it works.

I don't understand why is that the case. I tried to let the compiler infer an implied Self: 'a in addition to the explicit by adding a dummy &'a Self parameter to Reborrow, but it didn't help.

Why does this fail, and is there a way to make it work while keeping the Self: 'a bound?

1 post - 1 participant

Read full topic

🏷️ Rust_feed