about summary refs log tree commit diff
path: root/compiler/rustc_traits
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-18 15:54:59 +0000
committerbors <bors@rust-lang.org>2021-08-18 15:54:59 +0000
commit3d0774d0dc98084d25d95cc1909a8051ebbd9cb1 (patch)
treefc3a58189d33e8a6044f15dcd7705bc3f79be7b6 /compiler/rustc_traits
parent29d61427ac47dc16c83e1c66b929b1198a3ccc35 (diff)
parent8343806ff5d130f2ad8e0bc9814694864dcb5397 (diff)
downloadrust-3d0774d0dc98084d25d95cc1909a8051ebbd9cb1.tar.gz
rust-3d0774d0dc98084d25d95cc1909a8051ebbd9cb1.zip
Auto merge of #86700 - lqd:matthews-nll-hrtb-errors, r=nikomatsakis
Matthew's work on improving NLL's "higher-ranked subtype error"s

This PR rebases `@matthewjasper's` [branch](https://github.com/matthewjasper/rust/tree/nll-hrtb-errors) which has great work to fix the obscure higher-ranked subtype errors that are tracked in #57374.

These are a blocker to turning full NLLs on, and doing some internal cleanups to remove some of the old region code.

The goal is so `@nikomatsakis` can take a look at this early, and I'll then do my best to help do the changes and followup work to land this work, and move closer to turning off the migration mode.

I've only updated the branch and made it compile, removed a warning or two.

r? `@nikomatsakis`

(Here's the [zulip topic to discuss this](https://rust-lang.zulipchat.com/#narrow/stream/122657-t-compiler.2Fwg-nll/topic/.2357374.3A.20improving.20higher-ranked.20subtype.20errors.20via.20.2386700) that Niko wanted)
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));
+}