The following code compiles without complaint, but I don't understand why! It is derived from a real-world use case where I am getting
trait
DerefMut
is required to modify through a dereference, but it is not implemented forPgRelation
Here, I don't get the error, even though afact I've set things up in a way that should trigger it. Hoping someone here can help!
use std::ops::Deref;
pub type PgStatCounter = i64;
#[repr(C)]
pub struct RelationData {
pub pgstat_info: *mut PgStatTableStatus,
}
#[repr(C)]
pub struct PgStatTableCounts {
pub numscans: PgStatCounter,
}
#[repr(C)]
pub struct PgStatTableStatus {
pub counts: PgStatTableCounts,
}
pub struct PgRelation {
boxed: Box<RelationData>,
}
impl Deref for PgRelation {
type Target = Box<RelationData>;
fn deref(&self) -> &Self::Target {
&self.boxed
}
}
fn main() {
let mut status = PgStatTableStatus {
counts: PgStatTableCounts {
numscans: 0,
}
};
let rel = PgRelation {
boxed: Box::new(
RelationData {
pgstat_info: &mut status as *mut PgStatTableStatus,
}
)
};
// Now try incrementing `numscans` via `rel`. Will this work?
unsafe {
if !rel.pgstat_info.is_null() {
// Since PgRelation does not implement DerefMut, I would expect an
// error like:
//
// error[E0596]: cannot borrow data in dereference of `PgRelation` as mutable
// --> src/lib.rs:13:11
// |
// 13 | (*rel.pgstat_info).counts.numscans += 1;
// | ^^^ cannot borrow as mutable
// |
// = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `PgRelation`
//
// And yet, it compiles without errors! Why?
(*rel.pgstat_info).counts.numscans += 1;
}
}
}
Errors:
Compiling playground v0.0.1 (/playground)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.57s
Running `target/debug/playground`