about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-14 15:55:16 -0400
committerMichael Goulet <michael@errs.io>2024-10-04 17:15:28 -0400
commitfd7ee484f9da99120116dc560452dd551d4c6496 (patch)
tree8f9ebb4abb182cff48f1a4d93325db01ae891939 /compiler
parentae5f58d906e755bff56dd9667c1d8b13ca236286 (diff)
downloadrust-fd7ee484f9da99120116dc560452dd551d4c6496.tar.gz
rust-fd7ee484f9da99120116dc560452dd551d4c6496.zip
Elaborate supertrait span correctly to label the error better
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs20
-rw-r--r--compiler/rustc_middle/src/ty/predicate.rs4
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs40
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs2
4 files changed, 61 insertions, 5 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index f8ae9adebe3..394a263fbb5 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -13,6 +13,7 @@ use rustc_middle::ty::{
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
 use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
+use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
 use smallvec::{SmallVec, smallvec};
 use tracing::{debug, instrument};
 
@@ -124,16 +125,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .into_iter()
             .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
 
-        for (base_trait_ref, span) in regular_traits_refs_spans {
+        for (base_trait_ref, original_span) in regular_traits_refs_spans {
             let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx);
-            for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
+            for ClauseWithSupertraitSpan { pred, original_span, supertrait_span } in
+                traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)])
+                    .filter_only_self()
+            {
                 debug!("observing object predicate `{pred:?}`");
 
                 let bound_predicate = pred.kind();
                 match bound_predicate.skip_binder() {
                     ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
                         let pred = bound_predicate.rebind(pred);
-                        associated_types.entry(span).or_default().extend(
+                        associated_types.entry(original_span).or_default().extend(
                             tcx.associated_items(pred.def_id())
                                 .in_definition_order()
                                 .filter(|item| item.kind == ty::AssocKind::Type)
@@ -172,10 +176,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // the discussion in #56288 for alternatives.
                         if !references_self {
                             // Include projections defined on supertraits.
-                            projection_bounds.push((pred, span));
+                            projection_bounds.push((pred, original_span));
                         }
 
-                        self.check_elaborated_projection_mentions_input_lifetimes(pred, span);
+                        self.check_elaborated_projection_mentions_input_lifetimes(
+                            pred,
+                            original_span,
+                            supertrait_span,
+                        );
                     }
                     _ => (),
                 }
@@ -371,6 +379,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         &self,
         pred: ty::PolyProjectionPredicate<'tcx>,
         span: Span,
+        supertrait_span: Span,
     ) {
         let tcx = self.tcx();
 
@@ -407,6 +416,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     item_name,
                     br_name
                 )
+                .with_span_label(supertrait_span, "due to this supertrait")
             },
         );
     }
diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs
index fd4e8f1cd4e..d20cb368278 100644
--- a/compiler/rustc_middle/src/ty/predicate.rs
+++ b/compiler/rustc_middle/src/ty/predicate.rs
@@ -179,6 +179,10 @@ pub struct Clause<'tcx>(
 );
 
 impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
+    fn as_predicate(self) -> Predicate<'tcx> {
+        self.as_predicate()
+    }
+
     fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
         self.instantiate_supertrait(tcx, trait_ref)
     }
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index 61736633cfa..dac45ff2aba 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -44,6 +44,46 @@ pub trait Elaboratable<I: Interner> {
     ) -> Self;
 }
 
+pub struct ClauseWithSupertraitSpan<I: Interner> {
+    pub pred: I::Predicate,
+    // Span of the original elaborated predicate.
+    pub original_span: I::Span,
+    // Span of the supertrait predicatae that lead to this clause.
+    pub supertrait_span: I::Span,
+}
+impl<I: Interner> ClauseWithSupertraitSpan<I> {
+    pub fn new(pred: I::Predicate, span: I::Span) -> Self {
+        ClauseWithSupertraitSpan { pred, original_span: span, supertrait_span: span }
+    }
+}
+impl<I: Interner> Elaboratable<I> for ClauseWithSupertraitSpan<I> {
+    fn predicate(&self) -> <I as Interner>::Predicate {
+        self.pred
+    }
+
+    fn child(&self, clause: <I as Interner>::Clause) -> Self {
+        ClauseWithSupertraitSpan {
+            pred: clause.as_predicate(),
+            original_span: self.original_span,
+            supertrait_span: self.supertrait_span,
+        }
+    }
+
+    fn child_with_derived_cause(
+        &self,
+        clause: <I as Interner>::Clause,
+        supertrait_span: <I as Interner>::Span,
+        _parent_trait_pred: crate::Binder<I, crate::TraitPredicate<I>>,
+        _index: usize,
+    ) -> Self {
+        ClauseWithSupertraitSpan {
+            pred: clause.as_predicate(),
+            original_span: self.original_span,
+            supertrait_span: supertrait_span,
+        }
+    }
+}
+
 pub fn elaborate<I: Interner, O: Elaboratable<I>>(
     cx: I,
     obligations: impl IntoIterator<Item = O>,
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 59a83ea5412..69665df4bfc 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -460,6 +460,8 @@ pub trait Clause<I: Interner<Clause = Self>>:
     + IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
     + Elaboratable<I>
 {
+    fn as_predicate(self) -> I::Predicate;
+
     fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
         self.kind()
             .map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })