Skip to content

Commit d2a80c1

Browse files
Avoid noting cause code (which is usually misc, b/c codegen) for opaque type reveal overflow
1 parent e940f84 commit d2a80c1

File tree

6 files changed

+80
-49
lines changed

6 files changed

+80
-49
lines changed

compiler/rustc_trait_selection/src/traits/codegen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub fn codegen_select_candidate<'tcx>(
7070
// `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization.
7171
for err in errors {
7272
if let FulfillmentErrorCode::CodeCycle(cycle) = err.code {
73-
infcx.err_ctxt().report_overflow_error_cycle(&cycle);
73+
infcx.err_ctxt().report_overflow_obligation_cycle(&cycle);
7474
}
7575
}
7676
return Err(CodegenObligationError::FulfillmentError);

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+63-21
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,36 @@ pub trait InferCtxtExt<'tcx> {
9999
}
100100

101101
pub trait TypeErrCtxtExt<'tcx> {
102+
fn report_overflow_error<T>(
103+
&self,
104+
predicate: &T,
105+
span: Span,
106+
suggest_increasing_limit: bool,
107+
mutate: impl FnOnce(&mut Diagnostic),
108+
) -> !
109+
where
110+
T: fmt::Display
111+
+ TypeFoldable<'tcx>
112+
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
113+
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
114+
102115
fn report_fulfillment_errors(
103116
&self,
104117
errors: &[FulfillmentError<'tcx>],
105118
body_id: Option<hir::BodyId>,
106119
) -> ErrorGuaranteed;
107120

108-
fn report_overflow_error<T>(
121+
fn report_overflow_obligation<T>(
109122
&self,
110123
obligation: &Obligation<'tcx, T>,
111124
suggest_increasing_limit: bool,
112125
) -> !
113126
where
114-
T: fmt::Display
115-
+ TypeFoldable<'tcx>
116-
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
117-
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
127+
T: ToPredicate<'tcx> + Clone;
118128

119129
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic);
120130

121-
fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
131+
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> !;
122132

123133
/// The `root_obligation` parameter should be the `root_obligation` field
124134
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
@@ -458,17 +468,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
458468
/// occurrences in any case.
459469
fn report_overflow_error<T>(
460470
&self,
461-
obligation: &Obligation<'tcx, T>,
471+
predicate: &T,
472+
span: Span,
462473
suggest_increasing_limit: bool,
474+
mutate: impl FnOnce(&mut Diagnostic),
463475
) -> !
464476
where
465477
T: fmt::Display
466478
+ TypeFoldable<'tcx>
467479
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
468480
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
469481
{
470-
let predicate = self.resolve_vars_if_possible(obligation.predicate.clone());
482+
let predicate = self.resolve_vars_if_possible(predicate.clone());
471483
let mut pred_str = predicate.to_string();
484+
472485
if pred_str.len() > 50 {
473486
// We don't need to save the type to a file, we will be talking about this type already
474487
// 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> {
483496
}
484497
let mut err = struct_span_err!(
485498
self.tcx.sess,
486-
obligation.cause.span,
499+
span,
487500
E0275,
488501
"overflow evaluating the requirement `{}`",
489502
pred_str,
@@ -493,20 +506,46 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
493506
self.suggest_new_overflow_limit(&mut err);
494507
}
495508

496-
self.note_obligation_cause_code(
497-
&mut err,
498-
&obligation.predicate,
499-
obligation.param_env,
500-
obligation.cause.code(),
501-
&mut vec![],
502-
&mut Default::default(),
503-
);
509+
mutate(&mut err);
504510

505511
err.emit();
506512
self.tcx.sess.abort_if_errors();
507513
bug!();
508514
}
509515

516+
/// Reports that an overflow has occurred and halts compilation. We
517+
/// halt compilation unconditionally because it is important that
518+
/// overflows never be masked -- they basically represent computations
519+
/// whose result could not be truly determined and thus we can't say
520+
/// if the program type checks or not -- and they are unusual
521+
/// occurrences in any case.
522+
fn report_overflow_obligation<T>(
523+
&self,
524+
obligation: &Obligation<'tcx, T>,
525+
suggest_increasing_limit: bool,
526+
) -> !
527+
where
528+
T: ToPredicate<'tcx> + Clone,
529+
{
530+
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
531+
let predicate = self.resolve_vars_if_possible(predicate);
532+
self.report_overflow_error(
533+
&predicate,
534+
obligation.cause.span,
535+
suggest_increasing_limit,
536+
|err| {
537+
self.note_obligation_cause_code(
538+
err,
539+
&predicate,
540+
obligation.param_env,
541+
obligation.cause.code(),
542+
&mut vec![],
543+
&mut Default::default(),
544+
);
545+
},
546+
);
547+
}
548+
510549
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) {
511550
let suggested_limit = match self.tcx.recursion_limit() {
512551
Limit(0) => Limit(2),
@@ -521,19 +560,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
521560
}
522561

523562
/// Reports that a cycle was detected which led to overflow and halts
524-
/// compilation. This is equivalent to `report_overflow_error` except
563+
/// compilation. This is equivalent to `report_overflow_obligation` except
525564
/// that we can give a more helpful error message (and, in particular,
526565
/// we do not suggest increasing the overflow limit, which is not
527566
/// going to help).
528-
fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
567+
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
529568
let cycle = self.resolve_vars_if_possible(cycle.to_owned());
530569
assert!(!cycle.is_empty());
531570

532571
debug!(?cycle, "report_overflow_error_cycle");
533572

534573
// The 'deepest' obligation is most likely to have a useful
535574
// cause 'backtrace'
536-
self.report_overflow_error(cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(), false);
575+
self.report_overflow_obligation(
576+
cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(),
577+
false,
578+
);
537579
}
538580

