diff --git a/collector/benchmarks/README.md b/collector/benchmarks/README.md index f1c46b1ec..3747dc0b3 100644 --- a/collector/benchmarks/README.md +++ b/collector/benchmarks/README.md @@ -89,6 +89,9 @@ programs. performance](https://github.com/rust-lang/rust/issues/46449) in the past. - **issue-58319**: A small program that caused [poor performance](https://github.com/rust-lang/rust/issues/58319) in the past. +- **issue-88862**: A MCVE of a program that had a + [severe performance regression](https://github.com/rust-lang/rust/issues/88862) + when trying to normalize large opaque types with late-bound regions. - **many-assoc-items**: Contains a struct with many associated items, which caused [quadratic behavior](https://github.com/rust-lang/rust/issues/68957) in the past. diff --git a/collector/benchmarks/issue-88862/Cargo.lock b/collector/benchmarks/issue-88862/Cargo.lock new file mode 100644 index 000000000..4f9cf2465 --- /dev/null +++ b/collector/benchmarks/issue-88862/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "issue-58319" +version = "0.1.0" diff --git a/collector/benchmarks/issue-88862/Cargo.toml b/collector/benchmarks/issue-88862/Cargo.toml new file mode 100644 index 000000000..e02baac8d --- /dev/null +++ b/collector/benchmarks/issue-88862/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "issue-88862" +version = "0.1.0" +edition = "2018" + diff --git a/collector/benchmarks/issue-88862/src/main.rs b/collector/benchmarks/issue-88862/src/main.rs new file mode 100644 index 000000000..70ddd39f4 --- /dev/null +++ b/collector/benchmarks/issue-88862/src/main.rs @@ -0,0 +1,196 @@ +#[derive(Debug)] +struct Error; +struct SharedPool { + a: PoolOptions, +} + +struct PoolOptions; + +async fn check<'s: 'p, 'p>( + mut _conn: Floating<'s>, + _: &'p PoolOptions, +) -> Result<(), DecrementSizeGuard<'s>> { + todo!() +} + +impl SharedPool { + async fn acquire(&'_ self) -> Result, Error> { + async { + if let conn = todo!() { + if let d = check(conn, &self.a).await {} + } + } + .await; + todo!() + } +} + +struct G; +struct Floating<'s>(std::marker::PhantomData); +impl<'s> Floating<'s> { + fn attach(self, e: &std::sync::Arc) -> G { todo!() } +} + +struct DecrementSizeGuard<'s>(std::marker::PhantomData); +struct FooDb; +impl FooDb { + fn acquire(&self) -> impl std::future::Future> + 'static { + let _shared: std::sync::Arc = todo!(); + async move { _shared.acquire().await.map(|conn| conn.attach(&_shared)) } + } + + async fn nested(&self) -> Result, ()> { + (async move { + match async move { + async move { + ( + async move { + match async move { + let db = FooDb; + let mut _conn = db.acquire().await.unwrap(); + Ok::<_, ()>(String::default()) + } + .await + { + Ok(x) => Ok(x), + Err0 => todo!(), + } + }, + todo!(), + ) + .0 + .await + } + .await + .map(Some) + } + .await + { + Ok(x) => Ok(x), + Err(e) => Err(e), + } + },) + .0 + .await + } +} + +fn main() -> Result<(), Box> { + factory(Factory::handle(route)); + todo!() +} + +fn factory(factory: X) -> BoxServiceFactory +where X: ServiceFactory + 'static { + BoxServiceFactory(Box::new(FactoryWrapper(factory))) +} + + +async fn route(database: FooDb) -> Result<(), Error> { + database.nested().await; + todo!() +} + +struct Factory { + _hnd: I, + j: std::marker::PhantomData<(T, R)>, +} + +impl Factory { + fn handle(_: I) -> Self { todo!() } +} + +struct K; +struct L; +impl ServiceFactory for Factory +where + I: N, + R: std::future::Future, + R::Output: Responder, +{ + type Future = std::future::Ready>; + type Service = Self; + + fn new_service(&self, _: ()) -> Self::Future { todo!() } +} + +impl Service for Factory { + type Error = Error; + type Future = std::future::Ready>; + + fn poll(&self, _: &mut core::task::Context) -> core::task::Poll> { todo!() } + + fn call(&self, m: K) -> Self::Future { todo!() } +} + +trait Responder {} + +impl Responder for Result {} + +trait N: 'static +where + R: std::future::Future, + R::Output: Responder, { + fn call(&self, param: T) -> R; +} + + +type BoxFuture = std::pin::Pin>>; + +struct BoxServiceFactory( + Box< + dyn ServiceFactory< + Req, + Service = Box>>>, + Future = BoxFuture< + Result>>>, ()>, + >, + >, + >, +); + +trait ServiceFactory { + type Service: Service; + type Future; + fn new_service(&self, _: ()) -> Self::Future; +} + +trait Service { + type Error; + type Future; + fn poll(&self, ctx: &mut std::task::Context) -> std::task::Poll>; + fn call(&self, req: Req) -> Self::Future; +} + +impl Service for Box +where S: Service + ?Sized +{ + type Error = S::Error; + type Future = S::Future; + + fn poll(&self, _: &mut std::task::Context) -> std::task::Poll> { todo!() } + + fn call(&self, _: Req) -> S::Future { todo!() } +} + +impl ServiceFactory for FactoryWrapper +where + SF: ServiceFactory, + SF: 'static, +{ + type Future = BoxFuture>; + type Service = Box>>>; + + fn new_service(&self, _: ()) -> Self::Future { todo!() } +} + +impl N<(A,), Res> for Func +where + Func: Fn(A) -> Res + 'static, + Res: std::future::Future, + Res::Output: Responder, +{ + fn call(&self, _: (A,)) -> Res { todo!() } +} + +struct FactoryWrapper(T);