/// 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>,
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,
}
}
-#[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,
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
use syntax::abi::Abi;
use hir;
use lint;
-use util::nodemap::FxHashMap;
+use util::nodemap::{FxHashMap, FxHashSet};
struct InferredObligationsSnapshotVecDelegate<'tcx> {
phantom: PhantomData<&'tcx i32>,
// 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(
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)
}
}
}
}
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum AdtKind { Struct, Union, Enum }
bitflags! {