]> git.lizzy.rs Git - rust.git/commitdiff
Revert #92191 Prefer projection candidates instead of param_env candidates for Sized...
authorJack Huey <31162821+jackh726@users.noreply.github.com>
Sun, 1 May 2022 01:00:57 +0000 (21:00 -0400)
committerJack Huey <31162821+jackh726@users.noreply.github.com>
Wed, 4 May 2022 05:55:23 +0000 (01:55 -0400)
compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
src/test/ui/generic-associated-types/bugs/issue-89352.base.stderr [new file with mode: 0644]
src/test/ui/generic-associated-types/bugs/issue-89352.rs [new file with mode: 0644]
src/test/ui/generic-associated-types/issue-89352.rs [deleted file]
src/test/ui/generic-associated-types/issue-93262.rs [new file with mode: 0644]

index dbb6c54fcd93b4962b178e35e1dec680a20083b2..07720ba71ca95138c95eb9d32fcc7df4a63b05cf 100644 (file)
@@ -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,
index e69bf6eca90ef04baaf42a32c16f8c3fd1ad48c5..9e2d0657029fd0d83c6c399b7cf3978ed5425bb3 100644 (file)
@@ -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 (file)
index 0000000..81125a7
--- /dev/null
@@ -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`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89352.rs b/src/test/ui/generic-associated-types/bugs/issue-89352.rs
new file mode 100644 (file)
index 0000000..a9f0dd0
--- /dev/null
@@ -0,0 +1,44 @@
+// 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)]
+
+use std::marker::PhantomData;
+
+pub trait GenAssoc<T> {
+    type Iter<'at>;
+    fn iter(&self) -> Self::Iter<'_>;
+    fn reborrow<'longt: 'shortt, 'shortt>(iter: Self::Iter<'longt>) -> Self::Iter<'shortt>;
+}
+
+pub struct Wrapper<'a, T: 'a, A: GenAssoc<T>> {
+    a: A::Iter<'a>,
+    _p: PhantomData<T>,
+}
+
+impl<'ai, T: 'ai, A: GenAssoc<T>> GenAssoc<T> for Wrapper<'ai, T, A>
+where
+    A::Iter<'ai>: Clone,
+{
+    type Iter<'b> = ();
+    fn iter<'s>(&'s self) -> Self::Iter<'s> {
+        let a = A::reborrow::<'ai, 's>(self.a.clone());
+    }
+
+    fn reborrow<'long: 'short, 'short>(iter: Self::Iter<'long>) -> Self::Iter<'short> {
+        ()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-89352.rs b/src/test/ui/generic-associated-types/issue-89352.rs
deleted file mode 100644 (file)
index d9c656d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// check-pass
-
-#![feature(generic_associated_types)]
-
-use std::marker::PhantomData;
-
-pub trait GenAssoc<T> {
-    type Iter<'at>;
-    fn iter(&self) -> Self::Iter<'_>;
-    fn reborrow<'longt: 'shortt, 'shortt>(iter: Self::Iter<'longt>) -> Self::Iter<'shortt>;
-}
-
-pub struct Wrapper<'a, T: 'a, A: GenAssoc<T>> {
-    a: A::Iter<'a>,
-    _p: PhantomData<T>,
-}
-
-impl<'ai, T: 'ai, A: GenAssoc<T>> GenAssoc<T> for Wrapper<'ai, T, A>
-where
-    A::Iter<'ai>: Clone,
-{
-    type Iter<'b> = ();
-    fn iter<'s>(&'s self) -> Self::Iter<'s> {
-        let a = A::reborrow::<'ai, 's>(self.a.clone());
-    }
-
-    fn reborrow<'long: 'short, 'short>(iter: Self::Iter<'long>) -> Self::Iter<'short> {
-        ()
-    }
-}
-
-fn main() {}
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 (file)
index 0000000..adc6aa8
--- /dev/null
@@ -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() {}