about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/nll/empty-type-predicate.rs11
-rw-r--r--src/test/ui/nll/issue-61311-normalize.rs34
-rw-r--r--src/test/ui/nll/issue-61320-normalize.rs160
3 files changed, 205 insertions, 0 deletions
diff --git a/src/test/ui/nll/empty-type-predicate.rs b/src/test/ui/nll/empty-type-predicate.rs
new file mode 100644
index 00000000000..75431d40ce5
--- /dev/null
+++ b/src/test/ui/nll/empty-type-predicate.rs
@@ -0,0 +1,11 @@
+// Regression test for #61315
+//
+// `dyn T:` is lowered to `dyn T: ReEmpty` - check that we don't ICE in NLL for
+// the unexpected region.
+
+// compile-pass
+
+trait T {}
+fn f() where dyn T: {}
+
+fn main() {}
diff --git a/src/test/ui/nll/issue-61311-normalize.rs b/src/test/ui/nll/issue-61311-normalize.rs
new file mode 100644
index 00000000000..1164e9ef2d6
--- /dev/null
+++ b/src/test/ui/nll/issue-61311-normalize.rs
@@ -0,0 +1,34 @@
+// Regression test for #61311
+// We would ICE after failing to normalize `Self::Proj` in the `impl` below.
+
+// compile-pass
+
+pub struct Unit;
+trait Obj {}
+
+trait Bound {}
+impl Bound for Unit {}
+
+pub trait HasProj {
+    type Proj;
+}
+
+impl<T> HasProj for T {
+    type Proj = Unit;
+}
+
+trait HasProjFn {
+    type Proj;
+    fn the_fn(_: Self::Proj);
+}
+
+impl HasProjFn for Unit
+where
+    Box<dyn Obj + 'static>: HasProj,
+    <Box<dyn Obj + 'static> as HasProj>::Proj: Bound,
+{
+    type Proj = Unit;
+    fn the_fn(_: Self::Proj) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/issue-61320-normalize.rs b/src/test/ui/nll/issue-61320-normalize.rs
new file mode 100644
index 00000000000..a36ccd36113
--- /dev/null
+++ b/src/test/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.
+
+// compile-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() {}