Licenser · GitHub

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!");
}

Read the original on github.com ↗