diff options
Diffstat (limited to 'compiler/rustc_traits')
| -rw-r--r-- | compiler/rustc_traits/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/type_op.rs | 26 |
2 files changed, 22 insertions, 6 deletions
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index d0b05beb4e6..8dd7c5bdfae 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -19,6 +19,8 @@ mod normalize_erasing_regions; mod normalize_projection_ty; mod type_op; +pub use type_op::type_op_prove_predicate_with_span; + use rustc_middle::ty::query::Providers; pub fn provide(p: &mut Providers) { diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index bd0acb0e53b..c2e0a998785 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts}; use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable, Variance}; use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Predicate, ToPredicate}; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::query::normalize::AtExt; @@ -236,11 +236,25 @@ fn type_op_prove_predicate<'tcx>( canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| { - let (param_env, ProvePredicate { predicate }) = key.into_parts(); - fulfill_cx.register_predicate_obligation( - infcx, - Obligation::new(ObligationCause::dummy(), param_env, predicate), - ); + type_op_prove_predicate_with_span(infcx, fulfill_cx, key, None); Ok(()) }) } + +/// The core of the `type_op_prove_predicate` query: for diagnostics purposes in NLL HRTB errors, +/// this query can be re-run to better track the span of the obligation cause, and improve the error +/// message. Do not call directly unless you're in that very specific context. +pub fn type_op_prove_predicate_with_span<'a, 'tcx: 'a>( + infcx: &'a InferCtxt<'a, 'tcx>, + fulfill_cx: &'a mut dyn TraitEngine<'tcx>, + key: ParamEnvAnd<'tcx, ProvePredicate<'tcx>>, + span: Option<Span>, +) { + let cause = if let Some(span) = span { + ObligationCause::dummy_with_span(span) + } else { + ObligationCause::dummy() + }; + let (param_env, ProvePredicate { predicate }) = key.into_parts(); + fulfill_cx.register_predicate_obligation(infcx, Obligation::new(cause, param_env, predicate)); +} |
