mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Re-derive the shared edge pointer and type-check the paint transmute
This commit is contained in:
@@ -124,6 +124,13 @@ impl<N: ?Sized> SharedEdge<N> {
|
||||
pub fn share(&self) -> Self {
|
||||
Self { ptr: self.ptr, own: self.own.clone() }
|
||||
}
|
||||
|
||||
/// Re-derives the cached pointer from the owned payload. An exclusive
|
||||
/// re-borrow of the payload invalidates the pointer taken before it, so
|
||||
/// every mutation through `own` ends here.
|
||||
pub fn rederive(&mut self) {
|
||||
self.ptr = std::ptr::NonNull::from(&*self.own);
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: `ptr` is derived from the owned Arc and never mutated through, so the edge is exactly as
|
||||
@@ -222,6 +229,7 @@ impl EdgeHandle {
|
||||
let shared = edge.downcast_mut::<SharedEdge<N>>().expect("set_layout hook matches the stored edge type");
|
||||
let node = std::sync::Arc::get_mut(&mut shared.own).expect("layout is installed before the node is shared");
|
||||
Node::<ContextImpl>::set_layout(node, layout);
|
||||
shared.rederive();
|
||||
},
|
||||
ty,
|
||||
}
|
||||
|
||||
@@ -378,9 +378,21 @@ fn forced_paint<'a, A: Attribute>(paint: LanePaint<'a>) -> Option<A::Value<'a>>
|
||||
name if name == Stroke::NAME => paint.stroke,
|
||||
_ => None,
|
||||
}?;
|
||||
assert_eq!(
|
||||
std::any::TypeId::of::<A::Value<'static>>(),
|
||||
std::any::TypeId::of::<Option<&'static List<Graphic<'static>>>>(),
|
||||
"attribute `{}` is declared at another value type than this crate's paint form",
|
||||
A::NAME
|
||||
);
|
||||
assert_eq!(
|
||||
size_of::<A::Value<'a>>(),
|
||||
size_of::<Option<&'a List<Graphic<'a>>>>(),
|
||||
"the paint value form must span the marker's value"
|
||||
);
|
||||
// SAFETY: the census admits one value type per attribute name and panics on
|
||||
// a conflict at registration, so a marker named `fill` or `stroke` carries
|
||||
// this crate's `Option<&List<Graphic>>` value form.
|
||||
// a conflict at registration, and the asserts above re-check it, so a marker
|
||||
// named `fill` or `stroke` carries this crate's `Option<&List<Graphic>>`
|
||||
// value form at the same size.
|
||||
Some(unsafe { std::mem::transmute_copy::<Option<&'a List<Graphic>>, A::Value<'a>>(&Some(slot)) })
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user