Skip to content
This repository has been archived by the owner on Sep 7, 2023. It is now read-only.

Rc::project is unsound. #3

Open
steffahn opened this issue Jan 9, 2023 · 4 comments
Open

Rc::project is unsound. #3

steffahn opened this issue Jan 9, 2023 · 4 comments

Comments

@steffahn
Copy link

steffahn commented Jan 9, 2023

Adapted from: Kimundi/owning-ref-rs#71.

Reproducing example:

use shared_rc::Rc;

fn main() {
    let x = Rc::new_owner(());
    let z: Rc<str, ()>;
    {
        let s = "Hello World!".to_string();
        let s_ref: &str = &s;
        let y: Rc<&str, ()> = Rc::project(x, |_| &s_ref);
        z = Rc::project(y, |s: &&str| *s);
        // s deallocated here
    }
    println!("{}", &*z); // printing garbage, accessing `s` after it’s freed
}

Applies to Arc, too, of course.

@steffahn
Copy link
Author

steffahn commented Jan 9, 2023

For comparison: using yoke with Yoke<&'static T, Rc<Owner>> requires T to be static.

The more general alternative I proposed in the linked owning-ref thread is to add a lifetime parameter, i.e. for this crate something like Rc<'a, T, Owner> with a T: 'a bound. As long as 'static is used for that parameter, this reduces back to the T: 'static bound. The reason why this fixes the problem is fairly analogous to the explanation here.

@CAD97
Copy link
Contributor

CAD97 commented Jan 9, 2023

Darn it, I knew I was going to do something wrong. What's different between this and Yoke::map_project that the latter ends up being sound?

Independent of the fact that their projection lifetime ends up being invariant, it's that the manipulated lifetime has to be the only lifetime, isn't it. So the solution needs to be a T: 'static bound or reintroducing the trait Covariant<'a> cover. Fun, I hadn't realized that there was a for<T: 'static> T/for<T: Trait> &'_ T impl conflict dodge going on in yoke... I seem to bump into that overlap a lot for some reason.

I'm actively considering just yanking and replacing with a compile_error!("use yoke instead"). IIRC I wrote and published this because it doesn't have the noalias issue by virtue of restricting itself to Rc. But given progress towards addressing that and the determination that it's probably not LLVM UB (yet)...

@CAD97
Copy link
Contributor

CAD97 commented Jan 9, 2023

I write slowly and cross-reference stuff that I started before your second comment and it didn't show up in the app 🙃

@CAD97 CAD97 pinned this issue Sep 7, 2023
@CAD97
Copy link
Contributor

CAD97 commented Sep 7, 2023

I've experimented some with different ways of closing this hole, and I think any way of doing so makes the alleged benefit of specializing to just Rc effectively moot. I've yanked 0.1.1 as well, and am going to just archive this repo. People should just use yoke.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants