1

I have defined two structs and a function in my Rust program, in which I am implementing my own linear algebra. While doing so I stumbled onto a gap in my knowledge of lifetimes in Rust. To my understanding, a lifetime annotation simply tells the compiler that one input variable must live at least as long as output variable.

But now I am actually trying to tell the compiler that my output is NOT related to the input. Sure, I take in references, but the new struct is constructed by creating new slices, and filling these with new values (f64).

So, my idea was that I have two inputs, whose lifetimes can be unrelated when the function is called, and a third one, saying it is unrelated to the inputs, because a new struct with no references to the old one is created. (See code below).

Sadly, this returns an error, and to be perfectly honest, I have no idea what it really means. I mean, I can read the words and know these words, but it doesn't really fit in the idea of lifetimes I have in my head. I need a fresh new look on lifetimes, or someone to point out to me what I understood wrong.

What I get from this is that it complains that my output is not related/constrained to the inputs, which is precisely what I want!

error[E0207]: the lifetime parameter `'c` is not constrained by the impl      trait, self type, or predicates
--> src/mat.rs:199:14
|
199 | impl<'a, 'b, 'c
|                  ^^ unconstrained lifetime parameter
error[E0207]: the lifetime parameter `'c` is not constrained by the impl trait, self type, or predicates

I do not require any information on how to properly implement a matrix multiplication, or matrices, because I am toying around to learn Rust. I need an answer that shows me what I misunderstood about Rust.

The two structs:

pub struct ColVector<'a> {
    values: &'a [f64],
}

pub struct Matrix<'a> {
    values: &'a [&'a [f64]], 
    shape: (usize, usize) // Tuple containing size. First value is rows, second is columns
}

The implementation over-ride of the *-operator (I have 3 other ones, all giving the same error)

impl<'a, 'b, 'c> Mul<&'a ColVector<'a>> for &'b Matrix<'b> {
    type Output = ColVector<'c>;

    fn mul(self, v: &'a ColVector) -> ColVector<'c> {
        self.mat_mult(v)
    }
}

EDIT: I fail to see how this is a duplicate of the question Return local String as a slice (&str) . That question is about someone trying to return a reference to a variable local to the function, which is not what I am trying to do. My function does not return a reference, but a struct containing a reference to a newly created slice.

spyduck
  • 11
  • 3
  • Think about who owns the values that ColVector referes to. Yes you return a Struct with a reference, but a reference to where? It is not shown in the question but most likely the reference is to a local variable inside mat_mult. – raggy Feb 09 '18 at 12:46
  • Ah, yes, that is pretty much what happens. I chose a slice in the struct, because I do not know the size of the array at compile-time, and I do not yet understand how to solve this without slices or just making a lot of structs with different sizes. So, you're saying I am trying to do something impossible, I guess, and my question makes no sense. EDIT: can I accept a comment as an answer? – spyduck Feb 09 '18 at 12:57
  • @spyduck an "array" with a runtime-size is a `Vec` in Rust. So you definitely can do it, just like the duplicate uses `String` over `&str`, you can use `Vec` over `&[f64]` – oli_obk Feb 09 '18 at 13:05
  • Yeah, but vectors always get assigned on the heap, right? Since I expect to do a lot of numerical integration that doesn't seem very favorable. – spyduck Feb 09 '18 at 13:31
  • *My function does not return a reference, but a struct containing a reference to a newly created slice.* — Why do you believe that returning a reference wrapped in a struct is different than returning a reference directly? – Shepmaster Feb 09 '18 at 19:53

0 Answers0