Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusing error msg for lifetime mismatch (possibly a bug in lifetime inference as well) #1523

Closed
daniel-vainsencher opened this issue Mar 2, 2016 · 6 comments

Comments

@daniel-vainsencher
Copy link

The problem is demonstrated by compiling [1]. I can work around the problem by using [2](first half of the diff is relevant to this problem, second part not so much), or by patching ndarrays to give parameters of binary operators distinct lifetime parameters.

A few problems here:

  1. The basic error message is not very clear:
    src/lib.rs:30:28: 30:38 error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements [E0495]
    src/lib.rs:30 let delta = data - &self.mean;
    <arrow pointing at &self.mean>
    Lifetime of what expression cannot be inferred? What are the conflicting requirements? as someone with an only approximate mental model of lifetimes (i.e., a typical rust user) this is not helping me a lot to solve the problem nor to learn about lifetimes.
  2. The compiler suggests something that doesn't work. I don't expect suggestions to always work, but maybe its worth pointing this case out so that the suggestion can be improved or made conditional.
    src/lib.rs:27:5: 38:6 help: consider using an explicit lifetime parameter as shown: fn next_value<'a>(&'a mut self, data: &'a V, weight: f64)
    src/lib.rs:27 pub fn next_value(&mut self, data : &V, weight : f64) {
  3. @bluss suggested that rustc should be able to infer for the self and data borrows the intersection of their lifetimes, hence this should not be happening at all. I have no idea.
  4. The work around in [2] suggested by @bluss leaves me even more confused. I can change the lifetime of data by ... (what is that, actually, reborrowing it?), and then the borrow of self is ok? But if that's a good way to go about things, maybe the compiler should suggest this method sometimes.

Anyway, if any part of the documentation (error: no extended information for [E0495]) can enlighten me, pointers accepted gladly.

[1] daniel-vainsencher/online_weighted_stats@8f9cf03
[2] daniel-vainsencher/online_weighted_stats@0bfc04d

@bluss
Copy link
Member

bluss commented Mar 2, 2016

I think this is a representative minimization. Playground link.

use std::ops::Add;

struct Foo;

impl<'a> Add<&'a Foo> for &'a Foo {
    type Output = ();
    fn add(self, rhs: &'a Foo) {}
}

fn try_to_add(input: &Foo) {
    let local = Foo;
    &*input + &local; // ok
    input + &local; // error: `local` does not live long enough
}

fn main() {
}

@daniel-vainsencher
Copy link
Author

I get completely different error messages at your playground link, btw,
though still somewhat confusing: it is not clear why the block suffix does
not suffice, seems to cover the relevant part of the anonymous lifetime #1.

On Tue, Mar 1, 2016 at 11:34 PM, bluss [email protected] wrote:

I think this is a representative minimization. Playground link.
https://play.rust-lang.org/?gist=59e6b8c113e4e7eda1fe&version=stable

use std::ops::Add;
struct Foo;
impl<'a> Add<&'a Foo> for &'a Foo {
type Output = ();
fn add(self, rhs: &'a Foo) {}
}
fn try_to_add(input: &Foo) {
let local = Foo;
&*input + &local; // ok
input + &local; // error: local does not live long enough
}
fn main() {
}


Reply to this email directly or view it on GitHub
#1523 (comment).

Daniel Vainsencher

@nagisa
Copy link
Member

nagisa commented Mar 2, 2016

Wrong repository?
On Mar 2, 2016 7:28 AM, "Daniel Vainsencher" [email protected]
wrote:

I get completely different error messages at your playground link, btw,
though still somewhat confusing: it is not clear why the block suffix does
not suffice, seems to cover the relevant part of the anonymous lifetime #1.

On Tue, Mar 1, 2016 at 11:34 PM, bluss [email protected] wrote:

I think this is a representative minimization. Playground link.
https://play.rust-lang.org/?gist=59e6b8c113e4e7eda1fe&version=stable

use std::ops::Add;
struct Foo;
impl<'a> Add<&'a Foo> for &'a Foo {
type Output = ();
fn add(self, rhs: &'a Foo) {}
}
fn try_to_add(input: &Foo) {
let local = Foo;
&*input + &local; // ok
input + &local; // error: local does not live long enough
}
fn main() {
}


Reply to this email directly or view it on GitHub
#1523 (comment).

Daniel Vainsencher


Reply to this email directly or view it on GitHub
#1523 (comment).

@bluss
Copy link
Member

bluss commented Mar 2, 2016

Oops, this should be in rust-lang/rust ! I didn't notice the difference. Thanks nagisa.

@ticki
Copy link
Contributor

ticki commented Mar 2, 2016

@daniel-vainsencher, could you open a issue in rust-lang/rust?

@daniel-vainsencher
Copy link
Author

Opened in the right repo, copied over relevant information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants