The function signature for Interner::display_merged_solvables is:
fn display_merged_solvables(&self, solvables: &[SolvableId]) -> impl std::fmt::Display + '_
However, the elided lifetimes prevent returning a Display-able struct that borrows from both arguments. This prevents you from writing a display implementation that avoids allocating or cloning unnecessarily, which might look like:
fn display_merged_solvables(&self, solvables: &[SolvableId]) -> impl std::fmt::Display + '_ {
struct DisplayMergedSolvables<'a, 'b>(&'a ProviderType, &'b [SolvableId]);
impl<'a, 'b> std::fmt::Display for DisplayMergedSolvables<'a, 'b> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
todo!("insert implementation here")
}
}
DisplayMergedSolvables(self, solvables)
}
This is because of how Rust's lifetime elision rules work. In particular, see the following from the Rustnomicon:
Elision rules are as follows:
- Each elided lifetime in input position becomes a distinct lifetime parameter.
- ...
- If there are multiple input lifetime positions, but one of them is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes.
In particular, the return value cannot borrow from solvables, since solvables has an independent lifetime of self, and - as per the above rules - the returned lifetime must equal the lifetime of self.
Adding lifetime parameters to the trait would be a breaking change, since they would conflict with the original trait definition. Perhaps if a new major release is added in the future that this problem is avoided with specific lifetime bounds. Otherwise, this is quite a minor issue.
Since the other methods of the Interner trait only borrow from self, this method is the only one that is affected.
The function signature for
Interner::display_merged_solvablesis:However, the elided lifetimes prevent returning a
Display-able struct that borrows from both arguments. This prevents you from writing a display implementation that avoids allocating or cloning unnecessarily, which might look like:This is because of how Rust's lifetime elision rules work. In particular, see the following from the Rustnomicon:
In particular, the return value cannot borrow from
solvables, sincesolvableshas an independent lifetime ofself, and - as per the above rules - the returned lifetime must equal the lifetime ofself.Adding lifetime parameters to the trait would be a breaking change, since they would conflict with the original trait definition. Perhaps if a new major release is added in the future that this problem is avoided with specific lifetime bounds. Otherwise, this is quite a minor issue.
Since the other methods of the
Internertrait only borrow fromself, this method is the only one that is affected.