|
|
|
|
|
by chc4
690 days ago
|
|
Mark and sweep doesn't stop you from holding references across GC. If you write e.g. ```
let obj = some_object();
let len : &mut usize = &mut obj.len; // deref_mut
trigger_gc();
use(*len);
``` then you held a reference across the GC, and while it's mark/sweeping created an aliases `&mut` to `len`. Inlining was mention just because it causes function bodies to be splatting together, and so puts together code that is fine in isolation in a way that may allow Rust to observe UB: if `trigger_gc` was inlined for example then Rust has more information and code available at once, and might use the knowledge to apply some optimizations that are invalid because you caused UB. Actually, looking at your code the much larger issue is that nothing stops you from doing ```
let obj = some_object();
let obj2 = obj.clone();
let len1 = &mut obj.len;
let len2 = &mut obj2.len;
let n = *len1;
*len2 = 0;
println!("{n}"); // what does this print?
```
because your Deref mut are just creating unconstrained borrow from pointer types that you can copy. This is almost definitely going to cause you bugs in the future, since it opens you up to accidentally writing iterator invalidation and other issues (and even worse than C++ does, because C++ doesn't optimize references as heavily as Rust does borrows) |
|