]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_traits/src/type_op.rs
Better errors for implied static bound
[rust.git] / compiler / rustc_traits / src / type_op.rs
index 60e9b88107dd698a258c044d6042436bbdb9c74a..1a63f853211ed77ba87a71df5abbaec89a6c22f4 100644 (file)
@@ -3,7 +3,7 @@
 use rustc_infer::infer::at::ToTrace;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
 use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::TraitEngineExt as _;
+use rustc_infer::traits::{ObligationCauseCode, TraitEngineExt as _};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::{GenericArg, Subst, UserSelfTy, UserSubsts};
 use rustc_middle::ty::{
@@ -22,6 +22,7 @@
 use rustc_trait_selection::traits::query::{Fallible, NoSolution};
 use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, TraitEngine};
 use std::fmt;
+use std::iter::zip;
 
 pub(crate) fn provide(p: &mut Providers) {
     *p = Providers {
@@ -61,14 +62,15 @@ pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>(
         mir_ty, def_id, user_substs
     );
 
-    let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx };
-    cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs, span)?;
+    let mut cx = AscribeUserTypeCx { infcx, param_env, span: span.unwrap_or(DUMMY_SP), fulfill_cx };
+    cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?;
     Ok(())
 }
 
 struct AscribeUserTypeCx<'me, 'tcx> {
     infcx: &'me InferCtxt<'me, 'tcx>,
     param_env: ParamEnv<'tcx>,
+    span: Span,
     fulfill_cx: &'me mut dyn TraitEngine<'tcx>,
 }
 
@@ -79,7 +81,7 @@ fn normalize<T>(&mut self, value: T) -> T
     {
         self.infcx
             .partially_normalize_associated_types_in(
-                ObligationCause::misc(DUMMY_SP, hir::CRATE_HIR_ID),
+                ObligationCause::misc(self.span, hir::CRATE_HIR_ID),
                 self.param_env,
                 value,
             )
@@ -91,18 +93,13 @@ fn relate<T>(&mut self, a: T, variance: Variance, b: T) -> Result<(), NoSolution
         T: ToTrace<'tcx>,
     {
         self.infcx
-            .at(&ObligationCause::dummy(), self.param_env)
+            .at(&ObligationCause::dummy_with_span(self.span), self.param_env)
             .relate(a, variance, b)?
             .into_value_registering_obligations(self.infcx, self.fulfill_cx);
         Ok(())
     }
 
-    fn prove_predicate(&mut self, predicate: Predicate<'tcx>, span: Option<Span>) {
-        let cause = if let Some(span) = span {
-            ObligationCause::dummy_with_span(span)
-        } else {
-            ObligationCause::dummy()
-        };
+    fn prove_predicate(&mut self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) {
         self.fulfill_cx.register_predicate_obligation(
             self.infcx,
             Obligation::new(cause, self.param_env, predicate),
@@ -126,7 +123,6 @@ fn relate_mir_and_user_ty(
         mir_ty: Ty<'tcx>,
         def_id: DefId,
         user_substs: UserSubsts<'tcx>,
-        span: Option<Span>,
     ) -> Result<(), NoSolution> {
         let UserSubsts { user_self_ty, substs } = user_substs;
         let tcx = self.tcx();
@@ -145,10 +141,20 @@ fn relate_mir_and_user_ty(
         // outlives" error messages.
         let instantiated_predicates =
             self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);
+
+        let cause = ObligationCause::dummy_with_span(self.span);
+
         debug!(?instantiated_predicates);
-        for instantiated_predicate in instantiated_predicates.predicates {
-            let instantiated_predicate = self.normalize(instantiated_predicate);
-            self.prove_predicate(instantiated_predicate, span);
+        for (instantiated_predicate, predicate_span) in
+            zip(instantiated_predicates.predicates, instantiated_predicates.spans)
+        {
+            let span = if self.span == DUMMY_SP { predicate_span } else { self.span };
+            let cause = ObligationCause::new(
+                span,
+                hir::CRATE_HIR_ID,
+                ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
+            );
+            self.prove_predicate(instantiated_predicate, cause);
         }
 
         if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
@@ -161,7 +167,7 @@ fn relate_mir_and_user_ty(
             self.prove_predicate(
                 ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()))
                     .to_predicate(self.tcx()),
-                span,
+                cause.clone(),
             );
         }
 
@@ -178,7 +184,7 @@ fn relate_mir_and_user_ty(
         // which...could happen with normalization...
         self.prove_predicate(
             ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(self.tcx()),
-            span,
+            cause,
         );
         Ok(())
     }