use crate::traits::ProjectionCacheKey;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_errors::{Diagnostic, ErrorGuaranteed};
+use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
-use rustc_middle::ty::fast_reject::{self, SimplifyParams};
+use rustc_middle::ty::fast_reject::{self, TreatParams};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef};
match project::poly_project_and_unify_type(self, &project_obligation) {
Ok(Ok(Some(mut subobligations))) => {
'compute_res: {
- // If we've previously marked this projection as 'complete', thne
+ // If we've previously marked this projection as 'complete', then
// use the final cached result (either `EvaluatedToOk` or
// `EvaluatedToOkModuloRegions`), and skip re-evaluating the
// sub-obligations.
Err(_) => Ok(EvaluatedToErr),
}
}
- (Err(ErrorHandled::Reported(ErrorGuaranteed)), _)
- | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => Ok(EvaluatedToErr),
+ (Err(ErrorHandled::Reported(_)), _)
+ | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr),
(Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => {
span_bug!(
obligation.cause.span(self.tcx()),
// the master cache. Since coherence executes pretty quickly,
// it's not worth going to more trouble to increase the
// hit-rate, I don't think.
- if self.intercrate {
+ if self.intercrate || self.allow_negative_impls {
return false;
}
// mode, so don't do any caching. In particular, we might
// re-use the same `InferCtxt` with both an intercrate
// and non-intercrate `SelectionContext`
- if self.intercrate {
+ if self.intercrate || self.allow_negative_impls {
return None;
}
let tcx = self.tcx();
fn fast_reject_trait_refs(
&mut self,
- obligation: &TraitObligation<'_>,
- impl_trait_ref: &ty::TraitRef<'_>,
+ obligation: &TraitObligation<'tcx>,
+ impl_trait_ref: &ty::TraitRef<'tcx>,
) -> bool {
// We can avoid creating type variables and doing the full
// substitution if we find that any of the input types, when
let simplified_obligation_ty = fast_reject::simplify_type(
self.tcx(),
obligation_ty,
- SimplifyParams::Yes,
+ TreatParams::AsBoundTypes,
+ );
+ let simplified_impl_ty = fast_reject::simplify_type(
+ self.tcx(),
+ impl_ty,
+ TreatParams::AsPlaceholders,
);
- let simplified_impl_ty =
- fast_reject::simplify_type(self.tcx(), impl_ty, SimplifyParams::No);
simplified_obligation_ty.is_some()
&& simplified_impl_ty.is_some()
});
}
- // 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 propagated when processing deeply nested
- // types.
- //
- // This code is hot enough that it's worth avoiding the allocation
- // required for the FxHashSet when possible. Special-casing lengths 0,
- // 1 and 2 covers roughly 75-80% of the cases.
- if obligations.len() <= 1 {
- // No possibility of duplicates.
- } else if obligations.len() == 2 {
- // Only two elements. Drop the second if they are equal.
- if obligations[0] == obligations[1] {
- obligations.truncate(1);
- }
- } else {
- // Three or more elements. Use a general deduplication process.
- let mut seen = FxHashSet::default();
- obligations.retain(|i| seen.insert(i.clone()));
- }
-
obligations
}
}