From fa551a1575cb4b11541695bb9f62796ab8d20142 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Feb 2024 20:44:43 +0000 Subject: [PATCH] Collect relevant item bounds from trait clauses for nested rigid projections --- .../src/collect/item_bounds.rs | 21 ++++++++++---- .../imply-relevant-nested-item-bounds-2.rs | 28 +++++++++++++++++++ .../imply-relevant-nested-item-bounds.rs | 23 +++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs create mode 100644 tests/ui/associated-types/imply-relevant-nested-item-bounds.rs diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 39ca1bba06545..1b25217579d68 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -35,11 +35,22 @@ fn associated_type_bounds<'tcx>( let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id); let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { - match pred.kind().skip_binder() { - ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty, - ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty, - ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty, - _ => false, + let mut clause_ty = match pred.kind().skip_binder() { + ty::ClauseKind::Trait(tr) => tr.self_ty(), + ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty(), + ty::ClauseKind::TypeOutlives(outlives) => outlives.0, + _ => return false, + }; + + loop { + if clause_ty == item_ty { + return true; + } else if let ty::Alias(ty::Projection, alias_ty) = *clause_ty.kind() { + clause_ty = alias_ty.self_ty(); + continue; + } + + return false; } }); diff --git a/tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs b/tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs new file mode 100644 index 0000000000000..59248c1e62339 --- /dev/null +++ b/tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs @@ -0,0 +1,28 @@ +// check-pass +// revisions: current next +//[next] compile-flags: -Znext-solver + +trait Trait +where + Self::Assoc: Clone, +{ + type Assoc; +} + +fn foo(x: &T::Assoc) -> T::Assoc { + x.clone() +} + +trait Trait2 +where + Self::Assoc: Iterator, + ::Item: Clone, +{ + type Assoc; +} + +fn foo2(x: &::Item) -> ::Item { + x.clone() +} + +fn main() {} diff --git a/tests/ui/associated-types/imply-relevant-nested-item-bounds.rs b/tests/ui/associated-types/imply-relevant-nested-item-bounds.rs new file mode 100644 index 0000000000000..0aa703168ba3a --- /dev/null +++ b/tests/ui/associated-types/imply-relevant-nested-item-bounds.rs @@ -0,0 +1,23 @@ +// check-pass +// revisions: current next +//[next] compile-flags: -Znext-solver + +trait Foo +where + Self::Iterator: Iterator, + ::Item: Bar, +{ + type Iterator; + + fn iter() -> Self::Iterator; +} + +trait Bar { + fn bar(&self); +} + +fn x() { + T::iter().next().unwrap().bar(); +} + +fn main() {}