parent
9832374f6e
commit
ae0e3d0511
57 changed files with 720 additions and 442 deletions
|
@ -2,12 +2,12 @@ use super::ObjectSafetyViolation;
|
|||
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
use std::fmt;
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
@ -57,7 +57,8 @@ pub fn report_object_safety_error(
|
|||
err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
|
||||
|
||||
let mut reported_violations = FxHashSet::default();
|
||||
let mut had_span_label = false;
|
||||
let mut multi_span = vec![];
|
||||
let mut messages = vec![];
|
||||
for violation in violations {
|
||||
if let ObjectSafetyViolation::SizedSelf(sp) = &violation {
|
||||
if !sp.is_empty() {
|
||||
|
@ -71,31 +72,37 @@ pub fn report_object_safety_error(
|
|||
let msg = if trait_span.is_none() || spans.is_empty() {
|
||||
format!("the trait cannot be made into an object because {}", violation.error_msg())
|
||||
} else {
|
||||
had_span_label = true;
|
||||
format!("...because {}", violation.error_msg())
|
||||
};
|
||||
if spans.is_empty() {
|
||||
err.note(&msg);
|
||||
} else {
|
||||
for span in spans {
|
||||
err.span_label(span, &msg);
|
||||
multi_span.push(span);
|
||||
messages.push(msg.clone());
|
||||
}
|
||||
}
|
||||
match (trait_span, violation.solution()) {
|
||||
(Some(_), Some((note, None))) => {
|
||||
err.help(¬e);
|
||||
}
|
||||
(Some(_), Some((note, Some((sugg, span))))) => {
|
||||
err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable);
|
||||
}
|
||||
if trait_span.is_some() {
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
_ => {}
|
||||
violation.solution(&mut err);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let (Some(trait_span), true) = (trait_span, had_span_label) {
|
||||
err.span_label(trait_span, "this trait cannot be made into an object...");
|
||||
let has_multi_span = !multi_span.is_empty();
|
||||
let mut note_span = MultiSpan::from_spans(multi_span.clone());
|
||||
if let (Some(trait_span), true) = (trait_span, has_multi_span) {
|
||||
note_span
|
||||
.push_span_label(trait_span, "this trait cannot be made into an object...".to_string());
|
||||
}
|
||||
for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) {
|
||||
note_span.push_span_label(span, msg);
|
||||
}
|
||||
err.span_note(
|
||||
note_span,
|
||||
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
|
||||
to be resolvable dynamically; for more information visit \
|
||||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
|
||||
if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
|
||||
// Avoid emitting error caused by non-existing method (#58734)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue