Point at source of trait bound obligations in more places
Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). Address part of #89418.
This commit is contained in:
parent
93542a8240
commit
6b9d910639
101 changed files with 550 additions and 421 deletions
|
@ -2113,10 +2113,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
None
|
||||
},
|
||||
self.tcx.generics_of(owner.to_def_id()),
|
||||
hir.span(hir_id),
|
||||
)
|
||||
});
|
||||
|
||||
let span = match generics {
|
||||
// This is to get around the trait identity obligation, that has a `DUMMY_SP` as signal
|
||||
// for other diagnostics, so we need to recover it here.
|
||||
Some((_, _, node)) if span.is_dummy() => node,
|
||||
_ => span,
|
||||
};
|
||||
|
||||
let type_param_span = match (generics, bound_kind) {
|
||||
(Some((_, ref generics)), GenericKind::Param(ref param)) => {
|
||||
(Some((_, ref generics, _)), GenericKind::Param(ref param)) => {
|
||||
// Account for the case where `param` corresponds to `Self`,
|
||||
// which doesn't have the expected type argument.
|
||||
if !(generics.has_self && param.index == 0) {
|
||||
|
@ -2153,7 +2162,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
};
|
||||
let new_lt = generics
|
||||
.as_ref()
|
||||
.and_then(|(parent_g, g)| {
|
||||
.and_then(|(parent_g, g, _)| {
|
||||
let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char));
|
||||
let mut lts_names = g
|
||||
.params
|
||||
|
@ -2175,7 +2184,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
.unwrap_or("'lt".to_string());
|
||||
let add_lt_sugg = generics
|
||||
.as_ref()
|
||||
.and_then(|(_, g)| g.params.first())
|
||||
.and_then(|(_, g, _)| g.params.first())
|
||||
.and_then(|param| param.def_id.as_local())
|
||||
.map(|def_id| {
|
||||
(
|
||||
|
|
|
@ -192,14 +192,16 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
ObligationCauseCode::MatchImpl(parent, ..) => &parent.code,
|
||||
_ => &cause.code,
|
||||
};
|
||||
if let ObligationCauseCode::ItemObligation(item_def_id) = *code {
|
||||
if let (ObligationCauseCode::ItemObligation(item_def_id), None) =
|
||||
(code, override_error_code)
|
||||
{
|
||||
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
|
||||
// lifetime as above, but called using a fully-qualified path to the method:
|
||||
// `Foo::qux(bar)`.
|
||||
let mut v = TraitObjectVisitor(FxHashSet::default());
|
||||
v.visit_ty(param.param_ty);
|
||||
if let Some((ident, self_ty)) =
|
||||
self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0)
|
||||
self.get_impl_ident_and_self_ty_from_trait(*item_def_id, &v.0)
|
||||
{
|
||||
if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) {
|
||||
override_error_code = Some(ident);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue