1
Fork 0

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:
Esteban Kuber 2021-10-05 23:04:09 +00:00
parent 93542a8240
commit 6b9d910639
101 changed files with 550 additions and 421 deletions

View file

@ -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| {
(

View file

@ -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);