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:
commit
a113240b91
62 changed files with 813 additions and 195 deletions
|
@ -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!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue