From 1b1cbbade73cb85dabccc8632754ccf7706992a4 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Fri, 4 Jan 2019 15:27:55 +0200 Subject: [PATCH 1/2] add some debug logging to collect --- src/librustc_typeck/collect.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 9fc2f11b19738..e0e173901ef38 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1618,6 +1618,7 @@ fn predicates_defined_on<'a, 'tcx>( .predicates .extend(inferred_outlives.iter().map(|&p| (p, span))); } + debug!("predicates_defined_on({:?}) = {:?}", def_id, result); result } @@ -1645,6 +1646,7 @@ fn predicates_of<'a, 'tcx>( .predicates .push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); } + debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result } @@ -1972,10 +1974,12 @@ fn explicit_predicates_of<'a, 'tcx>( ); } - Lrc::new(ty::GenericPredicates { + let result = Lrc::new(ty::GenericPredicates { parent: generics.parent, predicates, - }) + }); + debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result); + result } pub enum SizedByDefault { From 366815d81488244277db854d3b061c7c7b2e9e4d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Fri, 4 Jan 2019 16:24:03 +0200 Subject: [PATCH 2/2] stop returning non-principal objects in issue #33140 relate mode Fixes #57162. --- src/librustc/ty/relate.rs | 55 +++++++++++++++---------------- src/test/ui/issues/issue-57162.rs | 7 ++++ 2 files changed, 34 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/issues/issue-57162.rs diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 84e15a751353e..fc467de186aec 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -18,6 +18,8 @@ use rustc_target::spec::abi; use hir as ast; use traits; +use rustc_data_structures::fx::FxHashSet; + pub type RelateResult<'tcx, T> = Result>; #[derive(Clone, Debug)] @@ -601,40 +603,37 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { use ty::ExistentialPredicate::*; let tcx = relation.tcx(); - let (a_buf, b_buf); - let (a_norm, b_norm): (&[_], &[_]) = match relation.trait_object_mode() { - TraitObjectMode::NoSquash => { - (a, b) - } - TraitObjectMode::SquashAutoTraitsIssue33140 => { - // Treat auto-trait "principal" components as equal - // to the non-principal components, to make - // `dyn Send+Sync = dyn Sync+Send`. - let normalize = |d: &[ty::ExistentialPredicate<'tcx>]| { - let mut result: Vec<_> = d.iter().map(|pi| match pi { - Trait(ref a) if tcx.trait_is_auto(a.def_id) => { - AutoTrait(a.def_id) - }, - other => *other - }).collect(); - - result.sort_by(|a, b| a.stable_cmp(tcx, b)); - result.dedup(); - result - }; - - a_buf = normalize(a); - b_buf = normalize(b); - - (&a_buf, &b_buf) + if let TraitObjectMode::SquashAutoTraitsIssue33140 = relation.trait_object_mode() { + // Treat auto-trait "principal" components as equal + // to the non-principal components, to make + // `dyn Send+Sync = dyn Sync+Send`. + // + // In that case,both types will be "fully resolved" (because + // auto-traits can't have type parameters or lifetimes), and we + // can just return either of them - we don't perform a full + // relation because that would "spread" the unnormalized types. + + let auto_traits = |d: &[ty::ExistentialPredicate<'tcx>]| { + d.iter().map(|pi| match pi { + Trait(ref a) if tcx.trait_is_auto(a.def_id) => { + Ok(a.def_id) + }, + AutoTrait(def_id) => Ok(*def_id), + _ => Err(()), + }).collect::, ()>>() + }; + + match (&auto_traits(a), &auto_traits(b)) { + (Ok(a_dids), Ok(b_dids)) if a_dids == b_dids => return Ok(a), + _ => {} } }; - if a_norm.len() != b_norm.len() { + if a.len() != b.len() { return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))); } - let v = a_norm.iter().zip(b_norm.iter()).map(|(ep_a, ep_b)| { + let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| { use ty::ExistentialPredicate::*; match (*ep_a, *ep_b) { (Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)), diff --git a/src/test/ui/issues/issue-57162.rs b/src/test/ui/issues/issue-57162.rs new file mode 100644 index 0000000000000..abe0887e927b5 --- /dev/null +++ b/src/test/ui/issues/issue-57162.rs @@ -0,0 +1,7 @@ +// compile-pass + +trait Foo {} +impl Foo for dyn Send {} + +impl Foo for T {} +fn main() {}