Reputation: 11
pub struct SumAggregator<'ctx> {
input: i32,
state: Cell<Option<IntValue<'ctx>>>,
}
impl<'ctx> SumAggregator<'ctx> {
pub fn new() -> SumAggregator<'ctx> {
SumAggregator {
input: 0,
state: Cell::new(None),
}
}
}
impl<'ctx> Aggregator for SumAggregator<'ctx> {
fn init(&self, generator: &Generator, layout: &mut Layout, idx: i32) {
let col_type = generator.context.i32_type();
self.state.set(Some(col_type.const_int(0, true)));
generator.build_debug("initialized state value:", self.state.get().unwrap().as_basic_value_enum());
}
fn process(&self, val: IntValue) {
unimplemented!()
}
}
Above is the core code which throws this error. col_type.const_int(0, true)
can return a IntValue
with a 'ctx lifetime. When I tried to set this value to my struct, this error occured. I am new to Rust. As far as I know, only references could cause lifetime problem. However, in my use case, I just want to put a value not a reference to a struct(even though this value has a lifetime).
Here is the error stack:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/operator/groupby/mod.rs:40:42
|
40 | let col_type = generator.context.i32_type();
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the method body at 37:5...
--> src/operator/groupby/mod.rs:37:5
|
37 | fn init(&self, generator: &Generator, layout: &mut Layout, idx: i32) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/operator/groupby/mod.rs:40:24
|
40 | let col_type = generator.context.i32_type();
| ^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'ctx` as defined on the impl at 36:6...
--> src/operator/groupby/mod.rs:36:6
|
36 | impl<'ctx> Aggregator for SumAggregator<'ctx> {
| ^^^^
note: ...so that the expression is assignable
--> src/operator/groupby/mod.rs:41:24
|
41 | self.state.set(Some(col_type.const_int(0, true)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `Option<inkwell::values::IntValue<'ctx>>`
found `Option<inkwell::values::IntValue<'_>>`
Upvotes: 1
Views: 107
Reputation: 53
You need to specific all of lets for example:
let int_value:IntValue<'ctx> = col_type.const_int(0, true)
And repeat it for Option and cell left-s.
Consider to a,b,ctx they need more management and if it is possible try it once:
impl<'a,'b,'ctx>
Upvotes: 0
Reputation: 1664
The problem is that SumAggregator
wants to have an IntValue
that lives at least as long as itself. But in the init
function you are trying to give it an IntValue
that lives only until the end of the init
function.
You can make sure that the IntValue
lives long enough by specifying the Generator
's reference's lifetime:
impl<'ctx> Aggregator for SumAggregator<'ctx> {
fn init(&self, generator: &'ctx Generator, layout: &mut Layout, idx: i32) {
// col_type is &'ctx IntType
let col_type = generator.context.i32_type();
// int_value is &'ctx IntValue
let int_value = col_type.const_int(0, true)
// putting &'ctx IntValue into &'ctx IntValue
self.state.set(Some(int_value));
generator.build_debug("initialized state value:", self.state.get().unwrap().as_basic_value_enum());
}
...
}
Without doing that it is the same as:
impl<'ctx> Aggregator for SumAggregator<'ctx> {
fn init<'a, 'b>(&self, generator: &'a Generator, layout: &'b mut Layout, idx: i32) {
// col_type is &'a IntType
let col_type = generator.context.i32_type();
// int_value is &'a IntValue
let int_value = col_type.const_int(0, true)
// trying to put &'a IntValue into &'ctx IntValue
self.state.set(Some(int_value));
generator.build_debug("initialized state value:", self.state.get().unwrap().as_basic_value_enum());
}
...
}
Upvotes: 0