]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_infer/src/traits/error_reporting/mod.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / compiler / rustc_infer / src / traits / error_reporting / mod.rs
CommitLineData
ba9703b0 1use super::ObjectSafetyViolation;
dfeec247 2
ba9703b0 3use crate::infer::InferCtxt;
487cf647 4use rustc_data_structures::fx::FxIndexSet;
04454e1e 5use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
dfeec247 6use rustc_hir as hir;
5e7ed085 7use rustc_hir::def_id::{DefId, LocalDefId};
ba9703b0 8use rustc_middle::ty::TyCtxt;
04454e1e 9use rustc_span::Span;
dfeec247 10use std::fmt;
cdc7bbd5 11use std::iter;
dfeec247 12
2b03887a 13impl<'tcx> InferCtxt<'tcx> {
dfeec247
XL
14 pub fn report_extra_impl_obligation(
15 &self,
16 error_span: Span,
5e7ed085 17 impl_item_def_id: LocalDefId,
dfeec247
XL
18 trait_item_def_id: DefId,
19 requirement: &dyn fmt::Display,
5e7ed085 20 ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
064997fb
FG
21 let mut err = struct_span_err!(
22 self.tcx.sess,
23 error_span,
24 E0276,
25 "impl has stricter requirements than trait"
26 );
dfeec247 27
064997fb 28 if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
5e7ed085 29 let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
dfeec247
XL
30 err.span_label(span, format!("definition of `{}` from trait", item_name));
31 }
32
064997fb 33 err.span_label(error_span, format!("impl has extra requirement {}", requirement));
dfeec247
XL
34
35 err
36 }
dfeec247
XL
37}
38
a2a8927a 39pub fn report_object_safety_error<'tcx>(
dfeec247
XL
40 tcx: TyCtxt<'tcx>,
41 span: Span,
42 trait_def_id: DefId,
ba9703b0 43 violations: &[ObjectSafetyViolation],
5e7ed085 44) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
dfeec247 45 let trait_str = tcx.def_path_str(trait_def_id);
74b04a01
XL
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),
48 _ => None,
49 });
dfeec247
XL
50 let mut err = struct_span_err!(
51 tcx.sess,
52 span,
53 E0038,
54 "the trait `{}` cannot be made into an object",
55 trait_str
56 );
29967ef6 57 err.span_label(span, format!("`{}` cannot be made into an object", trait_str));
dfeec247 58
487cf647 59 let mut reported_violations = FxIndexSet::default();
29967ef6
XL
60 let mut multi_span = vec![];
61 let mut messages = vec![];
dfeec247 62 for violation in violations {
5e7ed085
FG
63 if let ObjectSafetyViolation::SizedSelf(sp) = &violation && !sp.is_empty() {
64 // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations
65 // with a `Span`.
66 reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into()));
74b04a01 67 }
dfeec247 68 if reported_violations.insert(violation.clone()) {
74b04a01
XL
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())
72 } else {
74b04a01 73 format!("...because {}", violation.error_msg())
dfeec247 74 };
74b04a01
XL
75 if spans.is_empty() {
76 err.note(&msg);
77 } else {
78 for span in spans {
29967ef6
XL
79 multi_span.push(span);
80 messages.push(msg.clone());
74b04a01
XL
81 }
82 }
dfeec247
XL
83 }
84 }
29967ef6
XL
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) {
064997fb 88 note_span.push_span_label(trait_span, "this trait cannot be made into an object...");
74b04a01 89 }
cdc7bbd5 90 for (span, msg) in iter::zip(multi_span, messages) {
29967ef6
XL
91 note_span.push_span_label(span, msg);
92 }
93 err.span_note(
94 note_span,
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>",
98 );
c295e0f8
XL
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);
105 }
106 }
dfeec247
XL
107 err
108}