Skip to content

Commit

Permalink
Rollup merge of rust-lang#96593 - jackh726:issue-93262, r=compiler-er…
Browse files Browse the repository at this point in the history
…rors

Revert "Prefer projection candidates instead of param_env candidates for Sized predicates"

Fixes rust-lang#93262
Reopens rust-lang#89352

This was a hack that seemed to have no negative side-effects at the time. Given that the latter has a workaround and likely less common than the former, it makes sense to revert this change.

r? `@compiler-errors`
  • Loading branch information
GuillaumeGomez authored May 2, 2022
2 parents a0e2a37 + 121c978 commit 393705b
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

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.
Expand All @@ -186,7 +183,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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,
Expand Down
20 changes: 8 additions & 12 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1553,7 +1553,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
/// 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,
Expand Down Expand Up @@ -1625,16 +1624,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// 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.
Expand All @@ -1650,8 +1639,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| 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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// check-pass
// check-fail
// 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).

#![feature(generic_associated_types)]

Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/generic-associated-types/bugs/issue-89352.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0308]: mismatched types
--> $DIR/issue-89352.rs:30:13
|
LL | let a = A::reborrow::<'ai, 's>(self.a.clone());
| ^ lifetime mismatch
|
= note: expected type `<<A as GenAssoc<T>>::Iter<'s> as Sized>`
found type `<<A as GenAssoc<T>>::Iter<'ai> as Sized>`
note: the lifetime `'s` as defined here...
--> $DIR/issue-89352.rs:29: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:24:6
|
LL | impl<'ai, T: 'ai, A: GenAssoc<T>> GenAssoc<T> for Wrapper<'ai, T, A>
| ^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
21 changes: 21 additions & 0 deletions src/test/ui/generic-associated-types/issue-93262.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// check-pass

#![feature(generic_associated_types)]

pub trait Trait {
type Assoc<'a> where Self: 'a;
}

pub trait Foo<T: Trait>
where
for<'a> T::Assoc<'a>: Clone
{}

pub struct Type;

impl<T: Trait> Foo<T> for Type
where
for<'a> T::Assoc<'a>: Clone
{}

fn main() {}

0 comments on commit 393705b

Please sign in to comment.