Skip to content

Commit 1dfedd6

Browse files
authored
Rollup merge of rust-lang#105342 - compiler-errors:note_cause_code-takes-predicate, r=fee1-dead
Make `note_obligation_cause_code` take a `impl ToPredicate` for predicate The only usecase that wasn't `impl ToPredicate` was noting overflow errors while revealing opaque types, which passed in an `Obligation<'tcx, Ty<'tcx>>`... Since this only happens in a `RevealAll` environment, which is after typeck (and probably primarily within `normalize_erasing_regions`) we're unlikely to display anything useful while noting this code, evidenced by the lack of UI test changes.
2 parents 96888b9 + d2a80c1 commit 1dfedd6

File tree

9 files changed

+92
-63
lines changed

9 files changed

+92
-63
lines changed

compiler/rustc_borrowck/src/type_check/canonical.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
121121

122122
pub(super) fn prove_predicates(
123123
&mut self,
124-
predicates: impl IntoIterator<
125-
Item = impl ToPredicate<'tcx, ty::Predicate<'tcx>> + std::fmt::Debug,
126-
>,
124+
predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>,
127125
locations: Locations,
128126
category: ConstraintCategory<'tcx>,
129127
) {
@@ -135,7 +133,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
135133
#[instrument(skip(self), level = "debug")]
136134
pub(super) fn prove_predicate(
137135
&mut self,
138-
predicate: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + std::fmt::Debug,
136+
predicate: impl ToPredicate<'tcx> + std::fmt::Debug,
139137
locations: Locations,
140138
category: ConstraintCategory<'tcx>,
141139
) {

compiler/rustc_middle/src/ty/mod.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1150,8 +1150,8 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
11501150
}
11511151
}
11521152

1153-
pub trait ToPredicate<'tcx, Predicate> {
1154-
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate;
1153+
pub trait ToPredicate<'tcx, P = Predicate<'tcx>> {
1154+
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> P;
11551155
}
11561156

11571157
impl<'tcx, T> ToPredicate<'tcx, T> for T {
@@ -1160,21 +1160,21 @@ impl<'tcx, T> ToPredicate<'tcx, T> for T {
11601160
}
11611161
}
11621162

1163-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, PredicateKind<'tcx>> {
1163+
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
11641164
#[inline(always)]
11651165
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
11661166
tcx.mk_predicate(self)
11671167
}
11681168
}
11691169

1170-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Clause<'tcx> {
1170+
impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> {
11711171
#[inline(always)]
11721172
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
11731173
tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::Clause(self)))
11741174
}
11751175
}
11761176

1177-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
1177+
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
11781178
#[inline(always)]
11791179
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
11801180
let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
@@ -1193,25 +1193,25 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef
11931193
}
11941194
}
11951195

1196-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyTraitPredicate<'tcx> {
1196+
impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
11971197
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
11981198
self.map_bound(|p| PredicateKind::Clause(Clause::Trait(p))).to_predicate(tcx)
11991199
}
12001200
}
12011201

1202-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyRegionOutlivesPredicate<'tcx> {
1202+
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
12031203
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
12041204
self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
12051205
}
12061206
}
12071207

1208-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyTypeOutlivesPredicate<'tcx> {
1208+
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
12091209
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
12101210
self.map_bound(|p| PredicateKind::Clause(Clause::TypeOutlives(p))).to_predicate(tcx)
12111211
}
12121212
}
12131213

1214-
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyProjectionPredicate<'tcx> {
1214+
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
12151215
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
12161216
self.map_bound(|p| PredicateKind::Clause(Clause::Projection(p))).to_predicate(tcx)
12171217
}

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/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
150150
fn pred_known_to_hold_modulo_regions<'tcx>(
151151
infcx: &InferCtxt<'tcx>,
152152
param_env: ty::ParamEnv<'tcx>,
153-
pred: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + TypeVisitable<'tcx>,
153+
pred: impl ToPredicate<'tcx> + TypeVisitable<'tcx>,
154154
span: Span,
155155
) -> bool {
156156
let has_non_region_infer = pred.has_non_region_infer();

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)