1 use super::ObjectSafetyViolation
;
3 use crate::infer
::InferCtxt
;
4 use rustc_data_structures
::fx
::FxHashSet
;
5 use rustc_errors
::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}
;
7 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
8 use rustc_middle
::ty
::TyCtxt
;
13 impl<'a
, 'tcx
> InferCtxt
<'a
, 'tcx
> {
14 pub fn report_extra_impl_obligation(
17 impl_item_def_id
: LocalDefId
,
18 trait_item_def_id
: DefId
,
19 requirement
: &dyn fmt
::Display
,
20 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
21 let mut err
= struct_span_err
!(
25 "impl has stricter requirements than trait"
28 if let Some(span
) = self.tcx
.hir().span_if_local(trait_item_def_id
) {
29 let item_name
= self.tcx
.item_name(impl_item_def_id
.to_def_id());
30 err
.span_label(span
, format
!("definition of `{}` from trait", item_name
));
33 err
.span_label(error_span
, format
!("impl has extra requirement {}", requirement
));
39 pub fn report_object_safety_error
<'tcx
>(
43 violations
: &[ObjectSafetyViolation
],
44 ) -> DiagnosticBuilder
<'tcx
, ErrorGuaranteed
> {
45 let trait_str
= tcx
.def_path_str(trait_def_id
);
46 let trait_span
= tcx
.hir().get_if_local(trait_def_id
).and_then(|node
| match node
{
47 hir
::Node
::Item(item
) => Some(item
.ident
.span
),
50 let mut err
= struct_span_err
!(
54 "the trait `{}` cannot be made into an object",
57 err
.span_label(span
, format
!("`{}` cannot be made into an object", trait_str
));
59 let mut reported_violations
= FxHashSet
::default();
60 let mut multi_span
= vec
![];
61 let mut messages
= vec
![];
62 for violation
in violations
{
63 if let ObjectSafetyViolation
::SizedSelf(sp
) = &violation
&& !sp
.is_empty() {
64 // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations
66 reported_violations
.insert(ObjectSafetyViolation
::SizedSelf(vec
![].into()));
68 if reported_violations
.insert(violation
.clone()) {
69 let spans
= violation
.spans();
70 let msg
= if trait_span
.is_none() || spans
.is_empty() {
71 format
!("the trait cannot be made into an object because {}", violation
.error_msg())
73 format
!("...because {}", violation
.error_msg())
79 multi_span
.push(span
);
80 messages
.push(msg
.clone());
85 let has_multi_span
= !multi_span
.is_empty();
86 let mut note_span
= MultiSpan
::from_spans(multi_span
.clone());
87 if let (Some(trait_span
), true) = (trait_span
, has_multi_span
) {
88 note_span
.push_span_label(trait_span
, "this trait cannot be made into an object...");
90 for (span
, msg
) in iter
::zip(multi_span
, messages
) {
91 note_span
.push_span_label(span
, msg
);
95 "for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
96 to be resolvable dynamically; for more information visit \
97 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
99 if trait_span
.is_some() {
100 let mut reported_violations
: Vec
<_
> = reported_violations
.into_iter().collect();
101 reported_violations
.sort();
102 for violation
in reported_violations
{
103 // Only provide the help if its a local trait, otherwise it's not actionable.
104 violation
.solution(&mut err
);