# This parameter and the return type are declared with different lifetimes

Hello everybody, rust beginners here. I am writing a method for a class Ray called `intersect`, that given the starting point and ending point of a segment on a 2D plane, finds if there is an intersection or not.
The method `intersect` works like this:

``````    let start_line = vec2(300.0, 100.0);
let end_line = vec2(300.0, -300.0);
let mut r = Ray2D::new();
// ...
if let Some(collision) = r.intersect(start_line.x, start_line.y, end_line.x, end_line.y) {
draw.ellipse().color(GREEN).x_y(collision.x, collision.y);
};
``````

This is my Ray2D code:

``````#[allow(dead_code)]
use nannou::prelude::*;

pub struct Ray2D {
orig: Vector2,
dir: Vector2,
}

impl Ray2D {
pub fn new() -> Self {
Ray2D {
orig: vec2(0.0, 0.0),
dir: vec2(1.0, 0.0),
}
}

// ....

pub fn intersect(&self, x1: f32, y1: f32, x2: f32, y2: f32) -> Option<Vector2> {
let x3 = self.orig.x;
let y3 = self.orig.y;
let x4 = self.orig.x + self.dir.x;
let y4 = self.orig.y + self.dir.y;
let den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

let tri = (
den,
((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den,
-((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den,
);

match tri {
(d, t, u) if d != 0.0 && t > 0.0 && t < 1.0 && u > 0.0 => {
Some(vec2(x1 + t * (x2 - x1), y1 + t * (y2 - y1)))
}
_ => None,
}
}

pub fn intersect_reuse(
&self,
x1: f32,
y1: f32,
x2: f32,
y2: f32,
collision: &mut Vector2,
) -> Option<&mut Vector2> {
let x3 = self.orig.x;
let y3 = self.orig.y;
let x4 = self.orig.x + self.dir.x;
let y4 = self.orig.y + self.dir.y;
let den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

let tri = (
den,
((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den,
-((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den,
);

match tri {
(d, t, u) if d != 0.0 && t > 0.0 && t < 1.0 && u > 0.0 => {
collision.x = x1 + t * (x2 - x1);
collision.y = y1 + t * (y2 - y1);
Some(collision)
}
_ => None,
}
}
}
``````

What at the moment I am not able to di, is to pass as mutable reference a 2dVector to the `intersect_reuse` method and to have its `x` and` y` component updated if there is an intersection. I have tried an implementation in the `intersect_result` method but I get this error message:

``````error[E0623]: lifetime mismatch
--> ray2d/src/lib.rs:75:17
|
57 |         collision: &mut Vector2,
|                    ------------ this parameter and the return type are declared with different lifetimes...
58 |     ) -> Option<&mut Vector2> {
|          --------------------
...
75 |                 Some(collision)
|                 ^^^^^^^^^^^^^^^ ...but data from `collision` is returned here

error: aborting due to previous error
``````

I have read the chapter of the book regarding lifetime, https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html, but I do not know how to solve this.

Maybe someone has a suggestion?

``````    pub fn intersect_reuse<'a>(
&self,
x1: f32,
y1: f32,
x2: f32,
y2: f32,
collision: &'a mut Vector2,
) -> Option<&'a mut Vector2> { ... }
``````

This says that the vector you're returning has the same lifetime as the vector you're receiving.

Note however that returning a reference to the vector that you took as an argument is usually pointless, though I guess it depends on how you're calling the function.

Thanks Andrew, it is working. I am passing a reference because I have ~1000 rays and I want to draw the intersection with a group of ~ 60 segments. I am reusing the vector passed as argument in order to avoid to put a new vector on the stack for each collision. Does it make sense?

If, when trying to parallelize ray casting, I will hit some problems, like the reference that can not be share, I will simply use the `intersect` method.

Does it make sense?

Sure. If you want to reuse the same memory though you can just update `collision` and return a `bool`. That's not necessarily any better, I'm just pointing out that it will work.

@edapx, would a suggestion like the one for functions have been enough to help you here?

Honestly, I do not enough enough experience to give you a valuable feedback regarding that issue.

If you had seen something like

``````help: consider introducing a named lifetime parameter
|
1 | fn foo<'a>(x: &'a i32, y: &'a i32) -> Option<&'a i32> {
|       ^^^^    ^^^^^^^     ^^^^^^^            ^^^
``````

Would that have unblocked you?

It would have helped me, yes. But I think that also the sentence `this parameter and the return type are declared with different lifetimes...` is necessary to introduce the problem to a novice.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.