diff --git a/tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs b/tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs new file mode 100644 index 0000000000000..4e8c19d600d61 --- /dev/null +++ b/tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs @@ -0,0 +1,244 @@ +// This is a non-regression test for issues #108721 and its duplicate #123275 (hopefully, because +// the test is still convoluted and the ICE is fiddly). +// +// `pred_known_to_hold_modulo_regions` prevented "unexpected unsized tail" ICEs with warp/hyper but +// was unknowingly removed in #120463. + +//@ build-pass: the ICE happened in codegen + +use std::future::Future; +trait TryFuture: Future { + type Ok; +} +impl TryFuture for F +where + F: ?Sized + Future>, +{ + type Ok = T; +} +trait Executor {} +struct Exec {} +trait HttpBody { + type Data; +} +trait ConnStreamExec {} +impl ConnStreamExec for Exec where H2Stream: Send {} +impl ConnStreamExec for E where E: Executor {} +struct H2Stream { + _fut: F, +} +trait NewSvcExec> { + fn execute_new_svc(&mut self, _fut: NewSvcTask) { + unimplemented!() + } +} +impl NewSvcExec for Exec where W: Watcher {} +trait Watcher { + type Future; +} +struct NoopWatcher; +impl Watcher for NoopWatcher +where + S: HttpService, + E: ConnStreamExec, +{ + type Future = Option<<::ResBody as HttpBody>::Data>; +} +trait Service { + type Response; + type Future; +} +trait HttpService { + type ResBody: HttpBody; + type Future; +} +struct Body {} +impl HttpBody for Body { + type Data = String; +} +impl HttpService for S +where + S: Service<(), Response = ()>, +{ + type ResBody = Body; + type Future = S::Future; +} +trait MakeServiceRef { + type ResBody; + type Service: HttpService; +} +impl MakeServiceRef for T +where + T: for<'a> Service<&'a Target, Response = S, Future = F>, + S: HttpService, +{ + type Service = S; + type ResBody = S::ResBody; +} +fn make_service_fn(_f: F) -> MakeServiceFn +where + F: FnMut(&Target) -> Ret, + Ret: Future, +{ + unimplemented!() +} +struct MakeServiceFn { + _func: F, +} +impl<'t, F, Ret, Target, Svc> Service<&'t Target> for MakeServiceFn +where + F: FnMut(&Target) -> Ret, + Ret: Future>, +{ + type Response = Svc; + type Future = Option<()>; +} +struct AddrIncoming {} +struct Server { + _incoming: I, + _make_service: S, + _protocol: E, +} +impl Server +where + S: MakeServiceRef<(), ResBody = B>, + B: HttpBody, + E: ConnStreamExec<::Future>, + E: NewSvcExec, +{ + fn serve(&mut self) { + let fut = NewSvcTask::new(); + self._protocol.execute_new_svc(fut); + } +} +fn serve(_make_service: S) -> Server { + unimplemented!() +} +struct NewSvcTask> { + _state: State, +} +struct State> { + _fut: W::Future, +} +impl> NewSvcTask { + fn new() -> Self { + unimplemented!() + } +} +trait Filter { + type Extract; + type Future; + fn map(self, _fun: F) -> MapFilter + where + Self: Sized, + { + unimplemented!() + } + fn wrap_with(self, _wrapper: W) -> W::Wrapped + where + Self: Sized, + W: Wrap, + { + unimplemented!() + } +} +fn service(_filter: F) -> FilteredService +where + F: Filter, +{ + unimplemented!() +} +struct FilteredService { + _filter: F, +} +impl Service<()> for FilteredService +where + F: Filter, +{ + type Response = (); + type Future = FilteredFuture; +} +struct FilteredFuture { + _fut: F, +} +struct MapFilter { + _filter: T, + _func: F, +} +impl Filter for MapFilter +where + T: Filter, + F: Func, +{ + type Extract = F::Output; + type Future = MapFilterFuture; +} +struct MapFilterFuture { + _extract: T::Future, + _func: F, +} +trait Wrap { + type Wrapped; +} +fn make_filter_fn(_func: F) -> FilterFn +where + F: Fn() -> U, +{ + unimplemented!() +} +struct FilterFn { + _func: F, +} +impl Filter for FilterFn +where + F: Fn() -> U, + U: TryFuture, + U::Ok: Send, +{ + type Extract = U::Ok; + type Future = Option; +} +fn trace(_func: F) -> Trace +where + F: Fn(), +{ + unimplemented!() +} +struct Trace { + _func: F, +} +impl Wrap for Trace { + type Wrapped = WithTrace; +} +struct WithTrace { + _filter: F, + _trace: FN, +} +impl Filter for WithTrace +where + F: Filter, +{ + type Extract = (); + type Future = (F::Future, fn(F::Extract)); +} +trait Func { + type Output; +} +impl Func<()> for F +where + F: Fn() -> R, +{ + type Output = R; +} +fn main() { + let make_service = make_service_fn(|_| { + let tracer = trace(|| unimplemented!()); + let filter = make_filter_fn(|| std::future::ready(Some(()))) + .map(|| "Hello, world") + .wrap_with(tracer); + let svc = service(filter); + std::future::ready(Some(svc)) + }); + let mut server = serve(make_service); + server.serve(); +}