From 38df5bdcf1fee2dc4a7a566afee0f0f161417701 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 11 Feb 2024 18:23:05 +0000 Subject: [PATCH] Ignore own item bounds in parent alias types in `for_each_item_bound` --- .../src/traits/select/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ac6cfcdeb5950..fb2f1da325292 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1605,6 +1605,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { on_ambiguity: impl FnOnce(), ) -> ControlFlow { let mut idx = 0; + let mut in_parent_alias_type = false; + loop { let (kind, alias_ty) = match *self_ty.kind() { ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty), @@ -1618,6 +1620,18 @@ 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 + // 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, + _ => {} + } + } + for_each(self, bound, idx)?; idx += 1; } @@ -1627,6 +1641,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else { return ControlFlow::Continue(()); } + + in_parent_alias_type = true; } }