1
Fork 0

Rollup merge of #83689 - estebank:cool-bears-hot-tip, r=davidtwco

Add more info for common trait resolution and async/await errors

* Suggest `Pin::new`/`Box::new`/`Arc::new`/`Box::pin` in more cases
* Point at `impl` and type defs introducing requirements on E0277
This commit is contained in:
Dylan DPC 2021-04-08 01:01:43 +02:00 committed by GitHub
commit a113240b91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 813 additions and 195 deletions

View file

@ -2070,7 +2070,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Don't print the tuple of capture types
if !is_upvar_tys_infer_tuple {
err.note(&format!("required because it appears within the type `{}`", ty));
let msg = format!("required because it appears within the type `{}`", ty);
match ty.kind() {
ty::Adt(def, _) => match self.tcx.opt_item_name(def.did) {
Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&msg),
},
_ => err.note(&msg),
};
}
obligated_types.push(ty);
@ -2092,11 +2099,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
ObligationCauseCode::ImplDerivedObligation(ref data) => {
let mut parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
let parent_def_id = parent_trait_ref.def_id();
err.note(&format!(
let msg = format!(
"required because of the requirements on the impl of `{}` for `{}`",
parent_trait_ref.print_only_trait_path(),
parent_trait_ref.skip_binder().self_ty()
));
);
let mut candidates = vec![];
self.tcx.for_each_relevant_impl(
parent_def_id,
parent_trait_ref.self_ty().skip_binder(),
|impl_def_id| {
candidates.push(impl_def_id);
},
);
match &candidates[..] {
[def_id] => match self.tcx.hir().get_if_local(*def_id) {
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
..
})) => {
let mut spans = Vec::with_capacity(2);
if let Some(trait_ref) = of_trait {
spans.push(trait_ref.path.span);
}
spans.push(self_ty.span);
err.span_note(spans, &msg)
}
_ => err.note(&msg),
},
_ => err.note(&msg),
};
let mut parent_predicate = parent_trait_ref.without_const().to_predicate(tcx);
let mut data = data;
@ -2147,19 +2179,60 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
)
});
}
ObligationCauseCode::CompareImplMethodObligation { .. } => {
err.note(&format!(
"the requirement `{}` appears on the impl method but not on the corresponding \
trait method",
predicate
));
ObligationCauseCode::CompareImplMethodObligation {
item_name,
trait_item_def_id,
..
} => {
let msg = format!(
"the requirement `{}` appears on the impl method `{}` but not on the \
corresponding trait method",
predicate, item_name,
);
let sp = self
.tcx
.opt_item_name(trait_item_def_id)
.map(|i| i.span)
.unwrap_or_else(|| self.tcx.def_span(trait_item_def_id));
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
format!("this trait method doesn't have the requirement `{}`", predicate),
);
if let Some(ident) = self
.tcx
.opt_associated_item(trait_item_def_id)
.and_then(|i| self.tcx.opt_item_name(i.container.id()))
{
assoc_span.push_span_label(ident.span, "in this trait".into());
}
err.span_note(assoc_span, &msg);
}
ObligationCauseCode::CompareImplTypeObligation { .. } => {
err.note(&format!(
"the requirement `{}` appears on the associated impl type but not on the \
ObligationCauseCode::CompareImplTypeObligation {
item_name, trait_item_def_id, ..
} => {
let msg = format!(
"the requirement `{}` appears on the associated impl type `{}` but not on the \
corresponding associated trait type",
predicate
));
predicate, item_name,
);
let sp = self.tcx.def_span(trait_item_def_id);
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
format!(
"this trait associated type doesn't have the requirement `{}`",
predicate,
),
);
if let Some(ident) = self
.tcx
.opt_associated_item(trait_item_def_id)
.and_then(|i| self.tcx.opt_item_name(i.container.id()))
{
assoc_span.push_span_label(ident.span, "in this trait".into());
}
err.span_note(assoc_span, &msg);
}
ObligationCauseCode::CompareImplConstObligation => {
err.note(&format!(