[librsvg: 1/2] filters: simplify code to render filters



commit adcb65f8f82b3e6debd2fb675ba9b050f76b61c8
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Jun 2 16:15:03 2019 +0200

    filters: simplify code to render filters
    
    Instead of using owning_ref, we define an as_filter method
    on the NodeTrait that returns None for other nodes and returns
    the Filter trait for filter primitives.

 Cargo.lock                                       |  16 ----
 rsvg_internals/Cargo.toml                        |   1 -
 rsvg_internals/src/filters/blend.rs              |   2 +
 rsvg_internals/src/filters/color_matrix.rs       |   2 +
 rsvg_internals/src/filters/component_transfer.rs |   2 +
 rsvg_internals/src/filters/composite.rs          |   2 +
 rsvg_internals/src/filters/convolve_matrix.rs    |   2 +
 rsvg_internals/src/filters/displacement_map.rs   |   2 +
 rsvg_internals/src/filters/flood.rs              |   2 +
 rsvg_internals/src/filters/gaussian_blur.rs      |   2 +
 rsvg_internals/src/filters/image.rs              |   2 +
 rsvg_internals/src/filters/light/lighting.rs     |   2 +
 rsvg_internals/src/filters/merge.rs              |   2 +
 rsvg_internals/src/filters/mod.rs                | 113 +++++++----------------
 rsvg_internals/src/filters/morphology.rs         |   2 +
 rsvg_internals/src/filters/offset.rs             |   2 +
 rsvg_internals/src/filters/tile.rs               |   2 +
 rsvg_internals/src/filters/turbulence.rs         |   2 +
 rsvg_internals/src/node.rs                       |  14 ++-
 19 files changed, 77 insertions(+), 97 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 0a8f5475..f7d00f6e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -630,14 +630,6 @@ name = "numtoa"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 
