Skip to content

Commit 366815d

Browse files
committed
stop returning non-principal objects in issue rust-lang#33140 relate mode
Fixes rust-lang#57162.
1 parent 1b1cbba commit 366815d

File tree

2 files changed

+34
-28
lines changed

2 files changed

+34
-28
lines changed

src/librustc/ty/relate.rs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use rustc_target::spec::abi;
1818
use hir as ast;
1919
use traits;
2020

21+
use rustc_data_structures::fx::FxHashSet;
22+
2123
pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
2224

2325
#[derive(Clone, Debug)]
@@ -601,40 +603,37 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
601603
use ty::ExistentialPredicate::*;
602604

603605
let tcx = relation.tcx();
604-
let (a_buf, b_buf);
605-
let (a_norm, b_norm): (&[_], &[_]) = match relation.trait_object_mode() {
606-
TraitObjectMode::NoSquash => {
607-
(a, b)
608-
}
609-
TraitObjectMode::SquashAutoTraitsIssue33140 => {
610-
// Treat auto-trait "principal" components as equal
611-
// to the non-principal components, to make
612-
// `dyn Send+Sync = dyn Sync+Send`.
613-
let normalize = |d: &[ty::ExistentialPredicate<'tcx>]| {
614-
let mut result: Vec<_> = d.iter().map(|pi| match pi {
615-
Trait(ref a) if tcx.trait_is_auto(a.def_id) => {
616-
AutoTrait(a.def_id)
617-
},
618-
other => *other
619-
}).collect();
620-
621-
result.sort_by(|a, b| a.stable_cmp(tcx, b));
622-
result.dedup();
623-
result
624-
};
625-
626-
a_buf = normalize(a);
627-
b_buf = normalize(b);
628-
629-
(&a_buf, &b_buf)
606+
if let TraitObjectMode::SquashAutoTraitsIssue33140 = relation.trait_object_mode() {
607+
// Treat auto-trait "principal" components as equal
608+
// to the non-principal components, to make
609+
// `dyn Send+Sync = dyn Sync+Send`.
610+
//
611+
// In that case,both types will be "fully resolved" (because
612+
// auto-traits can't have type parameters or lifetimes), and we
613+
// can just return either of them - we don't perform a full
614+
// relation because that would "spread" the unnormalized types.
615+
616+
let auto_traits = |d: &[ty::ExistentialPredicate<'tcx>]| {
617+
d.iter().map(|pi| match pi {
618+
Trait(ref a) if tcx.trait_is_auto(a.def_id) => {
619+
Ok(a.def_id)
620+
},
621+
AutoTrait(def_id) => Ok(*def_id),
622+
_ => Err(()),
623+
}).collect::<Result<FxHashSet<_>, ()>>()
624+
};
625+
626+
match (&auto_traits(a), &auto_traits(b)) {
627+
(Ok(a_dids), Ok(b_dids)) if a_dids == b_dids => return Ok(a),
628+
_ => {}
630629
}
631630
};
632631

633-
if a_norm.len() != b_norm.len() {
632+
if a.len() != b.len() {
634633
return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
635634
}
636635

637-
let v = a_norm.iter().zip(b_norm.iter()).map(|(ep_a, ep_b)| {
636+
let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| {
638637
use ty::ExistentialPredicate::*;
639638
match (*ep_a, *ep_b) {
640639
(Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)),

src/test/ui/issues/issue-57162.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// compile-pass
2+
3+
trait Foo {}
4+
impl Foo for dyn Send {}
5+
6+
impl<T: Sync + Sync> Foo for T {}
7+
fn main() {}

0 commit comments

Comments
 (0)