Rollup merge of #90375 - yanok:master, r=lcnr

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.
This commit is contained in:
Guillaume Gomez 2021-10-30 20:30:27 +02:00 committed by GitHub
commit 06bb1ff1b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 2 deletions

View File

@ -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<'_>| cand.is_known_global() && !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.

View File

@ -0,0 +1,20 @@
// check-pass
pub trait Archive {
type Archived;
}
impl<T> Archive for Option<T> {
type Archived = ();
}
pub type Archived<T> = <T as Archive>::Archived;
pub trait Deserialize<D> {}
const ARRAY_SIZE: usize = 32;
impl<__D> Deserialize<__D> for ()
where
Option<[u8; ARRAY_SIZE]>: Archive,
Archived<Option<[u8; ARRAY_SIZE]>>: Deserialize<__D>,
{
}
fn main() {}

View File

@ -0,0 +1,21 @@
// check-pass
pub trait Archive {
type Archived;
}
impl<T> Archive for Option<T> {
type Archived = ();
}
pub type Archived<T> = <T as Archive>::Archived;
pub trait Deserialize<D> {}
const ARRAY_SIZE: usize = 32;
impl<__D> Deserialize<__D> for ()
where
Option<[u8; ARRAY_SIZE]>: Archive,
Option<[u8; ARRAY_SIZE]>: Archive,
Archived<Option<[u8; ARRAY_SIZE]>>: Deserialize<__D>,
{
}
fn main() {}