Reputation: 40319
I am getting this error - "cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements". However, I've tried to enforce start_duty
requirements explicitly.
error.rs:45:1: 55:2 note: consider using an explicit lifetime parameter as shown: fn start_duty<'dutylife>(duty: &'dutylife Duty) -> &'dutylife Job<'dutylife>
error.rs:45 fn start_duty<'dutylife> (duty: &'dutylife Duty) -> &'dutylife Job {
error.rs:46
error.rs:47 let j : Job = Job {
error.rs:48 duty: duty,
error.rs:49 output: "".to_string(),
error.rs:50 success: JobNotDone
...
error.rs:48:15: 48:19 error: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements
error.rs:48 duty: duty,
^~~~
error: aborting due to previous error
A somewhat expurgated version of my code inducing the error. Conceptually, what I am trying to do is generate a new Job referencing a Duty. Jobs can only exist for the lifetime of the Duty; when the Duty goes away, the Job should as well.
enum Source {
Nothing, // Nothing
Git(String, String), // reponame, refname
Hg(String, String), // reponame, csid
Url(String) // curl down what's here
}
enum JobResult {
JobNotDone,
JobSuccess,
JobFailure,
JobError
}
/*
Jobs
Jobs are always attached to the Duty that spawned them; there can be
no Job without the duty. So we take a lifetime param of the duty reference
*/
struct Job<'r> {
duty: &'r Duty, // pointer back to
output: String, // no output = ""
success: JobResult
}
enum Action {
BashScript(String)
}
struct Duty {
name: String,
source: Source,
action: Action,
comment: Option<String>
}
struct Agent<'r> {
hostname : String,
uid : u64,
job : Option<Job<'r>>, // mutable, agents
}
// returns new Job, but with duty referenced.
fn start_duty<'dutylife> (duty: &'dutylife Duty) -> &'dutylife Job {
let j : Job = Job {
duty: duty,
output: "".to_string(),
success: JobNotDone
};
return &j;
}
fn main () {
}
Upvotes: 0
Views: 1577
Reputation: 16640
This function signature promises to return a reference to a Job.
fn start_duty<'dutylife> (duty: &'dutylife Duty) -> &'dutylife Job
What you probably wanted to do was returning a Job
that contains a reference to a Duty
:
fn start_duty<'dutylife> (duty: &'dutylife Duty) -> Job<'dutylife> {
Job {
duty: duty,
output: "".to_string(),
success: JobNotDone
}
}
There was also another error, the code was trying to return a reference to the Job created in this function. I fixed that as well and the code now compiles. Let me know if this was what you were trying to do.
Edit: to respond to the "Jobs can only exist for the lifetime of the Duty; when the Duty goes away, the Job should as well." part.
This cannot be done in the way you've tried because the Job object will cease to exist when the function ends, and any references to it would become invalid.
The simplest way would be to let a Duty
own the Job
(s) working on it (by giving it a Option<Job>
or Option<Vec<Job>>
field). This is a single owner approach. Multiple owners are significantly more complex and would involve reference counted pointers, or raw pointers.
Upvotes: 2