Change:
Found as a byproduct of work on backtrace: Compiles on stable 1.35.0.
triage: Looks like matthewjasper is on top of this. Marking P-high just so I don't have to think about it further right now. Removing nomination tag.

Discussion:
/// A hacky variant of `canonicalize_query` that does not /// canonicalize `'static`. Unfortunately, the existing leak <del> /// check treaks `'static` differently in some cases (see also </del> <ins> /// check treats `'static` differently in some cases (see also </ins> /// #33684), so if we are performing an operation that may need to /// prove "leak-check" related things, we leave `'static` /// alone. <ins> /// /// `'static` is also special cased when winnowing candidates when /// selecting implementation candidates, so we also have to leave `'static` /// alone for queries that do selection. </ins> // <del> // FIXME(#48536): once we have universes, we can remove this and just use // `canonicalize_query`. </del> <ins> // FIXME(#48536): once the above issues are resolved, we can remove this // and just use `canonicalize_query`. </ins> pub fn canonicalize_hr_query_hack<V>( &self, value: &V,

let gcx = self.infcx.tcx.global_tcx(); let mut orig_values = OriginalQueryValues::default(); <del> let c_data = self.infcx.canonicalize_query( </del> <ins> // HACK(matthewjasper) `'static` is special-cased in selection, // so we cannot canonicalize it. let c_data = self.infcx.canonicalize_hr_query_hack( </ins> &self.param_env.and(*data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values);

match outlives_bound { OutlivesBound::RegionSubRegion(r1, r2) => { <ins> // `where Type:` is lowered to `where Type: 'empty` so that // we check `Type` is well formed, but there's no use for // this bound here. if let ty::ReEmpty = r1 { return; } </ins> // The bound says that `r1 <= r2`; we store `r2: r1`. let r1 = self.universal_regions.to_region_vid(r1); let r2 = self.universal_regions.to_region_vid(r2);

<ins> // 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() {} </ins>

<ins> // 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() {} </ins>

<ins> // 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() {} </ins>