about summary refs log tree commit diff
path: root/compiler/rustc_traits
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_traits')
-rw-r--r--compiler/rustc_traits/src/lib.rs2
-rw-r--r--compiler/rustc_traits/src/type_op.rs26
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));
+}