Comment by MrBuddyCasino
11 days ago
The heart of the matter:
struct Q<T: 'static>(Option<T>);
impl<T: 'static> Drop for Q<T> {
fn drop(&mut self) {
// Code in here has access to a non-'static &String
// but assumes that it's a &'static String
}
}
fn main() {
let l = String::new();
let mut q = Q(None);
q.0 = Some(&l);
}
I wonder if the certified compiler for safety critical uses (edit: Ferrocene) has the same issue.
> I wonder if the certified compiler for safety critical uses has the same issue.
It uses the same code, so yes.
(Although I don't know what are their guidelines, it might be that they require avoiding code relying on implied bounds, for example).
Can someone ELI5 for people who don't know Rust (but e.g. C)?
Rust is supposed to guarantee statically that a reference cannot outlive its referent. The `T: 'static` bound means that the value that Q holds must have a 'static lifetime (e.g. either be an owned value or a reference to a static value). So this program should not compile since a reference to l is not 'static. This code is unsound because rust will drop the string l before q so when the Q destructor runs the underlying string has already been freed yet we have a valid reference to it.
So the equivalent in C would be:
(The equivalent warning is main.c:47)
5 replies →
What does "q.0" and "Some(...)" mean?
4 replies →
> rust will drop the string l before q
Why?
2 replies →
'static lifetime bounds are kind of confusing in Rust, but here goes: A 'static lifetime constraint on T says: types that satisfy T must not contain any borrowed value/content whose lifetime will be shorter than the life of the program. So suppose you have a string s, and Option<&String> q. If q has the constraint 'static, and you do q = Some(&s) this should be rejected by the compiler since a reference to s gets a shorter lifetime than 'static by default (you could do q = Some(&'static s) if s is say a string literal or a leaked box but not for a normal string). In the examples it looks like you have to use a tuple to trick the borrow checker but the concept is the same: Rust allowed violation of the 'static lifetime bounds. The drop implemenation demonstrates it: drop happens in reverse declaration order, so the string s gets dropped first. Now q has a dangling reference, a pointer to dropped memory essentially, and we get a pretty classic use after free bug.
which compiler?
Ferrocene
DeepSeek v4.1 Flash thinks it should NOT compile. Whereas in reality it DOES compile which is why it is filed as a bug.
They're seriously using AI as a judge for what to file?
The issue and none of the comments mention AI. It is pretty clear your parent said it by themselves.
I was just checking what outcome an LLM would have based on the patterns in its probabilistic distribution it has seen the wild.
Most LLMs would probably say this piece of code won't compile.
1 reply →