summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/fulfill.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/fulfill.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs58
1 files changed, 38 insertions, 20 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index fb9cf51b5..045d7e444 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -1,4 +1,5 @@
use crate::infer::{InferCtxt, TyOrConstInferVar};
+use crate::traits::error_reporting::TypeErrCtxtExt;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::obligation_forest::ProcessResult;
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
@@ -115,12 +116,13 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
fn register_predicate_obligation(
&mut self,
infcx: &InferCtxt<'tcx>,
- obligation: PredicateObligation<'tcx>,
+ mut obligation: PredicateObligation<'tcx>,
) {
assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
// this helps to reduce duplicate errors, as well as making
// debug output much nicer to read and so on.
- let obligation = infcx.resolve_vars_if_possible(obligation);
+ debug_assert!(!obligation.param_env.has_non_region_infer());
+ obligation.predicate = infcx.resolve_vars_if_possible(obligation.predicate);
debug!(?obligation, "register_predicate_obligation");
@@ -350,7 +352,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
| ty::PredicateKind::ObjectSafe(_)
- | ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(_)
| ty::PredicateKind::Coerce(_)
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
@@ -360,8 +361,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
}
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
+ ty::PredicateKind::NormalizesTo(..) => {
+ bug!("NormalizesTo is only used by the new solver")
+ }
ty::PredicateKind::AliasRelate(..) => {
- bug!("AliasRelate is only used for new solver")
+ bug!("AliasRelate is only used by the new solver")
}
},
Some(pred) => match pred {
@@ -411,17 +415,30 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
}
}
- ty::PredicateKind::ClosureKind(_, closure_args, kind) => {
- match self.selcx.infcx.closure_kind(closure_args) {
- Some(closure_kind) => {
- if closure_kind.extends(kind) {
- ProcessResult::Changed(vec![])
- } else {
- ProcessResult::Error(CodeSelectionError(Unimplemented))
- }
- }
- None => ProcessResult::Unchanged,
- }
+ ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
+ ty::PredicateKind::NormalizesTo(..) => {
+ bug!("NormalizesTo is only used by the new solver")
+ }
+ ty::PredicateKind::AliasRelate(..) => {
+ bug!("AliasRelate is only used by the new solver")
+ }
+
+ // General case overflow check. Allow `process_trait_obligation`
+ // and `process_projection_obligation` to handle checking for
+ // the recursion limit themselves. Also don't check some
+ // predicate kinds that don't give further obligations.
+ _ if !self
+ .selcx
+ .tcx()
+ .recursion_limit()
+ .value_within_limit(obligation.recursion_depth) =>
+ {
+ self.selcx.infcx.err_ctxt().report_overflow_error(
+ &obligation.predicate,
+ obligation.cause.span,
+ false,
+ |_| {},
+ );
}
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
@@ -454,7 +471,12 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
ProcessResult::Unchanged
}
- Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
+ Ok(Ok(mut ok)) => {
+ for subobligation in &mut ok.obligations {
+ subobligation.set_depth_from_parent(obligation.recursion_depth);
+ }
+ ProcessResult::Changed(mk_pending(ok.obligations))
+ }
Ok(Err(err)) => {
let expected_found =
ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b);
@@ -625,10 +647,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
}
}
}
- ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
- ty::PredicateKind::AliasRelate(..) => {
- bug!("AliasRelate is only used for new solver")
- }
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
DefineOpaqueTypes::No,