Change:
<!-- [31mICE[0m: Rustc '' 'error: internal compiler error: opaque types got hidden types registered from within subtype predicate: Alias(Opaque, AliasTy { args: [], defid: DefId(0:25 ~ ice[ee90]::Tait::{opaque}) }) vs Continuation', 'error: internal compiler error: opaque types got hidden types registered from within subtype predicate: Alias(Opaque, AliasTy { args: [], defid: DefId(0:25 ~ ice[ee90]::Tait::{opaque}) }) vs Continuation' File: --auto-reduced (treereduce-rust): &lt;details&lt;summary&lt;strongoriginal code&lt;/strong&lt;/summary&lt;poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [typeck] type-checking [typeofopaque] computing type of opaque [typeof] computing type of [checkwellformed] checking that is well-formed [checkmodtypewf] checking that types are well-formed in top-level module [analysis] running analysis passes on this crate -- label +F-typealiasimpl_trait
bit smaller

Discussion:
(&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { return Err((a_vid, b_vid)); } <del> // We don't silently want to constrain hidden types here, so we assert that either one side is // an infer var, so it'll get constrained to whatever the other side is, or there are no opaque // types involved. // We don't expect this to actually get hit, but if it does, we now at least know how to write // a test for it. (_, ty::Infer(ty::TyVar(_))) => {} (ty::Infer(ty::TyVar(_)), _) => {} _ if r_a != r_b && (r_a, r_b).has_opaque_types() => { span_bug!( cause.span(), "opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}" ) } </del> _ => {} } self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { if a_is_expected { <del> Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b)) </del> <ins> Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b)) </ins> } else { <del> Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a)) </del> <ins> Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a)) </ins> } }) }

<del> //@ known-bug: rust-lang/rust#124891 type Tait = impl FnOnce() -> (); fn reify_as_tait() -> Thunk<Tait> { Thunk::new(|cont| cont) } struct Thunk<F>(F); impl<F> Thunk<F> { fn new(f: F) where F: ContFn, { todo!(); } } trait ContFn {} impl<F: FnOnce(Tait) -> ()> ContFn for F {} </del>

<ins> //! This test checks that we allow subtyping predicates that contain opaque types. //! No hidden types are being constrained in the subtyping predicate, but type and //! lifetime variables get subtyped in the generic parameter list of the opaque. use std::iter; mod either { pub enum Either<L, R> { Left(L), Right(R), } impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> { type Item = L::Item; fn next(&mut self) -> Option<Self::Item> { todo!() } } pub use self::Either::{Left, Right}; } pub enum BabeConsensusLogRef<'a> { NextEpochData(BabeNextEpochRef<'a>), NextConfigData, } impl<'a> BabeConsensusLogRef<'a> { pub fn scale_encoding( &self, ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { //~^ ERROR is not satisfied //~| ERROR is not satisfied //~| ERROR is not satisfied match self { BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left( digest.scale_encoding().map(either::Left).map(either::Left), )), BabeConsensusLogRef::NextConfigData => either::Right( // The Opaque type from ``scale_encoding` gets used opaquely here, while the `R` // generic parameter of `Either` contains type variables that get subtyped and the // opaque type contains lifetime variables that get subtyped. iter::once(either::Right(either::Left([1]))) .chain(std::iter::once([1]).map(either::Right).map(either::Right)), ), } } } pub struct BabeNextEpochRef<'a>(&'a ()); impl<'a> BabeNextEpochRef<'a> { pub fn scale_encoding( &self, ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { std::iter::once([1]) } } fn main() {} </ins>

<ins> error[E0277]: the trait bound `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied --> $DIR/lazy_subtyping_of_opaques.rs:30:10 | LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>` error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied --> $DIR/lazy_subtyping_of_opaques.rs:30:31 | LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>` error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied --> $DIR/lazy_subtyping_of_opaques.rs:30:31 | LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a { |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. </ins>

<ins> #![feature(type_alias_impl_trait)] //! This test used to ICE rust-lang/rust#124891 //! because we added an assertion for catching cases where opaque types get //! registered during the processing of subtyping predicates. type Tait = impl FnOnce() -> (); fn reify_as_tait() -> Thunk<Tait> { Thunk::new(|cont| cont) //~^ ERROR: mismatched types //~| ERROR: mismatched types } struct Thunk<F>(F); impl<F> Thunk<F> { fn new(f: F) where F: ContFn, { todo!(); } } trait ContFn {} impl<F: FnOnce(Tait) -> ()> ContFn for F {} fn main() {} </ins>

<ins> error[E0308]: mismatched types --> $DIR/lazy_subtyping_of_opaques.rs:10:23 | LL | type Tait = impl FnOnce() -> (); |             ------------------- the found opaque type ... LL |     Thunk::new(|cont| cont) |                       ^^^^ expected `()`, found opaque type | = note: expected unit type `()` found opaque type `Tait` error[E0308]: mismatched types --> $DIR/lazy_subtyping_of_opaques.rs:10:5 | LL | fn reify_as_tait() -> Thunk<Tait> { |                       ----------- expected `Thunk<_>` because of return type LL |     Thunk::new(|cont| cont) |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` | = note: expected struct `Thunk<_>` found unit type `()` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>