diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6460613d7d502..13bf2c277be8e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1620,16 +1620,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for bound in self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) { - // HACK: On subsequent recursions, we only care about bounds that don't + // HACK: In the initial recursion, we only care about bounds for the + // `self_ty`. On subsequent recursions, we care about bounds that don't // share the same type as `self_ty`. This is because for truly rigid // projections, we will never be able to equate, e.g. `::A` // with `<::A as Tr>::A`. - if in_parent_alias_type { - match bound.kind().skip_binder() { - ty::ClauseKind::Trait(tr) if tr.self_ty() == self_ty => continue, - ty::ClauseKind::Projection(p) if p.self_ty() == self_ty => continue, - _ => {} + match bound.kind().skip_binder() { + ty::ClauseKind::Trait(tr) + if (tr.self_ty() == self_ty) ^ !in_parent_alias_type => + { + continue; + } + ty::ClauseKind::Projection(p) + if (p.self_ty() == self_ty) ^ !in_parent_alias_type => + { + continue; } + _ => {} } for_each(self, bound, idx)?;