Here's my erroneous code:
use std::collections::HashSet;
pub struct Program<'a: 'b, 'b> {
pub list: Vec<Box<dyn Op<'a, 'b>>>,
}
/* Here's a very simple example of a struct that could be in my Program.list.
I am keeping it commented because the error still happens without it.
*/
/*
#[derive(Debug)]
pub struct Instruction<'a>(Reg<'a>);
impl<'a: 'b, 'b> TaintAnalysis<'a, 'b> for Instruction<'a> {
fn taint_analysis(&'b self, tainted: &mut HashSet<GlobalOrReg<'a, 'b>>) -> bool {
todo!()
}
}
impl<'a: 'b, 'b> Op<'a, 'b> for Instruction<'a> {}
*/
pub trait Op<'a: 'b, 'b>: std::fmt::Debug + TaintAnalysis<'a, 'b> {}
pub trait TaintAnalysis<'a: 'b, 'b> {
fn taint_analysis(&'b self, tainted: &mut HashSet<GlobalOrReg<'a, 'b>>) -> bool;
}
pub enum GlobalOrReg<'a: 'b, 'b> {
Global(&'b Global<'a>),
Reg(&'b Reg<'a>),
Other,
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct Global<'a>(pub &'a str);
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct Reg<'a>(pub &'a str);
fn main() -> Result<(), String> {
let prog = Program {list: vec![/*Instruction(Reg("t1"))*/]};
{ // I added this scope to try to fix the error but it did nothing
let mut tainted_set = HashSet::new();
for op in &prog.list {
if op.taint_analysis(&mut tainted_set) {
println!("FLOW");
return Ok(());
}
}
println!("NO FLOW");
return Ok(());
}
}
The error:
Compiling playground v0.0.1 (/playground)
error[E0597]: `prog.list` does not live long enough
--> src/main.rs:42:19
|
39 | let prog = Program {list: vec![/*Instruction(Reg("t1"))*/]};
| ---- binding `prog` declared here
...
42 | for op in &prog.list {
| ^^^^^^^^^^ borrowed value does not live long enough
...
51 | }
| -
| |
| `prog.list` dropped here while still borrowed
| borrow might be used here, when `prog` is dropped and runs the destructor for type `Program<'_, '_>`
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (bin "playground") due to 1 previous error
I notice that when I remove tainted_set
from main
, the error goes away. So I think that means that Rust thinks that the references stored in tainted_set
could still be around when prog
is dropped. But that doesn't make sense to me, because tainted_set
is dropped before prog
, especially since I put it in its own scope. What is going on? What does the type analysis see here?