539581
fn report_selection_error(
@@ -1554,7 +1596,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15541596
diag.emit();
15551597
}
15561598
FulfillmentErrorCode::CodeCycle(ref cycle) => {
1557-
self.report_overflow_error_cycle(cycle);
1599+
self.report_overflow_obligation_cycle(cycle);
15581600
}
15591601
}
15601602
}

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ pub trait TypeErrCtxtExt<'tcx> {
298298
obligated_types: &mut Vec<Ty<'tcx>>,
299299
seen_requirements: &mut FxHashSet<DefId>,
300300
) where
301-
T: fmt::Display + ToPredicate<'tcx, T>;
301+
T: fmt::Display + ToPredicate<'tcx>;
302302

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

compiler/rustc_trait_selection/src/traits/project.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -504,14 +504,12 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
504504
Reveal::All => {
505505
let recursion_limit = self.tcx().recursion_limit();
506506
if !recursion_limit.value_within_limit(self.depth) {
507-
let obligation = Obligation::with_depth(
508-
self.tcx(),
509-
self.cause.clone(),
510-
recursion_limit.0,
511-
self.param_env,
512-
ty,
507+
self.selcx.infcx.err_ctxt().report_overflow_error(
508+
&ty,
509+
self.cause.span,
510+
true,
511+
|_| {},
513512
);
514-
self.selcx.infcx.err_ctxt().report_overflow_error(&obligation, true);
515513
}
516514

517515
let substs = substs.fold_with(self);

compiler/rustc_trait_selection/src/traits/query/normalize.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::infer::canonical::OriginalQueryValues;
77
use crate::infer::{InferCtxt, InferOk};
88
use crate::traits::error_reporting::TypeErrCtxtExt;
99
use crate::traits::project::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
10-
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
10+
use crate::traits::{ObligationCause, PredicateObligation, Reveal};
1111
use rustc_data_structures::sso::SsoHashMap;
1212
use rustc_data_structures::stack::ensure_sufficient_stack;
1313
use rustc_infer::traits::Normalized;
@@ -214,14 +214,12 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
214214
let substs = substs.try_fold_with(self)?;
215215
let recursion_limit = self.tcx().recursion_limit();
216216
if !recursion_limit.value_within_limit(self.anon_depth) {
217-
let obligation = Obligation::with_depth(
218-
self.tcx(),
219-
self.cause.clone(),
220-
recursion_limit.0,
221-
self.param_env,
222-
ty,
217+
self.infcx.err_ctxt().report_overflow_error(
218+
&ty,
219+
self.cause.span,
220+
true,
221+
|_| {},
223222
);
224-
self.infcx.err_ctxt().report_overflow_error(&obligation, true);
225223
}
226224

227225
let generic_ty = self.tcx().bound_type_of(def_id);

compiler/rustc_trait_selection/src/traits/select/mod.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
4343
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
4444
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
4545
use rustc_middle::ty::fold::BottomUpFolder;
46-
use rustc_middle::ty::print::{FmtPrinter, Print};
4746
use rustc_middle::ty::relate::TypeRelation;
4847
use rustc_middle::ty::SubstsRef;
4948
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
@@ -1313,18 +1312,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13131312
error_obligation: &Obligation<'tcx, T>,
13141313
) -> Result<(), OverflowError>
13151314
where
1316-
T: fmt::Display
1317-
+ TypeFoldable<'tcx>
1318-
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
1319-
<T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
1315+
T: ToPredicate<'tcx> + Clone,
13201316
{
13211317
if !self.infcx.tcx.recursion_limit().value_within_limit(depth) {
13221318
match self.query_mode {
13231319
TraitQueryMode::Standard => {
13241320
if let Some(e) = self.infcx.tainted_by_errors() {
13251321
return Err(OverflowError::Error(e));
13261322
}
1327-
self.infcx.err_ctxt().report_overflow_error(error_obligation, true);
1323+
self.infcx.err_ctxt().report_overflow_obligation(error_obligation, true);
13281324
}
13291325
TraitQueryMode::Canonical => {
13301326
return Err(OverflowError::Canonical);
@@ -1345,10 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13451341
error_obligation: &Obligation<'tcx, V>,
13461342
) -> Result<(), OverflowError>
13471343
where
1348-
V: fmt::Display
1349-
+ TypeFoldable<'tcx>
1350-
+ Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
1351-
<V as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug,
1344+
V: ToPredicate<'tcx> + Clone,
13521345
{
13531346
self.check_recursion_depth(obligation.recursion_depth, error_obligation)
13541347
}

0 commit comments

Comments
 (0)