Skip to content

Commit

Permalink
impl_or_trait_obligations: deduplicate obligations
Browse files Browse the repository at this point in the history
  • Loading branch information
ishitatsuyuki committed Feb 22, 2018
1 parent 619ad71 commit 5a2bec9
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/librustc/traits/mod.rs
Expand Up @@ -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>,
Expand All @@ -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,

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/traits/select.rs
Expand Up @@ -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>,
Expand Down Expand Up @@ -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(
Expand All @@ -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)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/mod.rs
Expand Up @@ -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! {
Expand Down

0 comments on commit 5a2bec9

Please sign in to comment.