Rollup merge of #54780 - scalexm:dup-predicates, r=nikomatsakis
Remove duplicate predicates in `explicit_predicates_of` I took a more brutal approach than described in #52187. I could have used the `linked_hash_map` crate but this seems overkill, especially as we need a vec storage in the end. r? @nikomatsakis
This commit is contained in:
commit
cbc9477bda
2 changed files with 36 additions and 6 deletions
|
|
@ -1637,9 +1637,39 @@ fn explicit_predicates_of<'a, 'tcx>(
|
|||
def_id: DefId,
|
||||
) -> ty::GenericPredicates<'tcx> {
|
||||
use rustc::hir::*;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
debug!("explicit_predicates_of(def_id={:?})", def_id);
|
||||
|
||||
/// A data structure with unique elements, which preserves order of insertion.
|
||||
/// Preserving the order of insertion is important here so as not to break
|
||||
/// compile-fail UI tests.
|
||||
struct UniquePredicates<'tcx> {
|
||||
predicates: Vec<(ty::Predicate<'tcx>, Span)>,
|
||||
uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>,
|
||||
}
|
||||
|
||||
impl<'tcx> UniquePredicates<'tcx> {
|
||||
fn new() -> Self {
|
||||
UniquePredicates {
|
||||
predicates: vec![],
|
||||
uniques: FxHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn push(&mut self, value: (ty::Predicate<'tcx>, Span)) {
|
||||
if self.uniques.insert(value) {
|
||||
self.predicates.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter: I) {
|
||||
for value in iter {
|
||||
self.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let node = tcx.hir.get(node_id);
|
||||
|
||||
|
|
@ -1649,7 +1679,7 @@ fn explicit_predicates_of<'a, 'tcx>(
|
|||
let icx = ItemCtxt::new(tcx, def_id);
|
||||
let no_generics = hir::Generics::empty();
|
||||
|
||||
let mut predicates = vec![];
|
||||
let mut predicates = UniquePredicates::new();
|
||||
|
||||
let ast_generics = match node {
|
||||
Node::TraitItem(item) => &item.generics,
|
||||
|
|
@ -1744,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>(
|
|||
// on a trait we need to add in the supertrait bounds and bounds found on
|
||||
// associated types.
|
||||
if let Some((_trait_ref, _)) = is_trait {
|
||||
predicates = tcx.super_predicates_of(def_id).predicates;
|
||||
predicates.extend(tcx.super_predicates_of(def_id).predicates);
|
||||
}
|
||||
|
||||
// In default impls, we can assume that the self type implements
|
||||
|
|
@ -1895,6 +1925,8 @@ fn explicit_predicates_of<'a, 'tcx>(
|
|||
}))
|
||||
}
|
||||
|
||||
let mut predicates = predicates.predicates;
|
||||
|
||||
// Subtle: before we store the predicates into the tcx, we
|
||||
// sort them so that predicates like `T: Foo<Item=U>` come
|
||||
// before uses of `U`. This avoids false ambiguity errors
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@ LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
|
||||
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
|
||||
= note: Implemented(Self: Bar) :- FromEnv(Self: Bar).
|
||||
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo).
|
||||
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo).
|
||||
|
||||
error: program clause dump
|
||||
--> $DIR/lower_env1.rs:19:1
|
||||
|
|
@ -16,11 +15,10 @@ LL | #[rustc_dump_env_program_clauses] //~ ERROR program clause dump
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
|
||||
= note: FromEnv(Self: Foo) :- FromEnv(Self: Bar).
|
||||
= note: Implemented(Self: Bar) :- FromEnv(Self: Bar).
|
||||
= note: Implemented(Self: Foo) :- FromEnv(Self: Foo).
|
||||
= note: Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized).
|
||||
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo), WellFormed(Self: Foo).
|
||||
= note: WellFormed(Self: Bar) :- Implemented(Self: Bar), WellFormed(Self: Foo).
|
||||
= note: WellFormed(Self: Foo) :- Implemented(Self: Foo).
|
||||
= note: WellFormed(Self: std::marker::Sized) :- Implemented(Self: std::marker::Sized).
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue