Skip to content

Commit fd7ee48

Browse files
Elaborate supertrait span correctly to label the error better
1 parent ae5f58d commit fd7ee48

5 files changed

Lines changed: 64 additions & 5 deletions

File tree

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_middle::ty::{
1313
use rustc_span::{ErrorGuaranteed,Span};
1414
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
1515
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
16+
use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
1617
use smallvec::{SmallVec, smallvec};
1718
use tracing::{debug, instrument};
1819

@@ -124,16 +125,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
124125
.into_iter()
125126
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
126127

127-
for(base_trait_ref,span)in regular_traits_refs_spans {
128+
for(base_trait_ref,original_span)in regular_traits_refs_spans {
128129
let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx);
129-
for pred in traits::elaborate(tcx,[base_pred]).filter_only_self(){
130+
forClauseWithSupertraitSpan{ pred, original_span, supertrait_span }in
131+
traits::elaborate(tcx,[ClauseWithSupertraitSpan::new(base_pred, original_span)])
132+
.filter_only_self()
133+
{
130134
debug!("observing object predicate `{pred:?}`");
131135

132136
let bound_predicate = pred.kind();
133137
match bound_predicate.skip_binder(){
134138
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
135139
let pred = bound_predicate.rebind(pred);
136-
associated_types.entry(span).or_default().extend(
140+
associated_types.entry(original_span).or_default().extend(
137141
tcx.associated_items(pred.def_id())
138142
.in_definition_order()
139143
.filter(|item| item.kind == ty::AssocKind::Type)
@@ -172,10 +176,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
172176
// the discussion in #56288 for alternatives.
173177
if !references_self {
174178
// Include projections defined on supertraits.
175-
projection_bounds.push((pred,span));
179+
projection_bounds.push((pred,original_span));
176180
}
177181

178-
self.check_elaborated_projection_mentions_input_lifetimes(pred, span);
182+
self.check_elaborated_projection_mentions_input_lifetimes(
183+
pred,
184+
original_span,
185+
supertrait_span,
186+
);
179187
}
180188
_ => (),
181189
}
@@ -371,6 +379,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
371379
&self,
372380
pred: ty::PolyProjectionPredicate<'tcx>,
373381
span:Span,
382+
supertrait_span:Span,
374383
){
375384
let tcx = self.tcx();
376385

@@ -407,6 +416,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
407416
item_name,
408417
br_name
409418
)
419+
.with_span_label(supertrait_span,"due to this supertrait")
410420
},
411421
);
412422
}

‎compiler/rustc_middle/src/ty/predicate.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ pub struct Clause<'tcx>(
179179
);
180180

181181
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>>forClause<'tcx>{
182+
fnas_predicate(self) -> Predicate<'tcx>{
183+
self.as_predicate()
184+
}
185+
182186
fninstantiate_supertrait(self,tcx:TyCtxt<'tcx>,trait_ref: ty::PolyTraitRef<'tcx>) -> Self{
183187
self.instantiate_supertrait(tcx, trait_ref)
184188
}

‎compiler/rustc_type_ir/src/elaborate.rs‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,46 @@ pub trait Elaboratable<I: Interner> {
4444
) -> Self;
4545
}
4646

47+
pubstructClauseWithSupertraitSpan<I:Interner>{
48+
pubpred:I::Predicate,
49+
// Span of the original elaborated predicate.
50+
puboriginal_span:I::Span,
51+
// Span of the supertrait predicatae that lead to this clause.
52+
pubsupertrait_span:I::Span,
53+
}
54+
impl<I:Interner>ClauseWithSupertraitSpan<I>{
55+
pubfnnew(pred:I::Predicate,span:I::Span) -> Self{
56+
ClauseWithSupertraitSpan{ pred,original_span: span,supertrait_span: span }
57+
}
58+
}
59+
impl<I:Interner>Elaboratable<I>forClauseWithSupertraitSpan<I>{
60+
fnpredicate(&self) -> <IasInterner>::Predicate{
61+
self.pred
62+
}
63+
64+
fnchild(&self,clause: <IasInterner>::Clause) -> Self{
65+
ClauseWithSupertraitSpan{
66+
pred: clause.as_predicate(),
67+
original_span:self.original_span,
68+
supertrait_span:self.supertrait_span,
69+
}
70+
}
71+
72+
fnchild_with_derived_cause(
73+
&self,
74+
clause: <IasInterner>::Clause,
75+
supertrait_span: <IasInterner>::Span,
76+
_parent_trait_pred:crate::Binder<I,crate::TraitPredicate<I>>,
77+
_index:usize,
78+
) -> Self{
79+
ClauseWithSupertraitSpan{
80+
pred: clause.as_predicate(),
81+
original_span:self.original_span,
82+
supertrait_span: supertrait_span,
83+
}
84+
}
85+
}
86+
4787
pubfnelaborate<I:Interner,O:Elaboratable<I>>(
4888
cx:I,
4989
obligations:implIntoIterator<Item = O>,

‎compiler/rustc_type_ir/src/inherent.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,8 @@ pub trait Clause<I: Interner<Clause = Self>>:
460460
+ IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
461461
+ Elaboratable<I>
462462
{
463+
fnas_predicate(self) -> I::Predicate;
464+
463465
fnas_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>>{
464466
self.kind()
465467
.map_bound(|clause| iflet ty::ClauseKind::Trait(t) = clause {Some(t)}else{None})

‎tests/ui/traits/object/elaborated-predicates-unconstrained-late-bound.stderr‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0582]: binding for associated type `T` references lifetime `'a`, which does not appear in the trait input types
22
--> $DIR/elaborated-predicates-unconstrained-late-bound.rs:19:21
33
|
4+
LL | trait A<T>: B<T = T> {}
5+
| ----- due to this supertrait
6+
...
47
LL | Erase::<dyn for<'a> A<&'a _>>(x.as_str())
58
| ^^^^^^^^^^^^^^^^
69

0 commit comments

Comments
 (0)