Make rustc::traits::error_reporting::{recursive_type_with_infinite_size_error, report_object_safety_error} free functions.

This commit is contained in:
Camille GILLOT 2020-01-05 17:51:09 +01:00
parent d53bf7a676
commit 0b1521e6d3
5 changed files with 63 additions and 60 deletions

View file

@ -53,6 +53,7 @@ use crate::hir::map;
use crate::infer::opaque_types;
use crate::infer::{self, SuppressRegionErrors};
use crate::middle::region;
use crate::traits::error_reporting::report_object_safety_error;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
};
@ -1487,7 +1488,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let mut diag = match failure_code {
FailureCode::Error0038(did) => {
let violations = self.tcx.object_safety_violations(did);
self.tcx.report_object_safety_error(span, did, violations)
report_object_safety_error(self.tcx, span, did, violations)
}
FailureCode::Error0317(failure_str) => {
struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str)

View file

@ -916,7 +916,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty::Predicate::ObjectSafe(trait_def_id) => {
let violations = self.tcx.object_safety_violations(trait_def_id);
self.tcx.report_object_safety_error(span, trait_def_id, violations)
report_object_safety_error(self.tcx, span, trait_def_id, violations)
}
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
@ -1080,7 +1080,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
TraitNotObjectSafe(did) => {
let violations = self.tcx.object_safety_violations(did);
self.tcx.report_object_safety_error(span, did, violations)
report_object_safety_error(self.tcx, span, did, violations)
}
// already reported in the query
@ -1945,64 +1945,62 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
impl<'tcx> TyCtxt<'tcx> {
pub fn recursive_type_with_infinite_size_error(
self,
type_def_id: DefId,
) -> DiagnosticBuilder<'tcx> {
assert!(type_def_id.is_local());
let span = self.hir().span_if_local(type_def_id).unwrap();
let span = self.sess.source_map().def_span(span);
let mut err = struct_span_err!(
self.sess,
span,
E0072,
"recursive type `{}` has infinite size",
self.def_path_str(type_def_id)
);
err.span_label(span, "recursive type has infinite size");
err.help(&format!(
"insert indirection (e.g., a `Box`, `Rc`, or `&`) \
pub fn recursive_type_with_infinite_size_error(
tcx: TyCtxt<'tcx>,
type_def_id: DefId,
) -> DiagnosticBuilder<'tcx> {
assert!(type_def_id.is_local());
let span = tcx.hir().span_if_local(type_def_id).unwrap();
let span = tcx.sess.source_map().def_span(span);
let mut err = struct_span_err!(
tcx.sess,
span,
E0072,
"recursive type `{}` has infinite size",
tcx.def_path_str(type_def_id)
);
err.span_label(span, "recursive type has infinite size");
err.help(&format!(
"insert indirection (e.g., a `Box`, `Rc`, or `&`) \
at some point to make `{}` representable",
self.def_path_str(type_def_id)
));
err
tcx.def_path_str(type_def_id)
));
err
}
pub fn report_object_safety_error(
tcx: TyCtxt<'tcx>,
span: Span,
trait_def_id: DefId,
violations: Vec<ObjectSafetyViolation>,
) -> DiagnosticBuilder<'tcx> {
let trait_str = tcx.def_path_str(trait_def_id);
let span = tcx.sess.source_map().def_span(span);
let mut err = struct_span_err!(
tcx.sess,
span,
E0038,
"the trait `{}` cannot be made into an object",
trait_str
);
err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
let mut reported_violations = FxHashSet::default();
for violation in violations {
if reported_violations.insert(violation.clone()) {
match violation.span() {
Some(span) => err.span_label(span, violation.error_msg()),
None => err.note(&violation.error_msg()),
};
}
}
pub fn report_object_safety_error(
self,
span: Span,
trait_def_id: DefId,
violations: Vec<ObjectSafetyViolation>,
) -> DiagnosticBuilder<'tcx> {
let trait_str = self.def_path_str(trait_def_id);
let span = self.sess.source_map().def_span(span);
let mut err = struct_span_err!(
self.sess,
span,
E0038,
"the trait `{}` cannot be made into an object",
trait_str
);
err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
let mut reported_violations = FxHashSet::default();
for violation in violations {
if reported_violations.insert(violation.clone()) {
match violation.span() {
Some(span) => err.span_label(span, violation.error_msg()),
None => err.note(&violation.error_msg()),
};
}
}
if self.sess.trait_methods_not_found.borrow().contains(&span) {
// Avoid emitting error caused by non-existing method (#58734)
err.cancel();
}
err
if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
// Avoid emitting error caused by non-existing method (#58734)
err.cancel();
}
err
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {

View file

@ -13,6 +13,7 @@ use errors::{Applicability, DiagnosticId};
use rustc::hir::intravisit::Visitor;
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc::traits;
use rustc::traits::error_reporting::report_object_safety_error;
use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
use rustc::ty::wf::object_region_bounds;
use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
@ -1454,7 +1455,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let object_safety_violations =
tcx.astconv_object_safety_violations(item.trait_ref().def_id());
if !object_safety_violations.is_empty() {
tcx.report_object_safety_error(
report_object_safety_error(
tcx,
span,
item.trait_ref().def_id(),
object_safety_violations,

View file

@ -37,6 +37,7 @@ use errors::{Applicability, DiagnosticBuilder};
use rustc::middle::lang_items;
use rustc::session::Session;
use rustc::traits;
use rustc::traits::error_reporting::report_object_safety_error;
use rustc::ty::adjustment::AllowTwoPhase;
use rustc::ty::cast::{CastKind, CastTy};
use rustc::ty::error::TypeError;
@ -519,7 +520,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) {
let violations = fcx.tcx.object_safety_violations(did);
let mut err = fcx.tcx.report_object_safety_error(self.cast_span, did, violations);
let mut err = report_object_safety_error(fcx.tcx, self.cast_span, did, violations);
err.note(&format!("required by cast to type '{}'", fcx.ty_to_string(self.cast_ty)));
err.emit();
}

View file

@ -100,6 +100,7 @@ use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc::infer::{self, InferCtxt, InferOk, InferResult};
use rustc::middle::region;
use rustc::mir::interpret::ConstValue;
use rustc::traits::error_reporting::recursive_type_with_infinite_size_error;
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
use rustc::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
@ -2222,7 +2223,7 @@ fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: DefId) -> bool {
// caught by case 1.
match rty.is_representable(tcx, sp) {
Representability::SelfRecursive(spans) => {
let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
let mut err = recursive_type_with_infinite_size_error(tcx, item_def_id);
for span in spans {
err.span_label(span, "recursive without indirection");
}