Skip to content

Commit 8327976

Browse files
committed
Remove duplicate predicates in explicit_predicates_of
Fixes #52187.
1 parent e812ca4 commit 8327976

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

src/librustc_typeck/collect.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -1637,9 +1637,39 @@ fn explicit_predicates_of<'a, 'tcx>(
16371637
def_id: DefId,
16381638
) -> ty::GenericPredicates<'tcx> {
16391639
use rustc::hir::*;
1640+
use rustc_data_structures::fx::FxHashSet;
16401641

16411642
debug!("explicit_predicates_of(def_id={:?})", def_id);
16421643

1644+
/// A data structure with unique elements, which preserves order of insertion.
1645+
/// Preserving the order of insertion is important here so as not to break
1646+
/// compile-fail UI tests.
1647+
struct UniquePredicates<'tcx> {
1648+
predicates: Vec<(ty::Predicate<'tcx>, Span)>,
1649+
uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>,
1650+
}
1651+
1652+
impl<'tcx> UniquePredicates<'tcx> {
1653+
fn new() -> Self {
1654+
UniquePredicates {
1655+
predicates: vec![],
1656+
uniques: FxHashSet::default(),
1657+
}
1658+
}
1659+
1660+
fn push(&mut self, value: (ty::Predicate<'tcx>, Span)) {
1661+
if self.uniques.insert(value) {
1662+
self.predicates.push(value);
1663+
}
1664+
}
1665+
1666+
fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter: I) {
1667+
for value in iter {
1668+
self.push(value);
1669+
}
1670+
}
1671+
}
1672+
16431673
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
16441674
let node = tcx.hir.get(node_id);
16451675

@@ -1649,7 +1679,7 @@ fn explicit_predicates_of<'a, 'tcx>(
16491679
let icx = ItemCtxt::new(tcx, def_id);
16501680
let no_generics = hir::Generics::empty();
16511681

1652-
let mut predicates = vec![];
1682+
let mut predicates = UniquePredicates::new();
16531683

16541684
let ast_generics = match node {
16551685
Node::TraitItem(item) => &item.generics,
@@ -1744,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>(
17441774
// on a trait we need to add in the supertrait bounds and bounds found on
17451775
// associated types.
17461776
if let Some((_trait_ref, _)) = is_trait {
1747-
predicates = tcx.super_predicates_of(def_id).predicates;
1777+
predicates.extend(tcx.super_predicates_of(def_id).predicates);
17481778
}
17491779

17501780
// In default impls, we can assume that the self type implements
@@ -1895,6 +1925,8 @@ fn explicit_predicates_of<'a, 'tcx>(
18951925
}))
18961926
}
18971927

1928+
let mut predicates = predicates.predicates;
1929+
18981930
// Subtle: before we store the predicates into the tcx, we
18991931
// sort them so that predicates like `T: Foo<Item=U>` come
19001932
// before uses of `U`. This avoids false ambiguity errors

src/test/ui/chalkify/lower_env1.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
8-
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
98
= note: Implemented(Self: Bar) :- FromEnv(Self: Bar).
10-
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo).
9+
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo).
1110

1211
error: program clause dump
1312
--> $DIR/lower_env1.rs:19:1
@@ -16,11 +15,10 @@ LL | #[rustc_dump_env_program_clauses] //~ ERROR program clause dump
1615
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1716
|
1817
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
19-
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
2018
= note: Implemented(Self: Bar) :- FromEnv(Self: Bar).
2119
= note: Implemented(Self: Foo) :- FromEnv(Self: Foo).
2220
= note: Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized).
23-
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo).
21+
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo).
2422
= note: WellFormed(Self: Foo) :- Implemented(Self: Foo).
2523
= note: WellFormed(Self: std::marker::Sized) :- Implemented(Self: std::marker::Sized).
2624

0 commit comments

Comments
 (0)