diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index dbb6c54fcd9..07720ba71ca 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -175,9 +175,6 @@ fn candidate_from_obligation_no_cache<'o>(
let needs_infer = stack.obligation.predicate.has_infer_types_or_consts();
- let sized_predicate = self.tcx().lang_items().sized_trait()
- == Some(stack.obligation.predicate.skip_binder().def_id());
-
// If there are STILL multiple candidates, we can further
// reduce the list by dropping duplicates -- including
// resolving specializations.
@@ -186,7 +183,6 @@ fn candidate_from_obligation_no_cache<'o>(
while i < candidates.len() {
let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| {
self.candidate_should_be_dropped_in_favor_of(
- sized_predicate,
&candidates[i],
&candidates[j],
needs_infer,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index e69bf6eca90..9e2d0657029 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1553,7 +1553,6 @@ pub(super) fn match_projection_projections(
/// See the comment for "SelectionCandidate" for more details.
fn candidate_should_be_dropped_in_favor_of(
&mut self,
- sized_predicate: bool,
victim: &EvaluatedCandidate<'tcx>,
other: &EvaluatedCandidate<'tcx>,
needs_infer: bool,
@@ -1625,16 +1624,6 @@ fn candidate_should_be_dropped_in_favor_of(
// Drop otherwise equivalent non-const fn pointer candidates
(FnPointerCandidate { .. }, FnPointerCandidate { is_const: false }) => true,
- // If obligation is a sized predicate or the where-clause bound is
- // global, prefer the projection or object candidate. See issue
- // #50825 and #89352.
- (ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
- sized_predicate || is_global(cand)
- }
- (ParamCandidate(ref cand), ObjectCandidate(_) | ProjectionCandidate(_)) => {
- !(sized_predicate || is_global(cand))
- }
-
// Global bounds from the where clause should be ignored
// here (see issue #50825). Otherwise, we have a where
// clause so don't go around looking for impls.
@@ -1650,8 +1639,15 @@ fn candidate_should_be_dropped_in_favor_of(
| BuiltinUnsizeCandidate
| TraitUpcastingUnsizeCandidate(_)
| BuiltinCandidate { .. }
- | TraitAliasCandidate(..),
+ | TraitAliasCandidate(..)
+ | ObjectCandidate(_)
+ | ProjectionCandidate(_),
) => !is_global(cand),
+ (ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
+ // Prefer these to a global where-clause bound
+ // (see issue #50825).
+ is_global(cand)
+ }
(
ImplCandidate(_)
| ClosureCandidate
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89352.base.stderr b/src/test/ui/generic-associated-types/bugs/issue-89352.base.stderr
new file mode 100644
index 00000000000..81125a7d6f3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-89352.base.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-89352.rs:36:13
+ |
+LL | let a = A::reborrow::<'ai, 's>(self.a.clone());
+ | ^ lifetime mismatch
+ |
+ = note: expected type `<>::Iter<'s> as Sized>`
+ found type `<>::Iter<'ai> as Sized>`
+note: the lifetime `'s` as defined here...
+ --> $DIR/issue-89352.rs:35:13
+ |
+LL | fn iter<'s>(&'s self) -> Self::Iter<'s> {
+ | ^^
+note: ...does not necessarily outlive the lifetime `'ai` as defined here
+ --> $DIR/issue-89352.rs:30:6
+ |
+LL | impl<'ai, T: 'ai, A: GenAssoc> GenAssoc for Wrapper<'ai, T, A>
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/generic-associated-types/issue-89352.rs b/src/test/ui/generic-associated-types/bugs/issue-89352.rs
similarity index 58%
rename from src/test/ui/generic-associated-types/issue-89352.rs
rename to src/test/ui/generic-associated-types/bugs/issue-89352.rs
index d9c656d5f58..a9f0dd0a0b4 100644
--- a/src/test/ui/generic-associated-types/issue-89352.rs
+++ b/src/test/ui/generic-associated-types/bugs/issue-89352.rs
@@ -1,4 +1,16 @@
-// check-pass
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
+//[base] check-fail
+//[nll] check-pass
+// known-bug
+
+// This should pass, but we end up with `A::Iter<'ai>: Sized` for some specific
+// `'ai`. We also know that `for<'at> A::Iter<'at>: Sized` from the definition,
+// but we prefer param env candidates. We changed this to preference in #92191,
+// but this led to unintended consequences (#93262). Suprisingly, this passes
+// under NLL. So only a bug in migrate mode.
#![feature(generic_associated_types)]
diff --git a/src/test/ui/generic-associated-types/issue-93262.rs b/src/test/ui/generic-associated-types/issue-93262.rs
new file mode 100644
index 00000000000..adc6aa8fa1a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93262.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+pub trait Trait {
+ type Assoc<'a> where Self: 'a;
+}
+
+pub trait Foo
+where
+ for<'a> T::Assoc<'a>: Clone
+{}
+
+pub struct Type;
+
+impl Foo for Type
+where
+ for<'a> T::Assoc<'a>: Clone
+{}
+
+fn main() {}