use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
use super::wf;
use super::DerivedObligationCause;
+use super::Normalized;
use super::Obligation;
use super::ObligationCauseCode;
use super::Selection;
use super::SelectionResult;
use super::TraitQueryMode;
-use super::{Normalized, ProjectionCacheKey};
use super::{ObligationCause, PredicateObligation, TraitObligation};
use super::{Overflow, SelectionError, Unimplemented};
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
use crate::traits::error_reporting::InferCtxtExt;
-use crate::traits::project::ProjectionCacheKeyExt;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
match project::poly_project_and_unify_type(self, &project_obligation) {
Ok(Ok(Some(mut subobligations))) => {
self.add_depth(subobligations.iter_mut(), obligation.recursion_depth);
- let result = self
- .evaluate_predicates_recursively(previous_stack, subobligations);
- if let Some(key) =
- ProjectionCacheKey::from_poly_projection_predicate(self, data)
- {
- self.infcx.inner.borrow_mut().projection_cache().complete(key);
- }
- result
+ self.evaluate_predicates_recursively(previous_stack, subobligations)
}
Ok(Ok(None)) => Ok(EvaluatedToAmbig),
Ok(Err(project::InProgress)) => Ok(EvaluatedToRecur),
it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1);
}
- /// Checks that the recursion limit has not been exceeded.
- ///
- /// The weird return type of this function allows it to be used with the `try` (`?`)
- /// operator within certain functions.
- fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>(
+ fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>(
&self,
- obligation: &Obligation<'tcx, T>,
- error_obligation: &Obligation<'tcx, V>,
+ depth: usize,
+ error_obligation: &Obligation<'tcx, T>,
) -> Result<(), OverflowError> {
- if !self.infcx.tcx.recursion_limit().value_within_limit(obligation.recursion_depth) {
+ if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
match self.query_mode {
TraitQueryMode::Standard => {
- self.infcx().report_overflow_error(error_obligation, true);
+ self.infcx.report_overflow_error(error_obligation, true);
}
TraitQueryMode::Canonical => {
return Err(OverflowError);
Ok(())
}
+ /// Checks that the recursion limit has not been exceeded.
+ ///
+ /// The weird return type of this function allows it to be used with the `try` (`?`)
+ /// operator within certain functions.
+ #[inline(always)]
+ fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>(
+ &self,
+ obligation: &Obligation<'tcx, T>,
+ error_obligation: &Obligation<'tcx, V>,
+ ) -> Result<(), OverflowError> {
+ self.check_recursion_depth(obligation.recursion_depth, error_obligation)
+ }
+
fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
where
OP: FnOnce(&mut Self) -> R,
let tcx = self.tcx();
// Respect const trait obligations
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
- if Some(obligation.predicate.skip_binder().trait_ref.def_id)
- != tcx.lang_items().sized_trait()
- // const Sized bounds are skipped
- {
- match candidate {
- // const impl
- ImplCandidate(def_id)
- if tcx.impl_constness(def_id) == hir::Constness::Const => {}
- // const param
- ParamCandidate(ty::ConstnessAnd {
- constness: ty::BoundConstness::ConstIfConst,
- ..
- }) => {}
- // auto trait impl
- AutoImplCandidate(..) => {}
- // generator, this will raise error in other places
- // or ignore error with const_async_blocks feature
- GeneratorCandidate => {}
- _ => {
- // reject all other types of candidates
- return Err(Unimplemented);
- }
+ match candidate {
+ // const impl
+ ImplCandidate(def_id) if tcx.impl_constness(def_id) == hir::Constness::Const => {}
+ // const param
+ ParamCandidate(ty::ConstnessAnd {
+ constness: ty::BoundConstness::ConstIfConst,
+ ..
+ }) => {}
+ // auto trait impl
+ AutoImplCandidate(..) => {}
+ // generator, this will raise error in other places
+ // or ignore error with const_async_blocks feature
+ GeneratorCandidate => {}
+ ConstDropCandidate => {}
+ _ => {
+ // reject all other types of candidates
+ return Err(Unimplemented);
}
}
}
(
BuiltinCandidate { has_nested: false }
| DiscriminantKindCandidate
- | PointeeCandidate,
+ | PointeeCandidate
+ | ConstDropCandidate,
_,
) => true,
(
_,
BuiltinCandidate { has_nested: false }
| DiscriminantKindCandidate
- | PointeeCandidate,
+ | PointeeCandidate
+ | ConstDropCandidate,
) => false,
(ParamCandidate(other), ParamCandidate(victim)) => {