From 6c61db44073ce96176850ea5db5dc99624823d91 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 28 Oct 2021 12:49:46 +0000 Subject: [PATCH 1/3] Use `is_global` in `candidate_should_be_dropped_in_favor_of` This manifistated in #90195 with compiler being unable to keep one candidate for a trait impl, if where is a global impl and more than one trait bound in the where clause. Before #87280 `candidate_should_be_dropped_in_favor_of` was using `TypeFoldable::is_global()` that was enough to discard the two `ParamCandidate`s. But #87280 changed it to use `TypeFoldable::is_known_global()` instead, which is pessimistic, so now the compiler drops the global impl instead (because `is_known_global` is not sure) and then can't decide between the two `ParamCandidate`s. Switching it to use `is_global` again solves the issue. Fixes #90195. --- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1b26e38fe0e..8bd842a5e06 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1548,7 +1548,7 @@ fn candidate_should_be_dropped_in_favor_of( // the param_env so that it can be given the lowest priority. See // #50825 for the motivation for this. let is_global = - |cand: &ty::PolyTraitRef<'_>| cand.is_known_global() && !cand.has_late_bound_regions(); + |cand: &ty::PolyTraitRef<'tcx>| cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions(); // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, // and `DiscriminantKindCandidate` to anything else. From 6f942a2f4a0487a7428a9aba8f018eb45cdb924e Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 28 Oct 2021 13:23:49 +0000 Subject: [PATCH 2/3] Reformat the changed line to make tidy happy --- compiler/rustc_trait_selection/src/traits/select/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8bd842a5e06..60676ad3f4f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1547,8 +1547,9 @@ fn candidate_should_be_dropped_in_favor_of( // 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::PolyTraitRef<'tcx>| cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions(); + let is_global = |cand: &ty::PolyTraitRef<'tcx>| { + cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions() + }; // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, // and `DiscriminantKindCandidate` to anything else. From 9a0a622a042d0ed04ad349d8bb778e40dd417a16 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 28 Oct 2021 14:25:46 +0000 Subject: [PATCH 3/3] Add test cases --- src/test/ui/traits/issue-90195-2.rs | 20 ++++++++++++++++++++ src/test/ui/traits/issue-90195.rs | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/test/ui/traits/issue-90195-2.rs create mode 100644 src/test/ui/traits/issue-90195.rs diff --git a/src/test/ui/traits/issue-90195-2.rs b/src/test/ui/traits/issue-90195-2.rs new file mode 100644 index 00000000000..b739dc46e4e --- /dev/null +++ b/src/test/ui/traits/issue-90195-2.rs @@ -0,0 +1,20 @@ +// check-pass +pub trait Archive { + type Archived; +} + +impl Archive for Option { + type Archived = (); +} +pub type Archived = ::Archived; + +pub trait Deserialize {} + +const ARRAY_SIZE: usize = 32; +impl<__D> Deserialize<__D> for () +where + Option<[u8; ARRAY_SIZE]>: Archive, + Archived>: Deserialize<__D>, +{ +} +fn main() {} diff --git a/src/test/ui/traits/issue-90195.rs b/src/test/ui/traits/issue-90195.rs new file mode 100644 index 00000000000..543c9f197e1 --- /dev/null +++ b/src/test/ui/traits/issue-90195.rs @@ -0,0 +1,21 @@ +// check-pass +pub trait Archive { + type Archived; +} + +impl Archive for Option { + type Archived = (); +} +pub type Archived = ::Archived; + +pub trait Deserialize {} + +const ARRAY_SIZE: usize = 32; +impl<__D> Deserialize<__D> for () +where + Option<[u8; ARRAY_SIZE]>: Archive, + Option<[u8; ARRAY_SIZE]>: Archive, + Archived>: Deserialize<__D>, +{ +} +fn main() {}