I'm working on a json schema crate and part of the functionality being built is auto-resolution of referenced schemas. In order to facilitate this, my compile flow needs to be async
. However, I'm running into the lifetime error below and I do not know how to solve it and need some help, please.
The error points to Unexpected higher-ranked lifetime error in GAT usage · Issue #100013 · rust-lang/rust · GitHub but I don't see a simple workaround, or at least one I recognize.
I apologize about the amount of code below. I was unable to create a repro that was relevant to my case and also not unwieldy. I've omitted as much code as I thought possible but all of source is currently available at GitHub - chanced/grill.
// https://github.com/chanced/grill/blob/b9dbcb7185c5f5a5f37c03f9eba22e7338891d2b/grill-core/src/resolve.rs#L22-L32
pub trait Resolve {}
// https://github.com/chanced/grill/blob/b9dbcb7185c5f5a5f37c03f9eba22e7338891d2b/grill-core/src/lang.rs#L105-L122
pub struct Compile<'int, 'txn, 'res, L, R, K>
where
L: Language<K>,
K: 'static + Key + Send + Sync,
{
pub uris: Vec<AbsoluteUri>,
pub txn: Transaction<'int, 'txn, L, K>,
pub resolve: &'res R,
pub validate: bool,
}
// https://github.com/chanced/grill/blob/b9dbcb7185c5f5a5f37c03f9eba22e7338891d2b/grill-core/src/state.rs#L54-L72
pub struct Transaction<'int, 'txn, L: Language<K>, K: 'static + Key + Send + Sync> {
pub schemas: &'txn mut Schemas<L::CompiledSchema, K>,
pub sources: &'txn mut Sources,
pub cache: &'int mut Cache,
}
// https://github.com/chanced/grill/blob/b9dbcb7185c5f5a5f37c03f9eba22e7338891d2b/grill-core/src/lang.rs#L41-L82
#[trait_variant::make(Send)]
pub trait Language<K>: Sized + Clone + fmt::Debug
where
K: 'static + Key + Send + Sync,
{
type CompiledSchema: schema::CompiledSchema<K>;
type CompileError<R>: 'static + Send + std::error::Error
where
R: 'static + Resolve;
type EvaluateResult<'val>
where
Self: 'val;
async fn compile<'int, 'txn, 'res, R>(
&'int mut self,
compile: Compile<'int, 'txn, 'res, Self, R, K>,
) -> Result<Vec<K>, Self::CompileError<R>>
where
R: 'static + Resolve + Send + Sync;
}
// https://github.com/chanced/grill/blob/main/grill-json-schema/src/lib.rs#L53C3-L144
pub struct JsonSchema<K, S>
where
K: 'static + Key + Send + Sync,
S: Specification<K>,
{
spec: S,
_marker: PhantomData<K>,
}
impl<K, S> Language<K> for JsonSchema<K, S>
where
K: 'static + Key + Send + Sync,
S: Specification<K> + Send + 'static,
{
type CompiledSchema = CompiledSchema<S, K>;
type CompileError<R> = S::CompileError<R>
where
R: 'static + Resolve;
type EvaluateResult<'val> =
Result<Report<S::Annotation<'val>, S::Error<'val>>, S::EvaluateError>;
async fn compile<'int, 'txn, 'res, R>(
&'int mut self,
ctx: lang::Compile<'int, 'txn, 'res, Self, R, K>,
) -> Result<Vec<K>, Self::CompileError<R>>
where
R: 'static + Resolve + Send + Sync,
{
compile::compile::<R, S, K>(self.spec.init_compile(ctx).await?).await
}
}
error: lifetime bound not satisfied
--> grill-json-schema/src/lib.rs:126:5
|
126 | / async fn compile<'int, 'txn, 'res, R>(
127 | | &'int mut self,
128 | | ctx: lang::Compile<'int, 'txn, 'res, Self, R, K>,
129 | | ) -> Result<Vec<K>, Self::CompileError<R>>
130 | | where
131 | | Self: 'int + 'txn + 'res,
132 | | R: 'static + Resolve + Send + Sync,
| |___________________________________________^
|
= note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
Is there anyway to work around this? I'm sorry that this is such a big ask. I don't know how to fix it and don't know where to even start on getting a solution in the works.
I appreciate you taking the time to even read this. Thank you.