-[[package]]
-name = "owning_ref"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-dependencies = [
- "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "pango"
 version = "0.6.0"
@@ -982,7 +974,6 @@ dependencies = [
  "markup5ever 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "nalgebra 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1046,11 +1037,6 @@ name = "smallvec"
 version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 
-[[package]]
-name = "stable_deref_trait"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-
 [[package]]
 name = "string_cache"
 version = "0.7.3"
@@ -1319,7 +1305,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = 
"6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
 "checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
 "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
-"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
 "checksum pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"4e36b55d7cd522bd183efeb3dfabc547bda1f26eadf8a1241dac09ab3fd3242c"
 "checksum pango-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"747ab9cd4d537e6dc5ef0e4308c10dde8b706673b0237fed4e056b8d2c0b23c8"
 "checksum pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"706e885b46a16ba96f46f3c8d880ca6082c2c62693b75f3d167bd3aa4e34b0d4"
@@ -1363,7 +1348,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index";
 "checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = 
"5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
 "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
 "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = 
"c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
-"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = 
"dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = 
"25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
 "checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = 
"b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 919bcd0e..737f9adc 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -41,7 +41,6 @@ locale_config = "*" # recommended explicitly by locale_config's README.md
 markup5ever = "0.8.1"
 nalgebra = "0.18"
 num-traits = "0.2"
-owning_ref = "0.4.0"
 pango = "0.6.0"
 pango-sys = "0.8.0"
 pangocairo = "0.7.0"
diff --git a/rsvg_internals/src/filters/blend.rs b/rsvg_internals/src/filters/blend.rs
index 993f468a..9dd2f7db 100644
--- a/rsvg_internals/src/filters/blend.rs
+++ b/rsvg_internals/src/filters/blend.rs
@@ -44,6 +44,8 @@ impl Default for Blend {
 }
 
 impl NodeTrait for Blend {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/color_matrix.rs b/rsvg_internals/src/filters/color_matrix.rs
index c70ecc65..8963fc7a 100644
--- a/rsvg_internals/src/filters/color_matrix.rs
+++ b/rsvg_internals/src/filters/color_matrix.rs
@@ -48,6 +48,8 @@ impl Default for ColorMatrix {
 }
 
 impl NodeTrait for ColorMatrix {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/component_transfer.rs 
b/rsvg_internals/src/filters/component_transfer.rs
index 21a00780..eb9634ac 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -202,6 +202,8 @@ impl FuncX {
 }
 
 impl NodeTrait for ComponentTransfer {
+    impl_node_as_filter!();
+
     #[inline]
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)
diff --git a/rsvg_internals/src/filters/composite.rs b/rsvg_internals/src/filters/composite.rs
index fa247fce..959f3ba8 100644
--- a/rsvg_internals/src/filters/composite.rs
+++ b/rsvg_internals/src/filters/composite.rs
@@ -60,6 +60,8 @@ impl Default for Composite {
 }
 
 impl NodeTrait for Composite {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index 6f2c1c5d..1b56bd0c 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -57,6 +57,8 @@ impl Default for ConvolveMatrix {
 }
 
 impl NodeTrait for ConvolveMatrix {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/displacement_map.rs b/rsvg_internals/src/filters/displacement_map.rs
index 68374d3a..0faacd1c 100644
--- a/rsvg_internals/src/filters/displacement_map.rs
+++ b/rsvg_internals/src/filters/displacement_map.rs
@@ -46,6 +46,8 @@ impl Default for DisplacementMap {
 }
 
 impl NodeTrait for DisplacementMap {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/flood.rs b/rsvg_internals/src/filters/flood.rs
index a501b5cf..5fb457cc 100644
--- a/rsvg_internals/src/filters/flood.rs
+++ b/rsvg_internals/src/filters/flood.rs
@@ -25,6 +25,8 @@ impl Default for Flood {
 }
 
 impl NodeTrait for Flood {
+    impl_node_as_filter!();
+
     #[inline]
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)
diff --git a/rsvg_internals/src/filters/gaussian_blur.rs b/rsvg_internals/src/filters/gaussian_blur.rs
index 40bf098e..84866763 100644
--- a/rsvg_internals/src/filters/gaussian_blur.rs
+++ b/rsvg_internals/src/filters/gaussian_blur.rs
@@ -42,6 +42,8 @@ impl Default for GaussianBlur {
 }
 
 impl NodeTrait for GaussianBlur {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index bf2f90eb..fd1b9e5f 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -175,6 +175,8 @@ impl Image {
 }
 
 impl NodeTrait for Image {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/light/lighting.rs b/rsvg_internals/src/filters/light/lighting.rs
index cd2f7b98..345bb16d 100644
--- a/rsvg_internals/src/filters/light/lighting.rs
+++ b/rsvg_internals/src/filters/light/lighting.rs
@@ -96,6 +96,8 @@ impl Lighting {
 }
 
 impl NodeTrait for Lighting {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/merge.rs b/rsvg_internals/src/filters/merge.rs
index f42742c8..ab287783 100644
--- a/rsvg_internals/src/filters/merge.rs
+++ b/rsvg_internals/src/filters/merge.rs
@@ -34,6 +34,8 @@ impl Default for Merge {
 }
 
 impl NodeTrait for Merge {
+    impl_node_as_filter!();
+
     #[inline]
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index 971b2faa..b80f4396 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -3,20 +3,18 @@ use std::ops::Deref;
 use std::time::Instant;
 
 use cairo::{self, MatrixTrait};
-use owning_ref::RcRef;
 
 use crate::bbox::BoundingBox;
 use crate::coord_units::CoordUnits;
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::{RenderingError, ValueErrorKind};
 use crate::length::{LengthHorizontal, LengthUnit, LengthVertical};
-use crate::node::{CascadedValues, NodeData, NodeResult, NodeTrait, NodeType, RsvgNode};
+use crate::node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
 use crate::parsers::{ParseError, ParseValue};
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::ColorInterpolationFilters;
 use crate::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
-use crate::tree_utils::{Node, NodeRef};
 
 mod bounds;
 use self::bounds::BoundsBuilder;
@@ -33,24 +31,8 @@ use self::input::Input;
 pub mod node;
 use self::node::NodeFilter;
 
-pub mod blend;
-pub mod color_matrix;
-pub mod component_transfer;
-pub mod composite;
-pub mod convolve_matrix;
-pub mod displacement_map;
-pub mod flood;
-pub mod gaussian_blur;
-pub mod image;
-pub mod light;
-pub mod merge;
-pub mod morphology;
-pub mod offset;
-pub mod tile;
-pub mod turbulence;
-
 /// A filter primitive interface.
-trait Filter: NodeTrait {
+pub trait Filter: NodeTrait {
     /// Renders this filter primitive.
     ///
     /// If this filter primitive can't be rendered for whatever reason (for instance, a required
@@ -70,6 +52,30 @@ trait Filter: NodeTrait {
     fn is_affected_by_color_interpolation_filters(&self) -> bool;
 }
 
+macro_rules! impl_node_as_filter {
+    () => (
+        fn as_filter(&self) -> Option<&Filter> {
+            Some(self)
+        }
+    )
+}
+
+pub mod blend;
+pub mod color_matrix;
+pub mod component_transfer;
+pub mod composite;
+pub mod convolve_matrix;
+pub mod displacement_map;
+pub mod flood;
+pub mod gaussian_blur;
+pub mod image;
+pub mod light;
+pub mod merge;
+pub mod morphology;
+pub mod offset;
+pub mod tile;
+pub mod turbulence;
+
 /// The base filter primitive node containing common properties.
 struct Primitive {
     x: Cell<Option<LengthHorizontal>>,
@@ -289,6 +295,8 @@ pub fn render(
 
             !in_error
         })
+        // Keep only filter primitives (those that implement the Filter trait)
+        .filter(|c| c.borrow().get_node_trait().as_filter().is_some())
         // Check if the node wants linear RGB.
         .map(|c| {
             let linear_rgb = {
@@ -299,68 +307,17 @@ pub fn render(
             };
 
             (c, linear_rgb)
-        })
-        // Keep only filter primitives (those that implement the Filter trait)
-        .filter_map(|(c, linear_rgb)| {
-            let rr = RcRef::new(c.0)
-                .try_map(|c: &Node<NodeData>| {
-                    // Go through the filter primitives and see if the node is one of them.
-                    #[inline]
-                    fn as_filter<T: Filter>(x: &T) -> &Filter {
-                        x
-                    }
-
-                    // Unfortunately it's not possible to downcast to a trait object.  So, we
-                    // try downcasting to each filter type individually, and use
-                    // owning_ref::RcRef to reduce the children to a list of
-                    // OwningRef<Rc<Node<NodeData>>, dyn Filter> -- which is essentially the
-                    // NodeRef, and something inside the NodeRef that implements the Filter
-                    // trait.
-                    macro_rules! try_downcasting_to_filter {
-                        ($c:expr; $($t:ty),+$(,)*) => ({
-                            let mut filter = None;
-                            $(
-                                filter = filter.or_else(|| $c.borrow().get_impl::<$t>().map(as_filter));
-                            )+
-                            filter
-                        })
-                    }
-
-                    let filter = try_downcasting_to_filter!(c;
-                        blend::Blend,
-                        color_matrix::ColorMatrix,
-                        component_transfer::ComponentTransfer,
-                        composite::Composite,
-                        convolve_matrix::ConvolveMatrix,
-                        displacement_map::DisplacementMap,
-                        flood::Flood,
-                        gaussian_blur::GaussianBlur,
-                        image::Image,
-                        light::lighting::Lighting,
-                        merge::Merge,
-                        morphology::Morphology,
-                        offset::Offset,
-                        tile::Tile,
-                        turbulence::Turbulence,
-                    );
-                    filter.ok_or(())
-                })
-                .ok();
-
-            rr.map(|rr| (rr, linear_rgb))
         });
 
-    for (rr, linear_rgb) in primitives {
-        // rr: OwningRef<Rc<Node<NodeData>>, dyn Filter>
-
-        let rr_node = NodeRef(rr.as_owner().clone());
+    for (c, linear_rgb) in primitives {
+        let filter = c.borrow().get_node_trait().as_filter().unwrap();
 
         let mut render = |filter_ctx: &mut FilterContext| {
-            if let Err(err) = rr
-                .render(&rr_node, filter_ctx, draw_ctx)
+            if let Err(err) = filter
+                .render(&c, filter_ctx, draw_ctx)
                 .and_then(|result| filter_ctx.store_result(result))
             {
-                rsvg_log!("(filter primitive {} returned an error: {})", rr_node, err);
+                rsvg_log!("(filter primitive {} returned an error: {})", c, err);
 
                 // Exit early on Cairo errors. Continue rendering otherwise.
                 if let FilterError::CairoError(status) = err {
@@ -373,7 +330,7 @@ pub fn render(
 
         let start = Instant::now();
 
-        if rr.is_affected_by_color_interpolation_filters() && linear_rgb {
+        if filter.is_affected_by_color_interpolation_filters() && linear_rgb {
             filter_ctx.with_linear_rgb(render)?;
         } else {
             render(&mut filter_ctx)?;
@@ -382,7 +339,7 @@ pub fn render(
         let elapsed = start.elapsed();
         rsvg_log!(
             "(rendered filter primitive {} in\n    {} seconds)",
-            rr_node,
+            c,
             elapsed.as_secs() as f64 + f64::from(elapsed.subsec_nanos()) / 1e9
         );
     }
diff --git a/rsvg_internals/src/filters/morphology.rs b/rsvg_internals/src/filters/morphology.rs
index 9eabfa87..ed13a0dd 100644
--- a/rsvg_internals/src/filters/morphology.rs
+++ b/rsvg_internals/src/filters/morphology.rs
@@ -48,6 +48,8 @@ impl Default for Morphology {
 }
 
 impl NodeTrait for Morphology {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/offset.rs b/rsvg_internals/src/filters/offset.rs
index 94ebb235..681af12f 100644
--- a/rsvg_internals/src/filters/offset.rs
+++ b/rsvg_internals/src/filters/offset.rs
@@ -34,6 +34,8 @@ impl Default for Offset {
 }
 
 impl NodeTrait for Offset {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
 
diff --git a/rsvg_internals/src/filters/tile.rs b/rsvg_internals/src/filters/tile.rs
index 4269eebb..a9df1a58 100644
--- a/rsvg_internals/src/filters/tile.rs
+++ b/rsvg_internals/src/filters/tile.rs
@@ -24,6 +24,8 @@ impl Default for Tile {
 }
 
 impl NodeTrait for Tile {
+    impl_node_as_filter!();
+
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)
     }
diff --git a/rsvg_internals/src/filters/turbulence.rs b/rsvg_internals/src/filters/turbulence.rs
index be9d5421..3e608dc8 100644
--- a/rsvg_internals/src/filters/turbulence.rs
+++ b/rsvg_internals/src/filters/turbulence.rs
@@ -59,6 +59,8 @@ impl Default for Turbulence {
 }
 
 impl NodeTrait for Turbulence {
+    impl_node_as_filter!();
+
     #[inline]
     fn set_atts(&self, node: &RsvgNode, pbag: &PropertyBag<'_>) -> NodeResult {
         self.base.set_atts(node, pbag)?;
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 221621ca..3550e5ef 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -8,6 +8,7 @@ use std::fmt;
 use crate::cond::{RequiredExtensions, RequiredFeatures, SystemLanguage};
 use crate::css::CssRules;
 use crate::drawing_ctx::DrawingCtx;
+use crate::filters::Filter;
 use crate::error::*;
 use crate::parsers::Parse;
 use crate::properties::{ComputedValues, SpecifiedValue, SpecifiedValues};
@@ -60,6 +61,10 @@ impl NodeData {
         }
     }
 
+    pub fn get_node_trait(&self) -> &NodeTrait {
+        self.node_impl.as_ref()
+    }
+
     pub fn get_impl<T: NodeTrait>(&self) -> Option<&T> {
         (&self.node_impl).downcast_ref::<T>()
     }
@@ -328,6 +333,11 @@ pub trait NodeTrait: Downcast {
         // by default nodes don't draw themselves
         Ok(())
     }
+
+    /// Returns the Filter trait if this node is a filter primitive
+    fn as_filter(&self) -> Option<&Filter> {
+        None
+    }
 }
 
 impl_downcast!(NodeTrait);
@@ -474,7 +484,7 @@ impl RsvgNode {
                 let cr = dc.get_cairo_context();
                 cr.transform(self.get_transform());
 
-                self.borrow().node_impl.draw(self, cascaded, dc, clipping)
+                self.borrow().get_node_trait().draw(self, cascaded, dc, clipping)
             })
         } else {
             rsvg_log!("(not rendering element {} because it is in error)", self);
@@ -488,7 +498,7 @@ impl RsvgNode {
     }
 
     pub fn get_impl<T: NodeTrait>(&self) -> &T {
-        if let Some(t) = (&self.borrow().node_impl).downcast_ref::<T>() {
+        if let Some(t) = self.borrow().get_impl::<T>() {
             t
         } else {
             panic!("could not downcast");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]