Avoid noting cause code (which is usually misc, b/c codegen) for opaque type reveal overflow
This commit is contained in:
parent
e940f845be
commit
d2a80c1571
6 changed files with 82 additions and 51 deletions
|
@ -70,7 +70,7 @@ pub fn codegen_select_candidate<'tcx>(
|
||||||
// `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization.
|
// `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization.
|
||||||
for err in errors {
|
for err in errors {
|
||||||
if let FulfillmentErrorCode::CodeCycle(cycle) = err.code {
|
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);
|
return Err(CodegenObligationError::FulfillmentError);
|
||||||
|
|
|
@ -99,16 +99,12 @@ pub trait InferCtxtExt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypeErrCtxtExt<'tcx> {
|
pub trait TypeErrCtxtExt<'tcx> {
|
||||||
fn report_fulfillment_errors(
|
|
||||||
&self,
|
|
||||||
errors: &[FulfillmentError<'tcx>],
|
|
||||||
body_id: Option<hir::BodyId>,
|
|
||||||
) -> ErrorGuaranteed;
|
|
||||||
|
|
||||||
fn report_overflow_error<T>(
|
fn report_overflow_error<T>(
|
||||||
&self,
|
&self,
|
||||||
obligation: &Obligation<'tcx, T>,
|
predicate: &T,
|
||||||
|
span: Span,
|
||||||
suggest_increasing_limit: bool,
|
suggest_increasing_limit: bool,
|
||||||
|
mutate: impl FnOnce(&mut Diagnostic),
|
||||||
) -> !
|
) -> !
|
||||||
where
|
where
|
||||||
T: fmt::Display
|
T: fmt::Display
|
||||||
|
@ -116,9 +112,23 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||||
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
|
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
|
||||||
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
|
<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 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
|
/// The `root_obligation` parameter should be the `root_obligation` field
|
||||||
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
|
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
|
||||||
|
@ -458,8 +468,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
/// occurrences in any case.
|
/// occurrences in any case.
|
||||||
fn report_overflow_error<T>(
|
fn report_overflow_error<T>(
|
||||||
&self,
|
&self,
|
||||||
obligation: &Obligation<'tcx, T>,
|
predicate: &T,
|
||||||
|
span: Span,
|
||||||
suggest_increasing_limit: bool,
|
suggest_increasing_limit: bool,
|
||||||
|
mutate: impl FnOnce(&mut Diagnostic),
|
||||||
) -> !
|
) -> !
|
||||||
where
|
where
|
||||||
T: fmt::Display
|
T: fmt::Display
|
||||||
|
@ -467,8 +479,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
|
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
|
||||||
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
|
<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();
|
let mut pred_str = predicate.to_string();
|
||||||
|
|
||||||
if pred_str.len() > 50 {
|
if pred_str.len() > 50 {
|
||||||
// We don't need to save the type to a file, we will be talking about this type already
|
// 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.
|
// 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!(
|
let mut err = struct_span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
obligation.cause.span,
|
span,
|
||||||
E0275,
|
E0275,
|
||||||
"overflow evaluating the requirement `{}`",
|
"overflow evaluating the requirement `{}`",
|
||||||
pred_str,
|
pred_str,
|
||||||
|
@ -493,20 +506,46 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
self.suggest_new_overflow_limit(&mut err);
|
self.suggest_new_overflow_limit(&mut err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.note_obligation_cause_code(
|
mutate(&mut err);
|
||||||
&mut err,
|
|
||||||
&obligation.predicate,
|
|
||||||
obligation.param_env,
|
|
||||||
obligation.cause.code(),
|
|
||||||
&mut vec![],
|
|
||||||
&mut Default::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
err.emit();
|
err.emit();
|
||||||
self.tcx.sess.abort_if_errors();
|
self.tcx.sess.abort_if_errors();
|
||||||
bug!();
|
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(
|
||||||
|
err,
|
||||||
|
&predicate,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.code(),
|
||||||
|
&mut vec![],
|
||||||
|
&mut Default::default(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) {
|
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) {
|
||||||
let suggested_limit = match self.tcx.recursion_limit() {
|
let suggested_limit = match self.tcx.recursion_limit() {
|
||||||
Limit(0) => Limit(2),
|
Limit(0) => Limit(2),
|
||||||
|
@ -521,11 +560,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reports that a cycle was detected which led to overflow and halts
|
/// 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,
|
/// that we can give a more helpful error message (and, in particular,
|
||||||
/// we do not suggest increasing the overflow limit, which is not
|
/// we do not suggest increasing the overflow limit, which is not
|
||||||
/// going to help).
|
/// 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());
|
let cycle = self.resolve_vars_if_possible(cycle.to_owned());
|
||||||
assert!(!cycle.is_empty());
|
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
|
// The 'deepest' obligation is most likely to have a useful
|
||||||
// cause 'backtrace'
|
// 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(
|
fn report_selection_error(
|
||||||
|
@ -1554,7 +1596,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
diag.emit();
|
diag.emit();
|
||||||
}
|
}
|
||||||
FulfillmentErrorCode::CodeCycle(ref cycle) => {
|
FulfillmentErrorCode::CodeCycle(ref cycle) => {
|
||||||
self.report_overflow_error_cycle(cycle);
|
self.report_overflow_obligation_cycle(cycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||||
seen_requirements: &mut FxHashSet<DefId>,
|
seen_requirements: &mut FxHashSet<DefId>,
|
||||||
) where
|
) where
|
||||||
T: fmt::Display + ToPredicate<'tcx, T>;
|
T: fmt::Display + ToPredicate<'tcx>;
|
||||||
|
|
||||||
/// Suggest to await before try: future? => future.await?
|
/// Suggest to await before try: future? => future.await?
|
||||||
fn suggest_await_before_try(
|
fn suggest_await_before_try(
|
||||||
|
@ -2353,7 +2353,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||||
seen_requirements: &mut FxHashSet<DefId>,
|
seen_requirements: &mut FxHashSet<DefId>,
|
||||||
) where
|
) where
|
||||||
T: fmt::Display,
|
T: fmt::Display + ToPredicate<'tcx>,
|
||||||
{
|
{
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
match *cause_code {
|
match *cause_code {
|
||||||
|
|
|
@ -504,14 +504,12 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
Reveal::All => {
|
Reveal::All => {
|
||||||
let recursion_limit = self.tcx().recursion_limit();
|
let recursion_limit = self.tcx().recursion_limit();
|
||||||
if !recursion_limit.value_within_limit(self.depth) {
|
if !recursion_limit.value_within_limit(self.depth) {
|
||||||
let obligation = Obligation::with_depth(
|
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||||
self.tcx(),
|
&ty,
|
||||||
self.cause.clone(),
|
self.cause.span,
|
||||||
recursion_limit.0,
|
true,
|
||||||
self.param_env,
|
|_| {},
|
||||||
ty,
|
|
||||||
);
|
);
|
||||||
self.selcx.infcx.err_ctxt().report_overflow_error(&obligation, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let substs = substs.fold_with(self);
|
let substs = substs.fold_with(self);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::infer::canonical::OriginalQueryValues;
|
||||||
use crate::infer::{InferCtxt, InferOk};
|
use crate::infer::{InferCtxt, InferOk};
|
||||||
use crate::traits::error_reporting::TypeErrCtxtExt;
|
use crate::traits::error_reporting::TypeErrCtxtExt;
|
||||||
use crate::traits::project::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
|
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::sso::SsoHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_infer::traits::Normalized;
|
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 substs = substs.try_fold_with(self)?;
|
||||||
let recursion_limit = self.tcx().recursion_limit();
|
let recursion_limit = self.tcx().recursion_limit();
|
||||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||||
let obligation = Obligation::with_depth(
|
self.infcx.err_ctxt().report_overflow_error(
|
||||||
self.tcx(),
|
&ty,
|
||||||
self.cause.clone(),
|
self.cause.span,
|
||||||
recursion_limit.0,
|
true,
|
||||||
self.param_env,
|
|_| {},
|
||||||
ty,
|
|
||||||
);
|
);
|
||||||
self.infcx.err_ctxt().report_overflow_error(&obligation, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let generic_ty = self.tcx().bound_type_of(def_id);
|
let generic_ty = self.tcx().bound_type_of(def_id);
|
||||||
|
|
|
@ -43,7 +43,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||||
use rustc_middle::ty::fold::BottomUpFolder;
|
use rustc_middle::ty::fold::BottomUpFolder;
|
||||||
use rustc_middle::ty::print::{FmtPrinter, Print};
|
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
use rustc_middle::ty::SubstsRef;
|
use rustc_middle::ty::SubstsRef;
|
||||||
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
|
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
|
||||||
|
@ -1313,10 +1312,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
error_obligation: &Obligation<'tcx, T>,
|
error_obligation: &Obligation<'tcx, T>,
|
||||||
) -> Result<(), OverflowError>
|
) -> Result<(), OverflowError>
|
||||||
where
|
where
|
||||||
T: fmt::Display
|
T: ToPredicate<'tcx> + Clone,
|
||||||
+ TypeFoldable<'tcx>
|
|
||||||
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
|
|
||||||
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
|
|
||||||
{
|
{
|
||||||
if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
|
if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
|
||||||
match self.query_mode {
|
match self.query_mode {
|
||||||
|
@ -1324,7 +1320,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
if let Some(e) = self.infcx.tainted_by_errors() {
|
if let Some(e) = self.infcx.tainted_by_errors() {
|
||||||
return Err(OverflowError::Error(e));
|
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 => {
|
TraitQueryMode::Canonical => {
|
||||||
return Err(OverflowError::Canonical);
|
return Err(OverflowError::Canonical);
|
||||||
|
@ -1345,10 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
error_obligation: &Obligation<'tcx, V>,
|
error_obligation: &Obligation<'tcx, V>,
|
||||||
) -> Result<(), OverflowError>
|
) -> Result<(), OverflowError>
|
||||||
where
|
where
|
||||||
V: fmt::Display
|
V: ToPredicate<'tcx> + Clone,
|
||||||
+ TypeFoldable<'tcx>
|
|
||||||
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
|
|
||||||
<V as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
|
|
||||||
{
|
{
|
||||||
self.check_recursion_depth(obligation.recursion_depth, error_obligation)
|
self.check_recursion_depth(obligation.recursion_depth, error_obligation)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue