diff options
Diffstat (limited to 'tests/ui/nll/issue-61320-normalize.rs')
-rw-r--r-- | tests/ui/nll/issue-61320-normalize.rs | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tests/ui/nll/issue-61320-normalize.rs b/tests/ui/nll/issue-61320-normalize.rs new file mode 100644 index 000000000..095bef03f --- /dev/null +++ b/tests/ui/nll/issue-61320-normalize.rs @@ -0,0 +1,160 @@ +// Regression test for #61320 +// This is the same issue as #61311, just a larger test case. + +// check-pass + +pub struct AndThen<A, B, F> +where + A: Future, + B: IntoFuture, +{ + state: (A, B::Future, F), +} + +pub struct FutureResult<T, E> { + inner: Option<Result<T, E>>, +} + +impl<T, E> Future for FutureResult<T, E> { + type Item = T; + type Error = E; + + fn poll(&mut self) -> Poll<T, E> { + unimplemented!() + } +} + +pub type Poll<T, E> = Result<T, E>; + +impl<A, B, F> Future for AndThen<A, B, F> +where + A: Future, + B: IntoFuture<Error = A::Error>, + F: FnOnce(A::Item) -> B, +{ + type Item = B::Item; + type Error = B::Error; + + fn poll(&mut self) -> Poll<B::Item, B::Error> { + unimplemented!() + } +} + +pub trait Future { + type Item; + + type Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error>; + + fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F> + where + F: FnOnce(Self::Item) -> B, + B: IntoFuture<Error = Self::Error>, + Self: Sized, + { + unimplemented!() + } +} + +pub trait IntoFuture { + /// The future that this type can be converted into. + type Future: Future<Item = Self::Item, Error = Self::Error>; + + /// The item that the future may resolve with. + type Item; + /// The error that the future may resolve with. + type Error; + + /// Consumes this object and produces a future. + fn into_future(self) -> Self::Future; +} + +impl<F: Future> IntoFuture for F { + type Future = F; + type Item = F::Item; + type Error = F::Error; + + fn into_future(self) -> F { + self + } +} + +impl<F: ?Sized + Future> Future for ::std::boxed::Box<F> { + type Item = F::Item; + type Error = F::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + (**self).poll() + } +} + +impl<T, E> IntoFuture for Result<T, E> { + type Future = FutureResult<T, E>; + type Item = T; + type Error = E; + + fn into_future(self) -> FutureResult<T, E> { + unimplemented!() + } +} + +struct Request<T>(T); + +trait RequestContext {} +impl<T> RequestContext for T {} +struct NoContext; +impl AsRef<NoContext> for NoContext { + fn as_ref(&self) -> &Self { + &NoContext + } +} + +type BoxedError = Box<dyn std::error::Error + Send + Sync>; +type DefaultFuture<T, E> = Box<dyn Future<Item = T, Error = E> + Send>; + +trait Guard: Sized { + type Result: IntoFuture<Item = Self, Error = BoxedError>; + fn from_request(request: &Request<()>) -> Self::Result; +} + +trait FromRequest: Sized { + type Context; + type Future: Future<Item = Self, Error = BoxedError> + Send; + fn from_request(request: Request<()>) -> Self::Future; +} + +struct MyGuard; +impl Guard for MyGuard { + type Result = Result<Self, BoxedError>; + fn from_request(_request: &Request<()>) -> Self::Result { + Ok(MyGuard) + } +} + +struct Generic<I> { + _inner: I, +} + +impl<I> FromRequest for Generic<I> +where + MyGuard: Guard, + <MyGuard as Guard>::Result: IntoFuture<Item = MyGuard, Error = BoxedError>, + <<MyGuard as Guard>::Result as IntoFuture>::Future: Send, + I: FromRequest<Context = NoContext>, +{ + type Future = DefaultFuture<Self, BoxedError>; + type Context = NoContext; + fn from_request(headers: Request<()>) -> DefaultFuture<Self, BoxedError> { + let _future = <MyGuard as Guard>::from_request(&headers) + .into_future() + .and_then(move |_| { + <I as FromRequest>::from_request(headers) + .into_future() + .and_then(move |fld_inner| Ok(Generic { _inner: fld_inner }).into_future()) + }); + panic!(); + } +} + +fn main() {} |