Revert #92191 Prefer projection candidates instead of param_env candidates for Sized predicates
This commit is contained in:
parent
76d4862fdd
commit
8e31cdefc4
@ -175,9 +175,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
|
|
||||||
let needs_infer = stack.obligation.predicate.has_infer_types_or_consts();
|
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
|
// If there are STILL multiple candidates, we can further
|
||||||
// reduce the list by dropping duplicates -- including
|
// reduce the list by dropping duplicates -- including
|
||||||
// resolving specializations.
|
// resolving specializations.
|
||||||
@ -186,7 +183,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
while i < candidates.len() {
|
while i < candidates.len() {
|
||||||
let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| {
|
let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| {
|
||||||
self.candidate_should_be_dropped_in_favor_of(
|
self.candidate_should_be_dropped_in_favor_of(
|
||||||
sized_predicate,
|
|
||||||
&candidates[i],
|
&candidates[i],
|
||||||
&candidates[j],
|
&candidates[j],
|
||||||
needs_infer,
|
needs_infer,
|
||||||
|
@ -1553,7 +1553,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
/// See the comment for "SelectionCandidate" for more details.
|
/// See the comment for "SelectionCandidate" for more details.
|
||||||
fn candidate_should_be_dropped_in_favor_of(
|
fn candidate_should_be_dropped_in_favor_of(
|
||||||
&mut self,
|
&mut self,
|
||||||
sized_predicate: bool,
|
|
||||||
victim: &EvaluatedCandidate<'tcx>,
|
victim: &EvaluatedCandidate<'tcx>,
|
||||||
other: &EvaluatedCandidate<'tcx>,
|
other: &EvaluatedCandidate<'tcx>,
|
||||||
needs_infer: bool,
|
needs_infer: bool,
|
||||||
@ -1625,16 +1624,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
// Drop otherwise equivalent non-const fn pointer candidates
|
// Drop otherwise equivalent non-const fn pointer candidates
|
||||||
(FnPointerCandidate { .. }, FnPointerCandidate { is_const: false }) => true,
|
(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
|
// Global bounds from the where clause should be ignored
|
||||||
// here (see issue #50825). Otherwise, we have a where
|
// here (see issue #50825). Otherwise, we have a where
|
||||||
// clause so don't go around looking for impls.
|
// clause so don't go around looking for impls.
|
||||||
@ -1650,8 +1639,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| BuiltinUnsizeCandidate
|
| BuiltinUnsizeCandidate
|
||||||
| TraitUpcastingUnsizeCandidate(_)
|
| TraitUpcastingUnsizeCandidate(_)
|
||||||
| BuiltinCandidate { .. }
|
| BuiltinCandidate { .. }
|
||||||
| TraitAliasCandidate(..),
|
| TraitAliasCandidate(..)
|
||||||
|
| ObjectCandidate(_)
|
||||||
|
| ProjectionCandidate(_),
|
||||||
) => !is_global(cand),
|
) => !is_global(cand),
|
||||||
|
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
|
||||||
|
// Prefer these to a global where-clause bound
|
||||||
|
// (see issue #50825).
|
||||||
|
is_global(cand)
|
||||||
|
}
|
||||||
(
|
(
|
||||||
ImplCandidate(_)
|
ImplCandidate(_)
|
||||||
| ClosureCandidate
|
| ClosureCandidate
|
||||||
|
@ -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 `<<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: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<T>> GenAssoc<T> for Wrapper<'ai, T, A>
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
@ -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)]
|
#![feature(generic_associated_types)]
|
||||||
|
|
21
src/test/ui/generic-associated-types/issue-93262.rs
Normal file
21
src/test/ui/generic-associated-types/issue-93262.rs
Normal file
@ -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() {}
|
Loading…
x
Reference in New Issue
Block a user