diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/fulfill.rs')
-rw-r--r-- | compiler/rustc_trait_selection/src/traits/fulfill.rs | 58 |
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, |