From d3f9d71e9ee8a0518fc3696d53170f5aad009546 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 6 Apr 2022 23:51:27 -0700 Subject: [PATCH] don't consider predicates with HRTBs to be global during winnowing --- .../src/traits/select/mod.rs | 15 +++------ src/test/ui/mir/issue-95640.rs | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/mir/issue-95640.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e69bf6eca90ef..c4bf82c68f53d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1562,13 +1562,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return true; } - // Check if a bound would previously have been removed when normalizing - // the param_env so that it can be given the lowest priority. See - // #50825 for the motivation for this. - let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| { - cand.is_global() && !cand.has_late_bound_regions() - }; - // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, // `DiscriminantKindCandidate`, and `ConstDestructCandidate` to anything else. // @@ -1629,10 +1622,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // global, prefer the projection or object candidate. See issue // #50825 and #89352. (ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => { - sized_predicate || is_global(cand) + sized_predicate || cand.is_global() } (ParamCandidate(ref cand), ObjectCandidate(_) | ProjectionCandidate(_)) => { - !(sized_predicate || is_global(cand)) + !(sized_predicate || cand.is_global()) } // Global bounds from the where clause should be ignored @@ -1651,7 +1644,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | TraitUpcastingUnsizeCandidate(_) | BuiltinCandidate { .. } | TraitAliasCandidate(..), - ) => !is_global(cand), + ) => !cand.is_global(), ( ImplCandidate(_) | ClosureCandidate @@ -1666,7 +1659,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) => { // Prefer these to a global where-clause bound // (see issue #50825). - is_global(cand) && other.evaluation.must_apply_modulo_regions() + cand.is_global() && other.evaluation.must_apply_modulo_regions() } (ProjectionCandidate(i), ProjectionCandidate(j)) diff --git a/src/test/ui/mir/issue-95640.rs b/src/test/ui/mir/issue-95640.rs new file mode 100644 index 0000000000000..e4e998b5d0bb8 --- /dev/null +++ b/src/test/ui/mir/issue-95640.rs @@ -0,0 +1,31 @@ +// build-pass +// compile-flags:-Zmir-opt-level=3 + +struct D; + +trait Tr { + type It; + fn foo(self) -> Option; +} + +impl<'a> Tr for &'a D { + type It = (); + fn foo(self) -> Option<()> { + None + } +} + +fn run(f: F) +where + for<'a> &'a D: Tr, + F: Fn(<&D as Tr>::It), +{ + let d = &D; + while let Some(i) = d.foo() { + f(i); + } +} + +fn main() { + run(|_| {}); +}