Avoid noting cause code (which is usually misc, b/c codegen) for opaque type reveal overflow

This commit is contained in:
Michael Goulet 2022-12-06 00:19:42 +00:00
parent e940f845be
commit d2a80c1571
6 changed files with 82 additions and 51 deletions

View file

@ -70,7 +70,7 @@ pub fn codegen_select_candidate<'tcx>(
// `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization.
for err in errors {
if let FulfillmentErrorCode::CodeCycle(cycle) = err.code {
infcx.err_ctxt().report_overflow_error_cycle(&cycle);
infcx.err_ctxt().report_overflow_obligation_cycle(&cycle);
}
}
return Err(CodegenObligationError::FulfillmentError);

View file

@ -99,16 +99,12 @@ pub trait InferCtxtExt<'tcx> {
}
pub trait TypeErrCtxtExt<'tcx> {
fn report_fulfillment_errors(
&self,
errors: &[FulfillmentError<'tcx>],
body_id: Option<hir::BodyId>,
) -> ErrorGuaranteed;
fn report_overflow_error<T>(
&self,
obligation: &Obligation<'tcx, T>,
predicate: &T,
span: Span,
suggest_increasing_limit: bool,
mutate: impl FnOnce(&mut Diagnostic),
) -> !
where
T: fmt::Display
@ -116,9 +112,23 @@ pub trait TypeErrCtxtExt<'tcx> {
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
fn report_fulfillment_errors(
&self,
errors: &[FulfillmentError<'tcx>],
body_id: Option<hir::BodyId>,
) -> ErrorGuaranteed;
fn report_overflow_obligation<T>(
&self,
obligation: &Obligation<'tcx, T>,
suggest_increasing_limit: bool,
) -> !
where
T: ToPredicate<'tcx> + Clone;
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
/// The `root_obligation` parameter should be the `root_obligation` field
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
@ -458,8 +468,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
/// occurrences in any case.
fn report_overflow_error<T>(
&self,
obligation: &Obligation<'tcx, T>,
predicate: &T,
span: Span,
suggest_increasing_limit: bool,
mutate: impl FnOnce(&mut Diagnostic),
) -> !
where
T: fmt::Display
@ -467,8 +479,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
{
let predicate = self.resolve_vars_if_possible(obligation.predicate.clone());
let predicate = self.resolve_vars_if_possible(predicate.clone());
let mut pred_str = predicate.to_string();
if pred_str.len() > 50 {
// We don't need to save the type to a file, we will be talking about this type already
// in a separate note when we explain the obligation, so it will be available that way.
@ -483,7 +496,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
let mut err = struct_span_err!(
self.tcx.sess,
obligation.cause.span,
span,
E0275,
"overflow evaluating the requirement `{}`",
pred_str,
@ -493,18 +506,44 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.suggest_new_overflow_limit(&mut err);
}
mutate(&mut err);
err.emit();
self.tcx.sess.abort_if_errors();
bug!();
}
/// Reports that an overflow has occurred and halts compilation. We
/// halt compilation unconditionally because it is important that
/// overflows never be masked -- they basically represent computations
/// whose result could not be truly determined and thus we can't say
/// if the program type checks or not -- and they are unusual
/// occurrences in any case.
fn report_overflow_obligation<T>(
&self,
obligation: &Obligation<'tcx, T>,
suggest_increasing_limit: bool,
) -> !
where
T: ToPredicate<'tcx> + Clone,
{
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
let predicate = self.resolve_vars_if_possible(predicate);
self.report_overflow_error(
&predicate,
obligation.cause.span,
suggest_increasing_limit,
|err| {
self.note_obligation_cause_code(
&mut err,
&obligation.predicate,
err,
&predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
&mut Default::default(),
);
err.emit();
self.tcx.sess.abort_if_errors();
bug!();
},
);
}
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) {
@ -521,11 +560,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
/// Reports that a cycle was detected which led to overflow and halts
/// compilation. This is equivalent to `report_overflow_error` except
/// compilation. This is equivalent to `report_overflow_obligation` except
/// that we can give a more helpful error message (and, in particular,
/// we do not suggest increasing the overflow limit, which is not
/// going to help).
fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
let cycle = self.resolve_vars_if_possible(cycle.to_owned());
assert!(!cycle.is_empty());
@ -533,7 +572,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// The 'deepest' obligation is most likely to have a useful
// cause 'backtrace'
self.report_overflow_error(cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(), false);
self.report_overflow_obligation(
cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(),
false,
);
}
fn report_selection_error(
@ -1554,7 +1596,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
diag.emit();
}
FulfillmentErrorCode::CodeCycle(ref cycle) => {
self.report_overflow_error_cycle(cycle);
self.report_overflow_obligation_cycle(cycle);
}
}
}

