Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmark for issue-88862 #1033

Merged
merged 1 commit into from
Sep 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions collector/benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions collector/benchmarks/issue-88862/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions collector/benchmarks/issue-88862/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "issue-88862"
version = "0.1.0"
edition = "2018"

196 changes: 196 additions & 0 deletions collector/benchmarks/issue-88862/src/main.rs
Original file line number Diff line number Diff line change
@@ -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<Floating<'_>, Error> {
async {
if let conn = todo!() {
if let d = check(conn, &self.a).await {}
}
}
.await;
todo!()
}
}

struct G;
struct Floating<'s>(std::marker::PhantomData<dyn Fn(&'s ())>);
impl<'s> Floating<'s> {
fn attach(self, e: &std::sync::Arc<SharedPool>) -> G { todo!() }
}

struct DecrementSizeGuard<'s>(std::marker::PhantomData<dyn Fn(&'s ())>);
struct FooDb;
impl FooDb {
fn acquire(&self) -> impl std::future::Future<Output = Result<G, Error>> + 'static {
let _shared: std::sync::Arc<SharedPool> = todo!();
async move { _shared.acquire().await.map(|conn| conn.attach(&_shared)) }
}

async fn nested(&self) -> Result<Option<String>, ()> {
(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<dyn std::error::Error + 'static>> {
factory(Factory::handle(route));
todo!()
}

fn factory<X, Req>(factory: X) -> BoxServiceFactory<Req>
where X: ServiceFactory<Req> + 'static {
BoxServiceFactory(Box::new(FactoryWrapper(factory)))
}


async fn route(database: FooDb) -> Result<(), Error> {
database.nested().await;
todo!()
}

struct Factory<I, T, R> {
_hnd: I,
j: std::marker::PhantomData<(T, R)>,
}

impl<I, T, R> Factory<I, T, R> {
fn handle(_: I) -> Self { todo!() }
}

struct K;
struct L;
impl<I, T, R> ServiceFactory<K> for Factory<I, T, R>
where
I: N<T, R>,
R: std::future::Future,
R::Output: Responder,
{
type Future = std::future::Ready<Result<Self, ()>>;
type Service = Self;

fn new_service(&self, _: ()) -> Self::Future { todo!() }
}

impl<I, T, R> Service<K> for Factory<I, T, R> {
type Error = Error;
type Future = std::future::Ready<Result<L, Error>>;

fn poll(&self, _: &mut core::task::Context) -> core::task::Poll<Result<(), Error>> { todo!() }

fn call(&self, m: K) -> Self::Future { todo!() }
}

trait Responder {}

impl<T, R> Responder for Result<T, R> {}

trait N<T, R>: 'static
where
R: std::future::Future,
R::Output: Responder, {
fn call(&self, param: T) -> R;
}


type BoxFuture<T> = std::pin::Pin<Box<dyn std::future::Future<Output = T>>>;

struct BoxServiceFactory<Req>(
Box<
dyn ServiceFactory<
Req,
Service = Box<dyn Service<Req, Error = (), Future = BoxFuture<Result<(), ()>>>>,
Future = BoxFuture<
Result<Box<dyn Service<Req, Error = (), Future = BoxFuture<Result<(), ()>>>>, ()>,
>,
>,
>,
);

trait ServiceFactory<Req> {
type Service: Service<Req>;
type Future;
fn new_service(&self, _: ()) -> Self::Future;
}

trait Service<Req> {
type Error;
type Future;
fn poll(&self, ctx: &mut std::task::Context) -> std::task::Poll<Result<(), Self::Error>>;
fn call(&self, req: Req) -> Self::Future;
}

impl<S, Req> Service<Req> for Box<S>
where S: Service<Req> + ?Sized
{
type Error = S::Error;
type Future = S::Future;

fn poll(&self, _: &mut std::task::Context) -> std::task::Poll<Result<(), S::Error>> { todo!() }

fn call(&self, _: Req) -> S::Future { todo!() }
}

impl<SF, Req> ServiceFactory<Req> for FactoryWrapper<SF>
where
SF: ServiceFactory<Req>,
SF: 'static,
{
type Future = BoxFuture<Result<Self::Service, ()>>;
type Service = Box<dyn Service<Req, Error = (), Future = BoxFuture<Result<(), ()>>>>;

fn new_service(&self, _: ()) -> Self::Future { todo!() }
}

impl<Func, A, Res> 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>(T);