From b58ba10f9b4e3c145c34b9740c49bc3c13856ca5 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Mon, 21 Mar 2016 01:08:19 -0700 Subject: [PATCH] So the mutable aliasing in Tracer properly. Apparently this is what UnsafeCell is for, and the code I wrote before wasn't technically correct, even thought it worked in practice. Hooray for doing things properly! --- src/tracer.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tracer.rs b/src/tracer.rs index 956b5fd..7532a55 100644 --- a/src/tracer.rs +++ b/src/tracer.rs @@ -1,5 +1,6 @@ use std::iter; use std::slice; +use std::cell::UnsafeCell; use math::Matrix4x4; use assembly::{Assembly, Object}; @@ -8,7 +9,7 @@ use surface::SurfaceIntersection; pub struct Tracer<'a> { root: &'a Assembly, - rays: Vec, // Should only be used from trace(), not any other methods + rays: UnsafeCell>, // Should only be used from trace(), not any other methods xform_stack: Vec, isects: Vec, } @@ -18,16 +19,19 @@ impl<'a> Tracer<'a> { Tracer { root: assembly, xform_stack: Vec::new(), - rays: Vec::new(), + rays: UnsafeCell::new(Vec::new()), isects: Vec::new(), } } pub fn trace<'b>(&'b mut self, wrays: &[Ray]) -> &'b [SurfaceIntersection] { // Ready the rays - self.rays.clear(); - self.rays.reserve(wrays.len()); - self.rays.extend(wrays.iter()); + let rays_ptr = self.rays.get(); + unsafe { + (*rays_ptr).clear(); + (*rays_ptr).reserve(wrays.len()); + (*rays_ptr).extend(wrays.iter()); + } // Ready the isects self.isects.clear(); @@ -44,7 +48,7 @@ impl<'a> Tracer<'a> { // NOT be used in any other methods. The rays should only be // accessed in other methods via the mutable slice passed directly // to them in their function parameters. - slice::from_raw_parts_mut(self.rays.as_mut_ptr(), self.rays.len()) + &mut (*rays_ptr)[..] }; self.trace_assembly(self.root, wrays, ray_refs);