mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Elaborate supertrait span correctly to label the error better
This commit is contained in:
parent
ae5f58d906
commit
fd7ee484f9
@ -13,6 +13,7 @@ use rustc_middle::ty::{
|
|||||||
use rustc_span::{ErrorGuaranteed, Span};
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
|
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
|
||||||
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
|
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
|
||||||
|
use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
@ -124,16 +125,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
.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);
|
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:?}`");
|
debug!("observing object predicate `{pred:?}`");
|
||||||
|
|
||||||
let bound_predicate = pred.kind();
|
let bound_predicate = pred.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
||||||
let pred = bound_predicate.rebind(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())
|
tcx.associated_items(pred.def_id())
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||||
@ -172,10 +176,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
// the discussion in #56288 for alternatives.
|
// the discussion in #56288 for alternatives.
|
||||||
if !references_self {
|
if !references_self {
|
||||||
// Include projections defined on supertraits.
|
// 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,
|
&self,
|
||||||
pred: ty::PolyProjectionPredicate<'tcx>,
|
pred: ty::PolyProjectionPredicate<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
supertrait_span: Span,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
@ -407,6 +416,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
item_name,
|
item_name,
|
||||||
br_name
|
br_name
|
||||||
)
|
)
|
||||||
|
.with_span_label(supertrait_span, "due to this supertrait")
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -179,6 +179,10 @@ pub struct Clause<'tcx>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for 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 {
|
fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
|
||||||
self.instantiate_supertrait(tcx, trait_ref)
|
self.instantiate_supertrait(tcx, trait_ref)
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,46 @@ pub trait Elaboratable<I: Interner> {
|
|||||||
) -> Self;
|
) -> 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>>(
|
pub fn elaborate<I: Interner, O: Elaboratable<I>>(
|
||||||
cx: I,
|
cx: I,
|
||||||
obligations: impl IntoIterator<Item = O>,
|
obligations: impl IntoIterator<Item = O>,
|
||||||
|
@ -460,6 +460,8 @@ pub trait Clause<I: Interner<Clause = Self>>:
|
|||||||
+ IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
|
+ IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
|
||||||
+ Elaboratable<I>
|
+ Elaboratable<I>
|
||||||
{
|
{
|
||||||
|
fn as_predicate(self) -> I::Predicate;
|
||||||
|
|
||||||
fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
|
fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
|
||||||
self.kind()
|
self.kind()
|
||||||
.map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })
|
.map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0582]: binding for associated type `T` references lifetime `'a`, which does not appear in the trait input types
|
error[E0582]: binding for associated type `T` references lifetime `'a`, which does not appear in the trait input types
|
||||||
--> $DIR/elaborated-predicates-unconstrained-late-bound.rs:19:21
|
--> $DIR/elaborated-predicates-unconstrained-late-bound.rs:19:21
|
||||||
|
|
|
|
||||||
|
LL | trait A<T>: B<T = T> {}
|
||||||
|
| ----- due to this supertrait
|
||||||
|
...
|
||||||
LL | Erase::<dyn for<'a> A<&'a _>>(x.as_str())
|
LL | Erase::<dyn for<'a> A<&'a _>>(x.as_str())
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user