Change:
The type is not inferred to be by the above mentioned nightly release, c.f. Using the stable, the code compiles with out issue. EDIT: It seems to be related to GAT, i.e. a more minimal reproducer is: which similarly fails on nightly and builds on stable. <details<summaryMore details</summaryon the above-mentioned nightly version whereas stable is happy Simply asserting that is via e.g. works on stable and nightly. </details
The reproducer wouldn't compile on stable though?
Sorry, I must have messed something up when trying to whittle it down as the reproducer I started with definitely did compile on stable. Will try to trace my steps backwards.
And indeed using instead of makes it compile on stable. (I wanted to avoid to avoid the standard library but indeed is closer to the original code in question.) I updated the reproducer in the OP accordingly.
Great, thank you. So I believe this to be a different manifestation of from cc -- and therefore also to be fixed by
Stumbled on this separately in my own code. The simplest reproduction I was able to come up with is Removing makes it compile on nightly as well. Putting a bound on does not help.

Discussion:
} self.infcx.probe(|_snapshot| { <del> if obligation.has_non_region_late_bound() { return; } </del> <ins> let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let placeholder_trait_predicate = self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); </ins> <del> // The code below doesn't care about regions, and the // self-ty here doesn't escape this probe, so just erase // any LBR. let self_ty = self.tcx().erase_late_bound_regions(obligation.self_ty()); let poly_trait_ref = match self_ty.kind() { </del> <ins> let self_ty = placeholder_trait_predicate.self_ty(); let principal_trait_ref = match self_ty.kind() { </ins> ty::Dynamic(ref data, ..) => { if data.auto_traits().any(|did| did == obligation.predicate.def_id()) { debug!(

_ => return, }; <del> debug!(?poly_trait_ref, "assemble_candidates_from_object_ty"); let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let placeholder_trait_predicate = self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); </del> <ins> debug!(?principal_trait_ref, "assemble_candidates_from_object_ty"); </ins> // Count only those upcast versions that match the trait-ref // we are looking for. Specifically, do not only check for the // correct trait, but also the correct type parameters. // For example, we may be trying to upcast `Foo` to `Bar<i32>`, // but `Foo` is declared as `trait Foo: Bar<u32>`. <del> let candidate_supertraits = util::supertraits(self.tcx(), poly_trait_ref) </del> <ins> let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref) </ins> .enumerate() .filter(|&(_, upcast_trait_ref)| { self.infcx.probe(|_| {

<ins> warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/non-lifetime-via-dyn-builtin.rs:5:12 | LL | #![feature(non_lifetime_binders)] |            ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted </ins>

<ins> // revisions: current next //[next] compile-flags: -Ztrait-solver=next // check-pass #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete and may not be safe fn trivial<A>() where for<B> dyn Fn(A, *const B): Fn(A, *const B), { } fn main() { trivial::<u8>(); } </ins>

<ins> // check-pass trait Foo { type Bar<T> where dyn Send + 'static: Send; } impl Foo for () { type Bar<T> = i32; // We take `<() as Foo>::Bar<T>: Sized` and normalize it under the where clause // of `for<S> <() as Foo>::Bar<S> = i32`. This gives us back `i32: Send` with // the nested obligation `(dyn Send + 'static): Send`. However, during candidate // assembly for object types, we disqualify any obligations that has non-region // late-bound vars in the param env(!), rather than just the predicate. This causes // the where clause to not hold even though it trivially should. } fn main() {} </ins>