impl_or_trait_obligations: deduplicate obligations
This commit is contained in:
parent
619ad716d1
commit
5a2bec9f45
3 changed files with 14 additions and 7 deletions
|
@ -73,7 +73,7 @@ pub enum IntercrateMode {
|
|||
/// either identifying an `impl` (e.g., `impl Eq for int`) that
|
||||
/// provides the required vtable, or else finding a bound that is in
|
||||
/// scope. The eventual result is usually a `Selection` (defined below).
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Obligation<'tcx, T> {
|
||||
pub cause: ObligationCause<'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -85,7 +85,7 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
|
|||
pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
|
||||
|
||||
/// Why did we incur this obligation? Used for error reporting.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ObligationCause<'tcx> {
|
||||
pub span: Span,
|
||||
|
||||
|
@ -113,7 +113,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ObligationCauseCode<'tcx> {
|
||||
/// Not well classified or should be obvious from span.
|
||||
MiscObligation,
|
||||
|
@ -215,7 +215,7 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
BlockTailExpression(ast::NodeId),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DerivedObligationCause<'tcx> {
|
||||
/// The trait reference of the parent obligation that led to the
|
||||
/// current obligation. Note that only trait obligations lead to
|
||||
|
|
|
@ -53,7 +53,7 @@ use std::rc::Rc;
|
|||
use syntax::abi::Abi;
|
||||
use hir;
|
||||
use lint;
|
||||
use util::nodemap::FxHashMap;
|
||||
use util::nodemap::{FxHashMap, FxHashSet};
|
||||
|
||||
struct InferredObligationsSnapshotVecDelegate<'tcx> {
|
||||
phantom: PhantomData<&'tcx i32>,
|
||||
|
@ -3282,7 +3282,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
// that order.
|
||||
let predicates = tcx.predicates_of(def_id);
|
||||
assert_eq!(predicates.parent, None);
|
||||
let predicates = predicates.predicates.iter().flat_map(|predicate| {
|
||||
let mut predicates: Vec<_> = predicates.predicates.iter().flat_map(|predicate| {
|
||||
let predicate = normalize_with_depth(self, param_env, cause.clone(), recursion_depth,
|
||||
&predicate.subst(tcx, substs));
|
||||
predicate.obligations.into_iter().chain(
|
||||
|
@ -3293,6 +3293,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
predicate: predicate.value
|
||||
}))
|
||||
}).collect();
|
||||
// We are performing deduplication here to avoid exponential blowups
|
||||
// (#38528) from happening, but the real cause of the duplication is
|
||||
// unknown. What we know is that the deduplication avoids exponential
|
||||
// amount of predicates being propogated when processing deeply nested
|
||||
// types.
|
||||
let mut seen = FxHashSet();
|
||||
predicates.retain(|i| seen.insert(i.clone()));
|
||||
self.infcx().plug_leaks(skol_map, snapshot, predicates)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1504,7 +1504,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for AdtDef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum AdtKind { Struct, Union, Enum }
|
||||
|
||||
bitflags! {
|
||||
|
|
Loading…
Reference in a new issue