Rust: E0495 Does not mention the conflicting requirements

Created on 14 Nov 2016  路  9Comments  路  Source: rust-lang/rust

E0495 returns "cannot infer an appropriate lifetime for autoref due to conflicting requirements" and suggest a way to fix this "help: consider using an explicit lifetime parameter..." but it does not say what the conflicting requirements are. This means that if the suggested way to fix it does not work, the user is stuck.

A-diagnostics C-enhancement T-compiler

Most helpful comment

I'm currently fighting with this and it's super frustrating because the only way to solve it is trial and error.

For trivial programs this isn't an issue, but when you start having multiple refs it becomes a tangled web that seems like it could very easily solved if rustc would just tell me _what_ exactly is conflicting.

All 9 comments

I'm currently fighting with this and it's super frustrating because the only way to solve it is trial and error.

For trivial programs this isn't an issue, but when you start having multiple refs it becomes a tangled web that seems like it could very easily solved if rustc would just tell me _what_ exactly is conflicting.

I think the old error format also used to say something about the conflicts such as, "Lifetime 'a needs to be valid for the call at x, but is only valid for y" or something that effect.

I would like to add that I have yet to run into a situation in which the "suggested way to fix it" actually can work at all, or even point in the right direction of fixing the issue :/

I encountered this issue just today using latest nightly (via rustup), and as someone relatively new to rust, the most puzzling thing was not knowing why this was a problem:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
   --> src/actions/mod.rs:195:30
    |
195 |         let v: Vec<&str> = s.trim()
    |                              ^^^^
    |
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Self, <Self>::Err>
   --> src/actions/mod.rs:193:5
    |
193 |     fn from_str(s: &str) -> Result<Self, Self::Err> {
    |     ^

What was also strange about it was that it only appeared after what initially seemed like unrelated changes. I have a suspicion it's because I started inserting some slices of that string into a BTreeMap as keys.

After applying the suggested change, it proceeded to fail for a different reason, but suggested the same change, even though that change has clearly already been applied:

error[E0308]: method not compatible with trait
   --> src/actions/mod.rs:193:5
    |
193 |     fn from_str(s: &'a str) -> Result<Self, Self::Err> {
    |     ^ lifetime mismatch
    |
    = note: expected type `fn(&str) -> std::result::Result<actions::Action<'a>, actions::ActionError<'_>>`
    = note:    found type `fn(&'a str) -> std::result::Result<actions::Action<'a>, actions::ActionError<'_>>`
    = note: the anonymous lifetime #1 defined on unknown free region bounded by scope CodeExtent(687/CallSiteScope { fn_id: NodeId(436), body_id: NodeId(1197) })...
    = note: ...does not necessarily outlive the lifetime 'a as defined on unknown free region bounded by scope CodeExtent(687/CallSiteScope { fn_id: NodeId(436), body_id: NodeId(1197) })
help: consider using an explicit lifetime parameter as shown: fn from_str(s: &'a str) -> Result<Self, <Self>::Err>
   --> src/actions/mod.rs:193:5
    |
193 |     fn from_str(s: &'a str) -> Result<Self, Self::Err> {
    |     ^

error: aborting due to previous error

It would be helpful if it could tell me what the conflicting requirements are, and furthermore, check to see if I've already applied a suggested change before suggesting it again.

Updated: As I suspected, what rust was really trying to tell me is that the function that I later called that splits up the string passed into from_str() was attempting to insert string slices from that string into a BTreeMap, which won't work because the slices aren't guaranteed to live beyond the call to from_str. After reworking the helper function that from_str was calling to use a BTreeMap

I recently ran into this diagnostic and just wanted to add another example to the mix. I could've sworn this particular diagnostic used to be more helpful, but lately I haven't been getting any suggestions at all from E0495, just the initial error text itself.

I'll walk you through a change I was trying to make to my 2D renderer, megumin

Given an enum like so in src/render.rs:

pub enum RenderJob {
    ... other renderer primitives ...
    DrawMany(usize, Vec<Rect>),
}

Along with an example usage in src/entities/map.rs like this:

   pub fn draw(&self, jobs: &mut Vec<RenderJob>) {
        // just imagine we clear self.starfield & fill it with rects to be drawn
        jobs.push(RenderJob::DrawMany(self.tx_star_fg, self.starfield.clone()));
    }

This clone is causing an allocation every frame, so in RenderJob::DrawMany I wanted to see if I could pass the list of Rect's by reference instead. So I tried to adapt the enum to take a slice like so:

pub enum RenderJob<'queue> {
    ... other renderer primitives ...
    DrawMany(usize, &'queue [Rect]),
}

... and we might want to use that like this:

   pub fn draw(&self, jobs: &mut Vec<RenderJob>) {
        // just imagine we clear self.starfield & fill it with rects to be drawn
        jobs.push(RenderJob::DrawMany(self.tx_star_fg, &self.starfield[..]));
    }

_(NOTE: I'm aware this particular approach is indeed flawed. I'm just a tad bummed that the diagnostics weren't more helpful in guiding me to that conclusion.)_

This change emits the following error

rustc 1.16.0-nightly (5d994d8b7 2017-01-05)

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/entities/map.rs:84:61
   |
84 |             jobs.push(RenderJob::DrawMany(self.tx_star_fg, &self.starfield[..]));
   |                                                             ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: Could not compile `megumin`.

To learn more, run the command again with --verbose.

There's a few things that stand out to me about this diagnostic:

  • It mentions "conflicting requirements" but does not seem to point out what they are.
  • Furthermore it mentions conflicting requirements but there's only one span. -- Given the phrasing I would intuitively expect at least two spans illustrating the conflict.
  • From the error alone one can see it attempted to infer lifetimes, but it doesn't show you what lifetime(s) it attempted.
  • There is no --explain flag suggested.
  • There are no note: or help: lines, only the error itself
  • There is no suggestion to even add lifetime annotations. As an experienced user this isn't a big deal, but if I were a novice I'm not sure it's clear from this error how to move forward.

For completeness sake here is a signature I attempted which, in my opinion, finally got rustc to reveal the true nature of my mistake:

pub fn draw<'world, 'call>(&'world self, jobs: &'call mut Vec<RenderJob<'world>>) { ... }

(The way I mentally parse the above signature is: "I'm submitting a render job which must live as long as my interior (the life of worldmap) into a render queue which lives as long as this iteration of the game loop.")

This yields the following error:

rustc 1.16.0-nightly (5d994d8b7 2017-01-05)

error: `world` does not live long enough
   --> src/main.rs:148:1
    |
133 |         world.draw(&mut render_jobs);
    |         ----- borrow occurs here
...
148 | }
    | ^ `world` dropped here while still borrowed
    |
    = note: values in a scope are dropped in the opposite order they are created

error: aborting due to previous error

error: Could not compile `megumin`.

To learn more, run the command again with --verbose.

This error is basically saying that the borrow must live until the end of the game loop, which is in fact correct since the render queue is shared between iterations of that loop. So once I submit a reference to the interior of the worldmap into the render queue I can no longer mutate that world until the render queue is destroyed. (Since rustc can't reason about when that queue might be emptied; it can only reason about when that queue is dropped.)

Since the render queue lives the entire length of the gameloop rustc correctly proves that the world cannot be mutated again until the render queue which held the reference is gone, which sadly won't happen until the end of main. This exposed the true flaw in my approach, but in my experience it was completely non-obvious from diagnostic E0495... it took quite a bit of trial and error to arrive at the function signature which yielded this last error.


I hope my little story provides some insight as to how this diagnostic might be improved. Thanks all!

I've been learning Rust and coming to grips with lifetimes, and this is one of the most vexing error messages. Usually I get past it with judicious trial and error, because I don't understand why it isn't working in the first place (otherwise I would have specified the lifetimes differently) and it doesn't tell me what the conflict is.

Having some additional information here - either some description of what the conflict is, or the valid combination of lifetimes to choose from - would be very helpful.

The current nightly does in fact, in my specific code, report the conflicting requirements. So either this issue can be closed, or conflicting requirements are reported only in some cases.

I should have added a mwe back then :/

Edit: Yes some kind of conflict is mentioned but it's really vague & the type expect/got is irritating.
You can also trigger this with something like this here (also on rust nightly):
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=defafd804076acbee230e337975b4206

You effectively spawn a thread inside an impl, which uses self.

use std::thread;

pub struct A {
    a: String,
    b: i32,
}

impl A {
    pub fn foo(&self) {
        thread::spawn(move || {
            println!("something {}",&self.a);
        });
    }
}

Giving you

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/lib.rs:10:23
   |
10 |           thread::spawn(move || {
   |  _______________________^
11 | |             println!("something {}",&self.a);
12 | |         });
   | |_________^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 9:5...
  --> src/lib.rs:9:5
   |
9  | /     pub fn foo(&self) {
10 | |         thread::spawn(move || {
11 | |             println!("something {}",&self.a);
12 | |         });
13 | |     }
   | |_____^
   = note: ...so that the types are compatible:
           expected &A
              found &A
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/lib.rs:10:23: 12:10 self:&A]` will meet its required lifetime bounds
  --> src/lib.rs:10:9
   |
10 |         thread::spawn(move || {
   |         ^^^^^^^^^^^^^
Was this page helpful?
0 / 5 - 0 ratings