}) else {
continue;
};
- let note_span = self
- .tcx
- .hir()
- .span_if_local(item.def_id)
- .or_else(|| self.tcx.hir().span_if_local(impl_did));
+
+ let note_span = if item.def_id.is_local() {
+ Some(self.tcx.def_span(item.def_id))
+ } else if impl_did.is_local() {
+ Some(self.tcx.def_span(impl_did))
+ } else {
+ None
+ };
let impl_ty = self.tcx.at(span).type_of(impl_did);
};
if let Some(note_span) = note_span {
// We have a span pointing to the method. Show note with snippet.
- err.span_note(
- self.tcx.sess.source_map().guess_head_span(note_span),
- ¬e_str,
- );
+ err.span_note(note_span, ¬e_str);
} else {
err.note(¬e_str);
}
}
CandidateSource::Trait(trait_did) => {
let Some(item) = self.associated_value(trait_did, item_name) else { continue };
- let item_span = self
- .tcx
- .sess
- .source_map()
- .guess_head_span(self.tcx.def_span(item.def_id));
+ let item_span = self.tcx.def_span(item.def_id);
let idx = if sources.len() > 1 {
let msg = &format!(
"candidate #{} is defined in the trait `{}`",
let type_param = generics.type_param(param_type, self.tcx);
Some(self.tcx.def_span(type_param.def_id))
}
- ty::Adt(def, _) if def.did().is_local() => {
- tcx.def_ident_span(def.did()).map(|span| span)
- }
+ ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
_ => None,
};
err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
}
} else if !unsatisfied_predicates.is_empty() {
- let def_span = |def_id| {
- self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
- };
let mut type_params = FxHashMap::default();
// Pick out the list of unimplemented traits on the receiver.
);
match &self_ty.kind() {
// Point at the type that couldn't satisfy the bound.
- ty::Adt(def, _) => bound_spans.push((def_span(def.did()), msg)),
+ ty::Adt(def, _) => {
+ bound_spans.push((self.tcx.def_span(def.did()), msg))
+ }
// Point at the trait object that couldn't satisfy the bound.
ty::Dynamic(preds, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
- ty::ExistentialPredicate::Trait(tr) => {
- bound_spans.push((def_span(tr.def_id), msg.clone()))
- }
+ ty::ExistentialPredicate::Trait(tr) => bound_spans
+ .push((self.tcx.def_span(tr.def_id), msg.clone())),
ty::ExistentialPredicate::Projection(_)
| ty::ExistentialPredicate::AutoTrait(_) => {}
}
}
}
// Point at the closure that couldn't satisfy the bound.
- ty::Closure(def_id, _) => bound_spans
- .push((def_span(*def_id), format!("doesn't satisfy `{}`", quiet))),
+ ty::Closure(def_id, _) => bound_spans.push((
+ tcx.def_span(*def_id),
+ format!("doesn't satisfy `{}`", quiet),
+ )),
_ => {}
}
};
// Find all the requirements that come from a local `impl` block.
let mut skip_list: FxHashSet<_> = Default::default();
let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
- for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates
+ for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates
.iter()
.filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
.filter_map(|(p, parent, c)| match c.code() {
ObligationCauseCode::ImplDerivedObligation(ref data) => {
- Some((&data.derived, p, parent, data.impl_def_id, data.span))
+ Some((&data.derived, p, parent, data.impl_def_id, data))
}
_ => None,
})
let _ = format_pred(*pred);
}
skip_list.insert(p);
- let mut spans = if cause_span != *item_span {
- let mut spans: MultiSpan = cause_span.into();
- spans.push_span_label(cause_span, unsatisfied_msg);
+ let mut spans = if cause.span != *item_span {
+ let mut spans: MultiSpan = cause.span.into();
+ spans.push_span_label(cause.span, unsatisfied_msg);
spans
} else {
ident.span.into()
// Unmet obligation coming from an `impl`.
Some(Node::Item(hir::Item {
- kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
+ kind:
+ hir::ItemKind::Impl(hir::Impl {
+ of_trait, self_ty, generics, ..
+ }),
span: item_span,
..
})) if !matches!(
Some(ExpnKind::Macro(MacroKind::Derive, _))
) =>
{
+ let sized_pred =
+ unsatisfied_predicates.iter().any(|(pred, _, _)| {
+ match pred.kind().skip_binder() {
+ ty::PredicateKind::Trait(pred) => {
+ Some(pred.def_id())
+ == self.tcx.lang_items().sized_trait()
+ && pred.polarity == ty::ImplPolarity::Positive
+ }
+ _ => false,
+ }
+ });
+ for param in generics.params {
+ if param.span == cause.span && sized_pred {
+ let (sp, sugg) = match param.colon_span {
+ Some(sp) => (sp.shrink_to_hi(), " ?Sized +"),
+ None => (param.span.shrink_to_hi(), ": ?Sized"),
+ };
+ err.span_suggestion_verbose(
+ sp,
+ "consider relaxing the type parameter's implicit \
+ `Sized` bound",
+ sugg,
+ Applicability::MachineApplicable,
+ );
+ }
+ }
if let Some(pred) = parent_p {
// Done to add the "doesn't satisfy" `span_label`.
let _ = format_pred(*pred);
}
skip_list.insert(p);
- let mut spans = if cause_span != *item_span {
- let mut spans: MultiSpan = cause_span.into();
- spans.push_span_label(cause_span, unsatisfied_msg);
+ let mut spans = if cause.span != *item_span {
+ let mut spans: MultiSpan = cause.span.into();
+ spans.push_span_label(cause.span, unsatisfied_msg);
spans
} else {
let mut spans = Vec::with_capacity(2);
_ => None,
})
.collect::<FxHashSet<_>>();
- let sm = self.tcx.sess.source_map();
let mut spans: MultiSpan = def_ids
.iter()
.filter_map(|def_id| {
let span = self.tcx.def_span(*def_id);
- if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) }
+ if span.is_dummy() { None } else { Some(span) }
})
.collect::<Vec<_>>()
.into();
for pred in &preds {
match pred.self_ty().kind() {
- ty::Adt(def, _) => {
+ ty::Adt(def, _) if def.did().is_local() => {
spans.push_span_label(
- sm.guess_head_span(self.tcx.def_span(def.did())),
+ self.tcx.def_span(def.did()),
format!("must implement `{}`", pred.trait_ref.print_only_trait_path()),
);
}
match &potential_candidates[..] {
[] => {}
[trait_info] if trait_info.def_id.is_local() => {
- let span = self.tcx.hir().span_if_local(trait_info.def_id).unwrap();
err.span_note(
- self.tcx.sess.source_map().guess_head_span(span),
+ self.tcx.def_span(trait_info.def_id),
&format!(
"`{}` defines an item `{}`, perhaps you need to {} it",
self.tcx.def_path_str(trait_info.def_id),