Type that accepts generic closures which return owned or referenced values
⚓ Rust 📅 2025-11-08 👤 surdeus 👁️ 6I've been working on a small library as part of a larger project which lets you build "comparators" which compare things. Instead of using Ord, you can build and customize a comparator to change the way that two things are compared. The motivating use-case is in an application where the user may customize the sort behavior of a table of complex data.
One important combinator that I'm trying to write is called map, which lets you map a value to another value so the output is compared instead of the original. For example, given a list of structs, you might want to sort them based on a single field of that struct, so you would use a map combinator with a closure like |x: Foo| &x.sort. However I've been having a lot of trouble writing a single generic type for map that accepts both closures that return an owned value (such as a single number, or a tuple of numbers) and closures that return a referenced value (such as a reference to a non-Copy field of a struct), as well as combinations of the two (such as a tuple where the first field is a reference and the second field is a number).
This is my most basic attempt at this, which fails to compile for closures returning references, I think because the closure's output type has nothing that requires it lives as long as the argument.
I've tried a lot of other approaches with lifetime generics which resulted in even thornier compile errors like "one type is more general than the other". I feel like I must be missing something fundamental here. How do you write a closure type that's generic on the output but still requires that the output must live as long as the input? How would you fix the code I linked so that all three comparisons in main compile?
4 posts - 3 participants
🏷️ Rust_feed