about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRémy Rakic <remy.rakic+github@gmail.com>2021-08-15 14:49:36 +0200
committerRémy Rakic <remy.rakic+github@gmail.com>2021-08-15 14:49:36 +0200
commit2cf4b873935d418b13712da7471f9cd36676aec1 (patch)
treeda7b934ccbd5b2d0b00b45c6bc68da614a653f1e
parenta69c7cc0d57ee8c906689c3c9c0e48e2548eb500 (diff)
downloadrust-2cf4b873935d418b13712da7471f9cd36676aec1.tar.gz
rust-2cf4b873935d418b13712da7471f9cd36676aec1.zip
De-dupe NLL HRTB diagnostics' use of `type_op_prove_predicate`
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_mir/Cargo.toml1
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs15
-rw-r--r--compiler/rustc_traits/src/lib.rs2
-rw-r--r--compiler/rustc_traits/src/type_op.rs26
5 files changed, 27 insertions, 18 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 940608975c5..2d2eaf741a4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4055,6 +4055,7 @@ dependencies = [
  "rustc_span",
  "rustc_target",
  "rustc_trait_selection",
+ "rustc_traits",
  "smallvec",
  "tracing",
 ]
diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml
index ec1627f5c8a..72e3d5e564a 100644
--- a/compiler/rustc_mir/Cargo.toml
+++ b/compiler/rustc_mir/Cargo.toml
@@ -27,6 +27,7 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
+rustc_traits = { path = "../rustc_traits" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
 rustc_apfloat = { path = "../rustc_apfloat" }
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
index 103e3d9a9ad..f72a8e3a70b 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
@@ -3,12 +3,13 @@ use rustc_infer::infer::canonical::Canonical;
 use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_infer::infer::region_constraints::Constraint;
 use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
-use rustc_infer::traits::{Normalized, Obligation, ObligationCause, TraitEngine, TraitEngineExt};
+use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::type_op;
 use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _};
+use rustc_traits::type_op_prove_predicate_with_span;
 
 use std::fmt;
 use std::rc::Rc;
@@ -209,17 +210,7 @@ impl TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
     ) -> Option<DiagnosticBuilder<'tcx>> {
         tcx.infer_ctxt().enter_with_canonical(span, &self.canonical_query, |ref infcx, key, _| {
             let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
-
-            let (param_env, prove_predicate) = key.into_parts();
-            fulfill_cx.register_predicate_obligation(
-                infcx,
-                Obligation::new(
-                    ObligationCause::dummy_with_span(span),
-                    param_env,
-                    prove_predicate.predicate,
-                ),
-            );
-
+            type_op_prove_predicate_with_span(infcx, &mut *fulfill_cx, key, Some(span));
             try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
         })
     }
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 f4a0cc6767f..fe1fec9c0ab 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -10,7 +10,7 @@ use rustc_middle::ty::{
     self, FnSig, Lift, PolyFnSig, PredicateKind, 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;
@@ -247,11 +247,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));
+}