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

View File

@ -177,7 +177,7 @@ impl VType {
} }
} }
pub fn contains(&self, t: &VSingleType, info: &GlobalScriptInfo) -> bool { 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 { pub fn noenum(self) -> Self {
let mut o = Self { types: vec![] }; let mut o = Self { types: vec![] };