fix trait-solver issue requiring recursion_limit increase
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
2d049dacc3
commit
bd9a9cc5f8
6 changed files with 37 additions and 17 deletions
|
@ -1,5 +1,3 @@
|
||||||
#![recursion_limit = "192"]
|
|
||||||
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod router;
|
pub mod router;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![recursion_limit = "192"]
|
|
||||||
|
|
||||||
pub(crate) mod clap;
|
pub(crate) mod clap;
|
||||||
mod mods;
|
mod mods;
|
||||||
mod restart;
|
mod restart;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![recursion_limit = "160"]
|
|
||||||
|
|
||||||
mod layers;
|
mod layers;
|
||||||
mod request;
|
mod request;
|
||||||
mod router;
|
mod router;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![recursion_limit = "192"]
|
|
||||||
#![allow(refining_impl_trait)]
|
#![allow(refining_impl_trait)]
|
||||||
|
|
||||||
mod manager;
|
mod manager;
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub(crate) struct Args<'a> {
|
||||||
|
|
||||||
/// Dep is a reference to a service used within another service.
|
/// Dep is a reference to a service used within another service.
|
||||||
/// Circular-dependencies between services require this indirection.
|
/// Circular-dependencies between services require this indirection.
|
||||||
pub(crate) struct Dep<T: Service> {
|
pub(crate) struct Dep<T: Service + Send + Sync> {
|
||||||
dep: OnceLock<Arc<T>>,
|
dep: OnceLock<Arc<T>>,
|
||||||
service: Weak<Map>,
|
service: Weak<Map>,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
|
@ -62,24 +62,47 @@ pub(crate) type MapType = BTreeMap<MapKey, MapVal>;
|
||||||
pub(crate) type MapVal = (Weak<dyn Service>, Weak<dyn Any + Send + Sync>);
|
pub(crate) type MapVal = (Weak<dyn Service>, Weak<dyn Any + Send + Sync>);
|
||||||
pub(crate) type MapKey = String;
|
pub(crate) type MapKey = String;
|
||||||
|
|
||||||
impl<T: Service> Deref for Dep<T> {
|
/// SAFETY: Workaround for a compiler limitation (or bug) where it is Hard to
|
||||||
|
/// prove the Sync'ness of Dep because services contain circular references
|
||||||
|
/// to other services through Dep's. The Sync'ness of Dep can still be
|
||||||
|
/// proved without unsafety by declaring the crate-attribute #![recursion_limit
|
||||||
|
/// = "192"] but this may take a while. Re-evaluate this when a new trait-solver
|
||||||
|
/// (such as Chalk) becomes available.
|
||||||
|
unsafe impl<T: Service> Sync for Dep<T> {}
|
||||||
|
|
||||||
|
/// SAFETY: Ancillary to unsafe impl Sync; while this is not needed to prevent
|
||||||
|
/// violating the recursion_limit, the trait-solver still spends an inordinate
|
||||||
|
/// amount of time to prove this.
|
||||||
|
unsafe impl<T: Service> Send for Dep<T> {}
|
||||||
|
|
||||||
|
impl<T: Service + Send + Sync> Deref for Dep<T> {
|
||||||
type Target = Arc<T>;
|
type Target = Arc<T>;
|
||||||
|
|
||||||
/// Dereference a dependency. The dependency must be ready or panics.
|
/// Dereference a dependency. The dependency must be ready or panics.
|
||||||
|
#[inline]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
self.dep.get_or_init(|| {
|
self.dep.get_or_init(
|
||||||
|
#[inline(never)]
|
||||||
|
|| self.init(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Service + Send + Sync> Dep<T> {
|
||||||
|
#[inline]
|
||||||
|
fn init(&self) -> Arc<T> {
|
||||||
let service = self
|
let service = self
|
||||||
.service
|
.service
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.expect("services map exists for dependency initialization.");
|
.expect("services map exists for dependency initialization.");
|
||||||
|
|
||||||
require::<T>(&service, self.name)
|
require::<T>(&service, self.name)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Args<'a> {
|
impl<'a> Args<'a> {
|
||||||
/// Create a lazy-reference to a service when constructing another Service.
|
/// Create a lazy-reference to a service when constructing another Service.
|
||||||
|
#[inline]
|
||||||
pub(crate) fn depend<T: Service>(&'a self, name: &'static str) -> Dep<T> {
|
pub(crate) fn depend<T: Service>(&'a self, name: &'static str) -> Dep<T> {
|
||||||
Dep::<T> {
|
Dep::<T> {
|
||||||
dep: OnceLock::new(),
|
dep: OnceLock::new(),
|
||||||
|
@ -90,12 +113,14 @@ impl<'a> Args<'a> {
|
||||||
|
|
||||||
/// Create a reference immediately to a service when constructing another
|
/// Create a reference immediately to a service when constructing another
|
||||||
/// Service. The other service must be constructed.
|
/// Service. The other service must be constructed.
|
||||||
|
#[inline]
|
||||||
pub(crate) fn require<T: Service>(&'a self, name: &str) -> Arc<T> { require::<T>(self.service, name) }
|
pub(crate) fn require<T: Service>(&'a self, name: &str) -> Arc<T> { require::<T>(self.service, name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reference a Service by name. Panics if the Service does not exist or was
|
/// Reference a Service by name. Panics if the Service does not exist or was
|
||||||
/// incorrectly cast.
|
/// incorrectly cast.
|
||||||
pub(crate) fn require<T: Service>(map: &Map, name: &str) -> Arc<T> {
|
#[inline]
|
||||||
|
fn require<T: Service>(map: &Map, name: &str) -> Arc<T> {
|
||||||
try_get::<T>(map, name)
|
try_get::<T>(map, name)
|
||||||
.inspect_err(inspect_log)
|
.inspect_err(inspect_log)
|
||||||
.expect("Failure to reference service required by another service.")
|
.expect("Failure to reference service required by another service.")
|
||||||
|
|
|
@ -195,6 +195,7 @@ impl Services {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn try_get<T>(&self, name: &str) -> Result<Arc<T>>
|
pub fn try_get<T>(&self, name: &str) -> Result<Arc<T>>
|
||||||
where
|
where
|
||||||
T: Any + Send + Sync + Sized,
|
T: Any + Send + Sync + Sized,
|
||||||
|
@ -202,6 +203,7 @@ impl Services {
|
||||||
service::try_get::<T>(&self.service, name)
|
service::try_get::<T>(&self.service, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get<T>(&self, name: &str) -> Option<Arc<T>>
|
pub fn get<T>(&self, name: &str) -> Option<Arc<T>>
|
||||||
where
|
where
|
||||||
T: Any + Send + Sync + Sized,
|
T: Any + Send + Sync + Sized,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue