diff --git a/mir/src/ir/nodes/ops/accessor.rs b/mir/src/ir/nodes/ops/accessor.rs index 5a5d8318f..ba2b07186 100644 --- a/mir/src/ir/nodes/ops/accessor.rs +++ b/mir/src/ir/nodes/ops/accessor.rs @@ -70,6 +70,9 @@ impl Child for Accessor { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/add.rs b/mir/src/ir/nodes/ops/add.rs index e5bfe1ebf..a09025f0a 100644 --- a/mir/src/ir/nodes/ops/add.rs +++ b/mir/src/ir/nodes/ops/add.rs @@ -33,10 +33,51 @@ impl Child for Add { fn get_parents(&self) -> Vec> { self.parents.clone() } + fn add_parent(&mut self, parent: Link) { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add_remove_parent_removes_only_target() { + let span = SourceSpan::default(); + + let lhs: Link = Op::None(span).into(); + let rhs: Link = Op::None(span).into(); + + let mut add = Add { + parents: Vec::new(), + lhs, + rhs, + _node: Singleton::default(), + _owner: Singleton::default(), + span, + }; + + let owner1: Link = Owner::None(span).into(); + let owner2: Link = Owner::None(span).into(); + + add.add_parent(owner1.clone()); + add.add_parent(owner2.clone()); + assert_eq!(add.get_parents().len(), 2); + + add.remove_parent(owner1.clone()); + + let parents = add.get_parents(); + assert_eq!(parents.len(), 1); + let remaining = + parents[0].to_link().expect("BackLink should upgrade to Link"); + assert_eq!(remaining, owner2); } } diff --git a/mir/src/ir/nodes/ops/boundary.rs b/mir/src/ir/nodes/ops/boundary.rs index 8785fa018..5c0c775e9 100644 --- a/mir/src/ir/nodes/ops/boundary.rs +++ b/mir/src/ir/nodes/ops/boundary.rs @@ -52,6 +52,9 @@ impl Child for Boundary { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/bus_op.rs b/mir/src/ir/nodes/ops/bus_op.rs index a868275ca..e37f9ea69 100644 --- a/mir/src/ir/nodes/ops/bus_op.rs +++ b/mir/src/ir/nodes/ops/bus_op.rs @@ -79,6 +79,9 @@ impl Child for BusOp { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/call.rs b/mir/src/ir/nodes/ops/call.rs index efa169328..95c98cff5 100644 --- a/mir/src/ir/nodes/ops/call.rs +++ b/mir/src/ir/nodes/ops/call.rs @@ -53,6 +53,9 @@ impl Child for Call { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/enf.rs b/mir/src/ir/nodes/ops/enf.rs index 0206a4023..d2e8b8451 100644 --- a/mir/src/ir/nodes/ops/enf.rs +++ b/mir/src/ir/nodes/ops/enf.rs @@ -36,6 +36,9 @@ impl Child for Enf { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/exp.rs b/mir/src/ir/nodes/ops/exp.rs index c888d1cf6..cdc0fc9ab 100644 --- a/mir/src/ir/nodes/ops/exp.rs +++ b/mir/src/ir/nodes/ops/exp.rs @@ -39,6 +39,9 @@ impl Child for Exp { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/fold.rs b/mir/src/ir/nodes/ops/fold.rs index 0ca0a7c9d..d14bd919f 100644 --- a/mir/src/ir/nodes/ops/fold.rs +++ b/mir/src/ir/nodes/ops/fold.rs @@ -65,6 +65,9 @@ impl Child for Fold { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/for_op.rs b/mir/src/ir/nodes/ops/for_op.rs index 9ab9a200d..c1eb1440d 100644 --- a/mir/src/ir/nodes/ops/for_op.rs +++ b/mir/src/ir/nodes/ops/for_op.rs @@ -62,6 +62,9 @@ impl Child for For { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/if_op.rs b/mir/src/ir/nodes/ops/if_op.rs index 023f65634..d0939154e 100644 --- a/mir/src/ir/nodes/ops/if_op.rs +++ b/mir/src/ir/nodes/ops/if_op.rs @@ -65,6 +65,9 @@ impl Child for If { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/matrix.rs b/mir/src/ir/nodes/ops/matrix.rs index 277783ca4..f7270e330 100644 --- a/mir/src/ir/nodes/ops/matrix.rs +++ b/mir/src/ir/nodes/ops/matrix.rs @@ -45,6 +45,9 @@ impl Child for Matrix { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/mul.rs b/mir/src/ir/nodes/ops/mul.rs index 247123755..1519e1f09 100644 --- a/mir/src/ir/nodes/ops/mul.rs +++ b/mir/src/ir/nodes/ops/mul.rs @@ -37,6 +37,9 @@ impl Child for Mul { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/parameter.rs b/mir/src/ir/nodes/ops/parameter.rs index 939215d27..ec5f798d3 100644 --- a/mir/src/ir/nodes/ops/parameter.rs +++ b/mir/src/ir/nodes/ops/parameter.rs @@ -83,6 +83,9 @@ impl Child for Parameter { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/sub.rs b/mir/src/ir/nodes/ops/sub.rs index 94e2c00ad..36ec37f12 100644 --- a/mir/src/ir/nodes/ops/sub.rs +++ b/mir/src/ir/nodes/ops/sub.rs @@ -37,6 +37,9 @@ impl Child for Sub { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/value.rs b/mir/src/ir/nodes/ops/value.rs index dbd7791be..4c35aea53 100644 --- a/mir/src/ir/nodes/ops/value.rs +++ b/mir/src/ir/nodes/ops/value.rs @@ -50,7 +50,10 @@ impl Child for Value { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } } diff --git a/mir/src/ir/nodes/ops/vector.rs b/mir/src/ir/nodes/ops/vector.rs index fc53c3d67..570d8d582 100644 --- a/mir/src/ir/nodes/ops/vector.rs +++ b/mir/src/ir/nodes/ops/vector.rs @@ -44,6 +44,9 @@ impl Child for Vector { self.parents.push(parent.into()); } fn remove_parent(&mut self, parent: Link) { - self.parents.retain(|p| *p != parent.clone().into()); + self.parents.retain(|p| match p.to_link() { + Some(link) => link != parent, + None => true, + }); } }