-
Notifications
You must be signed in to change notification settings - Fork 64
Open
Description
The lifetime based alias analysis inserts on-existent dependencies when a called function's lifetime annotations claim such a dependency exists.
Consider the following example
fn insert_ref<'v, 't: 'v, T>(v: &mut Vec<&'v T>, t: &'t T) {}
fn main() {
let x = /* some object */;
let mut v = Vec::new();
insert_ref(&mut v, &x);
read(&v);
}The resulting PDG has an edge from x to the &v argument of read, even though x is never added to the vector.
Implications on async
Perhaps more worryingly this also occurs when async functions are used.
async fn handle(ud1: &UserData, ud2: &mut UserData) {
read(ud1);
write(ud2);
}
async fn main() {
let mut ud1 = get_user_data();
let mut ud2 = get_user_data();
handle(&ud1, &mut ud2).await;
}
// external functions
fn read<T>(read: &T);
fn write<T>(written: &mut T);In this example the PDG shows a connection ud1 -> written which does not actually exist.
Similarly, and perhaps more concerning, the same effect is also visible in the caller, e.g.
async fn handle(ud1: &UserData, ud2: &mut UserData) {
}
async fn main() {
let mut ud1 = get_user_data();
let mut ud2 = get_user_data();
handle(&ud1, &mut ud2).await;
read(ud1);
write(ud2);
}Also has a ud1 -> written edge.
This seems to be caused by into_future and new_unchecked, which is called automatically by the await desugaring.
Metadata
Metadata
Assignees
Labels
No labels