abi_stable_crates: lifetimes with R* types break compared to non R* types
Hi, sorry for the bad title, I’m not sure how to phrase the issue in a concise one-line description.
It seems that something inside abi_stables R* types breaks rusts lifetime tracking. We (@marioortizmanero and the rest of the tremor team) went through the attempt of using them for internal data as part of his PDK project and got to the point where a lot of lifetime errors (the nasty kind) were thrown up.
Initially, we suspected that we had done something wrong in the interpreter using the data so we tried to find the underlying cause and boiled it down to (hopefully) one initial issue that doesn’t require to go through 1000s of lines of code 😃
Basically, the following code
use abi_stable::std_types::RCow;
use std::borrow::Cow;
fn cmp_cow<'a, 'b>(left: &Cow<'a, ()>, right: &Cow<'b, ()>) -> bool {
left == right
}
fn cmp_rcow<'a, 'b>(left: &RCow<'a, ()>, right: &RCow<'b, ()>) -> bool {
left == right
}
fn main() {
println!("Hello, world!");
}
fails with the following error:
Checking repro v0.1.0 (/home/heinz/mario/repro)
error[E0623]: lifetime mismatch
--> src/main.rs:9:10
|
8 | fn cmp_rcow<'a, 'b>(left: &RCow<'a, ()>, right: &RCow<'b, ()>) -> bool {
| ------------ ------------
| |
| these two types are declared with different lifetimes...
9 | left == right
| ^^ ...but data from `left` flows into `right` here
For more information about this error, try `rustc --explain E0623`.
error: could not compile `repro` due to previous error
We could reproduce the same for RVec, and RHashMap as long they contained a lifetime.
Below a more extensive test with a number of other types:
use abi_stable::std_types::{RCow, RHashMap, RSlice, RStr, RString, RVec, Tuple2};
use std::{borrow::Cow, collections::HashMap};
fn cmp_string<'a, 'b>(left: &String, right: &String) -> bool {
left == right
}
fn cmp_rstring<'a, 'b>(left: &RString, right: &RString) -> bool {
left == right
}
fn cmp_str<'a, 'b>(left: &'a str, right: &'b str) -> bool {
left == right
}
fn cmp_rstr<'a, 'b>(left: &RStr<'a>, right: &RStr<'b>) -> bool {
left == right
}
fn cmp_vec<'a, 'b>(left: &Vec<&'a str>, right: &Vec<&'b str>) -> bool {
left == right
}
fn cmp_rvec<'a, 'b>(left: &RVec<&'a str>, right: &RVec<&'b str>) -> bool {
left == right
}
fn cmp_tpl<'a, 'b>(left: &(&'a str, u8), right: &(&'b str, u8)) -> bool {
left == right
}
fn cmp_rtpl<'a, 'b>(left: &Tuple2<&'a str, u8>, right: &Tuple2<&'b str, u8>) -> bool {
left == right
}
fn cmp_slice<'a, 'b>(left: &[&'a str], right: &[&'b str]) -> bool {
left == right
}
fn cmp_rslice<'a, 'b>(left: &RSlice<&'a str>, right: &RSlice<&'b str>) -> bool {
left == right
}
fn cmp_cow<'a, 'b>(left: &Cow<'a, ()>, right: &Cow<'b, ()>) -> bool {
left == right
}
fn cmp_rcow<'a, 'b>(left: &RCow<'a, ()>, right: &RCow<'b, ()>) -> bool {
left == right
}
fn cmp_hashmap<'a, 'b>(left: &HashMap<&'a str, ()>, right: &HashMap<&'a str, ()>) -> bool {
left == right
}
fn cmp_rhashmap<'a, 'b>(left: &RHashMap<u8, &'a str>, right: &RHashMap<u8, &'b str>) -> bool {
left == right
}
fn main() {
println!("Hello, world!");
}
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 2
- Comments: 17 (16 by maintainers)
Commits related to this issue
- Rewrote RCow to make it covariant instead of invariant. Fixing the lifetime issues (WRT RCow) in https://github.com/rodrimati1992/abi_stable_crates/issues/75 Changed how `RCow` is represented, requi... — committed to rodrimati1992/abi_stable_crates by rodrimati1992 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up See https://github.com/rodrim... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up See https://github.com/rodrim... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up See https://github.com/rodrim... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up See https://github.com/rodrim... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up See https://github.com/rodrimati1992/... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up * Fix metronome plugin See https://g... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up * Fix metronome plugin See https://g... — committed to marioortizmanero/tremor-runtime by deleted user 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up * Fix metronome plugin See https://g... — committed to marioortizmanero/tremor-runtime by marioortizmanero 2 years ago
- PDK with a single value (#11) * Back to attempt with single value * Go back to known_key stub approach * Update to new `RCow` * Lots of fixes and cleaning up * Fix metronome plugin See https://g... — committed to marioortizmanero/tremor-runtime by marioortizmanero 2 years ago
- Rewrote RCow to make it covariant instead of invariant. Fixing the lifetime issues (WRT RCow) in https://github.com/rodrimati1992/abi_stable_crates/issues/75 Changed how `RCow` is represented, requi... — committed to rodrimati1992/abi_stable_crates by rodrimati1992 2 years ago
This has finally been fixed and can be closed.
I’ve opened a new issue with the tasks that must be done: #81. This one is quite filled with discussion about how we figured out that the issue was variance, and it will be easier to track the progress in there. You can close this if you like, @rodrimati1992.
Oh my god, okay, I’m not crazy. I’ve been banging my head against the wall all day trying to fix this. I’ve tried literally everything. And I have some confirmation that it is indeed unsolvable in the case of
Ord:At some point I decided to give up and ask for help in Rust’s unofficial Discord server because they are absolute geniuses. And indeed it helped a lot: I was right that
BorrowOwnedwas the issue, but I didn’t know the concept of “subtyping and variance”.BorrowOwnedmakes it impossible to have comparisons with different lifetimes, because it makes the trait invariant:std’s implementation doesn’t bindCow’s lifetime to any trait in its implementation ofOrd, so it’s covariant:Not sure if you’re familiar with those terms; I certainly wasn’t. There’s more info here. I still don’t know much about it, so I can’t provide any solutions. For now, I can only think of:
BorrowOwnedand having people useRCow<RStr>(which isn’t that terrible); orRBorrowedtype inside of it. I was told that GATs don’t solve the issue completely, though.Just wanted to give a quick update about today’s suffering. I’ll give another update some other day.
Can confirm that the problem lies in the implementations of
PartialEqforR*types. Will submit a PR soon.