Skip to content

Commit

Permalink
Rollup merge of #73485 - estebank:dedup-preds, r=nikomatsakis
Browse files Browse the repository at this point in the history
Perform obligation deduplication to avoid buggy `ExistentialMismatch`

Address #59326.
  • Loading branch information
Manishearth authored Jun 26, 2020
2 parents 38cbf15 + b7f2396 commit f13d09a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/librustc_middle/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,12 +617,22 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
a: &Self,
b: &Self,
) -> RelateResult<'tcx, Self> {
if a.len() != b.len() {
let tcx = relation.tcx();

// FIXME: this is wasteful, but want to do a perf run to see how slow it is.
// We need to perform this deduplication as we sometimes generate duplicate projections
// in `a`.
let mut a_v: Vec<_> = a.into_iter().collect();
let mut b_v: Vec<_> = b.into_iter().collect();
a_v.sort_by(|a, b| a.stable_cmp(tcx, b));
a_v.dedup();
b_v.sort_by(|a, b| a.stable_cmp(tcx, b));
b_v.dedup();
if a_v.len() != b_v.len() {
return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
}

let tcx = relation.tcx();
let v = a.iter().zip(b.iter()).map(|(ep_a, ep_b)| {
let v = a_v.into_iter().zip(b_v.into_iter()).map(|(ep_a, ep_b)| {
use crate::ty::ExistentialPredicate::*;
match (ep_a, ep_b) {
(Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)),
Expand Down
26 changes: 26 additions & 0 deletions src/test/ui/issues/issue-59326.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// check-pass
trait Service {
type S;
}

trait Framing {
type F;
}

impl Framing for () {
type F = ();
}

trait HttpService<F: Framing>: Service<S = F::F> {}

type BoxService = Box<dyn HttpService<(), S = ()>>;

fn build_server<F: FnOnce() -> BoxService>(_: F) {}

fn make_server<F: Framing>() -> Box<dyn HttpService<F, S = F::F>> {
unimplemented!()
}

fn main() {
build_server(|| make_server())
}

0 comments on commit f13d09a

Please sign in to comment.