View file

@ -298,7 +298,7 @@ pub trait TypeErrCtxtExt<'tcx> {
obligated_types: &mut Vec<Ty<'tcx>>,
seen_requirements: &mut FxHashSet<DefId>,
) where
T: fmt::Display + ToPredicate<'tcx, T>;
T: fmt::Display + ToPredicate<'tcx>;
/// Suggest to await before try: future? => future.await?
fn suggest_await_before_try(
@ -2353,7 +2353,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
obligated_types: &mut Vec<Ty<'tcx>>,
seen_requirements: &mut FxHashSet<DefId>,
) where
T: fmt::Display,
T: fmt::Display + ToPredicate<'tcx>,
{
let tcx = self.tcx;
match *cause_code {

View file

@ -504,14 +504,12 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
Reveal::All => {
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let obligation = Obligation::with_depth(
self.tcx(),
self.cause.clone(),
recursion_limit.0,
self.param_env,
ty,
self.selcx.infcx.err_ctxt().report_overflow_error(
&ty,
self.cause.span,
true,
|_| {},
);
self.selcx.infcx.err_ctxt().report_overflow_error(&obligation, true);
}
let substs = substs.fold_with(self);

View file

@ -7,7 +7,7 @@ use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::TypeErrCtxtExt;
use crate::traits::project::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use crate::traits::{ObligationCause, PredicateObligation, Reveal};
use rustc_data_structures::sso::SsoHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::traits::Normalized;
@ -214,14 +214,12 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
let substs = substs.try_fold_with(self)?;
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) {
let obligation = Obligation::with_depth(
self.tcx(),
self.cause.clone(),
recursion_limit.0,
self.param_env,
ty,
self.infcx.err_ctxt().report_overflow_error(
&ty,
self.cause.span,
true,
|_| {},
);
self.infcx.err_ctxt().report_overflow_error(&obligation, true);
}
let generic_ty = self.tcx().bound_type_of(def_id);

View file

@ -43,7 +43,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::print::{FmtPrinter, Print};
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::SubstsRef;
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
@ -1313,10 +1312,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
error_obligation: &Obligation<'tcx, T>,
) -> Result<(), OverflowError>
where
T: fmt::Display
+ TypeFoldable<'tcx>
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
T: ToPredicate<'tcx> + Clone,
{
if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
match self.query_mode {
@ -1324,7 +1320,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let Some(e) = self.infcx.tainted_by_errors() {
return Err(OverflowError::Error(e));
}
self.infcx.err_ctxt().report_overflow_error(error_obligation, true);
self.infcx.err_ctxt().report_overflow_obligation(error_obligation, true);
}
TraitQueryMode::Canonical => {
return Err(OverflowError::Canonical);
@ -1345,10 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
error_obligation: &Obligation<'tcx, V>,
) -> Result<(), OverflowError>
where
V: fmt::Display
+ TypeFoldable<'tcx>
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
<V as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
V: ToPredicate<'tcx> + Clone,
{
self.check_recursion_depth(obligation.recursion_depth, error_obligation)
}