title: How to construct a dynamically-dimensioned type based on of nalgebra::OPoint and simultaneously implement its constant-dimensioned functions?
body: <h1>Background</h1>
  <p>For a geometry library in Rust we need bounding boxes. As we need bounding boxes in several dimensions (mostly 2 and 3), we need implementations in every required dimension. To reduce the programming and maintenance overhead, we implemented a dynamic version of the bounding box on top of the Rust crate <code>nalgebra</code>. Until the release version <code>0.25</code> of nalgebra, our implementation against <code>nalgebra</code> looked as follows:</p>
  <pre class="lang-rust prettyprint-override"><code>#[derive(Debug, Clone)]
  pub struct AABB&lt;N: Scalar, D: DimName&gt;
  where
      DefaultAllocator: Allocator&lt;N, D&gt;,
  {
      pub min: Point&lt;N, D&gt;,
      pub max: Point&lt;N, D&gt;,
  }
  
  impl&lt;N: Scalar + RealField, D: DimName&gt; AABB&lt;N, D&gt;
  where
      DefaultAllocator: Allocator&lt;N, D&gt;,
  {
      /// Constructor to create a new instance of `AABB&lt;N, D&gt;`
      pub fn new(min: Point&lt;N, D&gt;, max: Point&lt;N, D&gt;) -&gt; Self {
          Self { min, max }
      }
  
      /// Returns the n-dimensional center as `Point&lt;N, D&gt;`
      pub fn get_center(&amp;self) -&gt; Point&lt;N, D&gt; {
          center(&amp;self.min, &amp;self.max)
      }
      ...
  }
  </code></pre>
  <p>With release versions <code>0.26+</code> the crate changed its <a href="https://docs.rs/nalgebra/0.25.1/nalgebra/geometry/struct.Point.html" rel="nofollow noreferrer">point type version 0.25.1</a>
  from</p>
  <pre class="lang-rust prettyprint-override"><code>#[repr(C)]
  #[derive(Debug, Clone)]
  pub struct Point&lt;N: Scalar, D: DimName&gt;
  where
      DefaultAllocator: Allocator&lt;N, D&gt;,
  {
      /// The coordinates of this point, i.e., the shift from the origin.
      pub coords: VectorN&lt;N, D&gt;,
  }
  </code></pre>
  <p>to <a href="https://docs.rs/nalgebra/0.30.1/src/nalgebra/lib.rs.html#390-395" rel="nofollow noreferrer">this point-type version 0.30.1</a></p>
  <pre class="lang-rust prettyprint-override"><code>pub struct OPoint&lt;T: Scalar, D: DimName&gt;
  where
      DefaultAllocator: Allocator&lt;T, D&gt;,
  {
      /// The coordinates of this point, i.e., the shift from the origin.
      pub coords: OVector&lt;T, D&gt;,
  }
  </code></pre>
  <p>with struct <code>OPoint</code> replacing struct <code>Point</code> and <code>Point</code> being used as a <a href="https://docs.rs/nalgebra/0.30.1/src/nalgebra/geometry/point_alias.rs.html" rel="nofollow noreferrer">type alias</a> for points with dimensions known at compile-time.</p>
  <p>The function signature for functions on points subsequently change from <a href="https://docs.rs/nalgebra/0.25.1/src/nalgebra/lib.rs.html#390-395" rel="nofollow noreferrer">link</a></p>
  <pre class="lang-rust prettyprint-override"><code>#[inline]
  pub fn distance&lt;N: SimdComplexField, D: DimName&gt;(
      p1: &amp;Point&lt;N, D&gt;,
      p2: &amp;Point&lt;N, D&gt;,
  ) -&gt; N::SimdRealField
  where
      DefaultAllocator: Allocator&lt;N, D&gt;,
  {
      (&amp;p2.coords - &amp;p1.coords).norm()
  }
  </code></pre>
  <p>to <a href="https://docs.rs/nalgebra/0.30.1/src/nalgebra/lib.rs.html#390-395" rel="nofollow noreferrer">link</a></p>
  <pre class="lang-rust prettyprint-override"><code>#[inline]
  pub fn distance&lt;T: SimdComplexField, const D: usize&gt;(
      p1: &amp;Point&lt;T, D&gt;,
      p2: &amp;Point&lt;T, D&gt;,
  ) -&gt; T::SimdRealField {
      (&amp;p2.coords - &amp;p1.coords).norm()
  }
  </code></pre>
  <p>with function signatures from dynamic types to constant types.</p>
  <h1>Problem</h1>
  <p>I cannot really figure out, how to adjust my bounding box structure <code>AABB</code> to accomodate for the changes made to the dependency <code>nalgebra</code>. I started by replacing the <code>Point</code> type that I use for the new <code>OPoint</code> type. This seemed like a good idea, as the <code>OPoint</code> type replaces the <code>Point</code> type using the exact same type signature. But as I am using functions of <code>Point</code> for which the function signatures changed to constant types, I am getting lots of errors, that I don't know how to fix.</p>
  <p>E.g. this one:</p>
  <pre class="lang-rust prettyprint-override"><code>impl&lt;N: Scalar + RealField, D: DimName&gt; AABB&lt;N, D&gt;
  where
      DefaultAllocator: Allocator&lt;N, D&gt;,
  { 
      /// Returns the n-dimensional center as `OPoint&lt;N, D&gt;`
      pub fn get_center(&amp;self) -&gt; OPoint&lt;N, D&gt; {
          center(&amp;self.min, &amp;self.max)
      }
  }
  </code></pre>
  <p>with error</p>
  <pre><code>error[E0308]: mismatched types
     --&gt; ghost\src\primitives\aabb\aabbn.rs:195:20
      |
  178 | impl&lt;N: Scalar + RealField, D: DimName&gt; AABB&lt;N, D&gt; 
      |                             - this type parameter  
  ...
  195 |             center(&amp;self.min, &amp;self.max)[i]        
      |                    ^^^^^^^^^ expected struct `Const`, found type parameter `D`
      |
      = note: expected reference `&amp;OPoint&lt;_, Const&lt;{_: usize}&gt;&gt;`
                 found reference `&amp;OPoint&lt;N, D&gt;`
  </code></pre>