(maybe?) fixed inner mutability on immutable (shared) values

This commit is contained in:
mark 2023-05-12 15:32:56 +02:00
parent c501a6e558
commit f8102c8fe6
3 changed files with 22 additions and 23 deletions

View File

@ -276,7 +276,7 @@ impl RStatementEnum {
}
VDataEnum::Tuple(vec![]).to()
}
Self::IndexFixed(st, i) => st.run(vars, info).get(*i).unwrap(),
Self::IndexFixed(st, i) => st.run(vars, info).get(*i, false).unwrap(),
Self::EnumVariant(e, v) => VDataEnum::EnumVariant(*e, Box::new(v.run(vars, info))).to(),
}
}

View File

@ -92,22 +92,14 @@ impl Clone for VData {
fn clone(&self) -> Self {
let mut d = self.data.lock().unwrap();
let o = if d.1 {
if Arc::strong_count(&self.data) > 1 {
// mutable, copy the value to avoid accidentally modifying it.
#[cfg(debug_assertions)]
eprintln!(
"VData: Clone: copying value due to clone of a mutable shared value. (strong count: {})",
Arc::strong_count(&self.data)
);
d.0.clone().to()
} else {
// mutable, but not shared. just change it to not being mutable.
d.1 = false;
// then return the same arc (-> avoid cloning)
Self {
data: Arc::clone(&self.data),
}
}
// mutable, copy the value to avoid accidentally modifying it.
// DON'T just set it to immutable even if we are the only reference (inner mutability!)
#[cfg(debug_assertions)]
eprintln!(
"VData: Clone: copying value due to clone of a mutable value. (strong count: {})",
Arc::strong_count(&self.data)
);
d.0.clone().to()
} else {
// immutable, return the same arc (-> avoid cloning)
Self {
@ -207,8 +199,15 @@ impl VData {
VDataEnum::EnumVariant(e, v) => VSingleType::EnumVariant(*e, v.out()),
}
}
pub fn get(&self, i: usize) -> Option<Self> {
self.data().0.get(i)
pub fn get(&self, i: usize, as_mut: bool) -> Option<Self> {
if let Some(mut d) = self.data().0.get(i) {
if as_mut {
d.make_mut();
}
Some(d)
} else {
None
}
}
pub fn noenum(self) -> Self {
self.inner().noenum()
@ -218,7 +217,7 @@ impl VData {
impl VDataEnum {
pub fn to(self) -> VData {
VData {
data: Arc::new(Mutex::new((self, true))),
data: Arc::new(Mutex::new((self, false))),
}
}
pub fn deref(self) -> Option<VData> {
@ -260,8 +259,8 @@ impl VDataEnum {
None => None,
},
Self::Tuple(v) | Self::List(_, v) => v.get(i).cloned(),
Self::Reference(r) => r.get(i),
Self::EnumVariant(_, v) => v.get(i),
Self::Reference(r) => r.get(i, false),
Self::EnumVariant(_, v) => v.get(i, false),
}
}
pub fn matches_ref_bool(&self) -> bool {

View File

@ -177,7 +177,7 @@ impl VType {
}
}
pub fn contains(&self, t: &VSingleType, info: &GlobalScriptInfo) -> bool {
self.types.iter().any(|s| t.fits_in(s, info))
t.fits_in_type(self, info)
}
pub fn noenum(self) -> Self {
let mut o = Self { types: vec![] };