Skip to content

Commit d1d4613

Browse files
authored
Rollup merge of #94391 - light4:issue-90319, r=estebank
Fix ice when error reporting recursion errors Fixes: #90319, #92148, #93955
2 parents 63b8f01 + 85e67b9 commit d1d4613

File tree

9 files changed

+66
-14
lines changed

9 files changed

+66
-14
lines changed

compiler/rustc_middle/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ pub enum SelectionError<'tcx> {
491491
/// A given constant couldn't be evaluated.
492492
NotConstEvaluatable(NotConstEvaluatable),
493493
/// Exceeded the recursion depth during type projection.
494-
Overflow,
494+
Overflow(OverflowError),
495495
/// Signaling that an error has already been emitted, to avoid
496496
/// multiple errors being shown.
497497
ErrorReporting,

compiler/rustc_middle/src/traits/select.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use self::EvaluationResult::*;
66

77
use super::{SelectionError, SelectionResult};
8+
use rustc_errors::ErrorGuaranteed;
89

910
use crate::ty;
1011

@@ -264,14 +265,26 @@ impl EvaluationResult {
264265
/// Indicates that trait evaluation caused overflow and in which pass.
265266
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
266267
pub enum OverflowError {
268+
Error(ErrorGuaranteed),
267269
Canonical,
268270
ErrorReporting,
269271
}
270272

273+
impl From<ErrorGuaranteed> for OverflowError {
274+
fn from(e: ErrorGuaranteed) -> OverflowError {
275+
OverflowError::Error(e)
276+
}
277+
}
278+
279+
TrivialTypeFoldableAndLiftImpls! {
280+
OverflowError,
281+
}
282+
271283
impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
272284
fn from(overflow_error: OverflowError) -> SelectionError<'tcx> {
273285
match overflow_error {
274-
OverflowError::Canonical => SelectionError::Overflow,
286+
OverflowError::Error(e) => SelectionError::Overflow(OverflowError::Error(e)),
287+
OverflowError::Canonical => SelectionError::Overflow(OverflowError::Canonical),
275288
OverflowError::ErrorReporting => SelectionError::ErrorReporting,
276289
}
277290
}

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_hir::GenericParam;
2222
use rustc_hir::Item;
2323
use rustc_hir::Node;
2424
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
25+
use rustc_middle::traits::select::OverflowError;
2526
use rustc_middle::ty::error::ExpectedFound;
2627
use rustc_middle::ty::fold::TypeFolder;
2728
use rustc_middle::ty::{
@@ -928,8 +929,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
928929
self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error");
929930
return;
930931
}
931-
932-
Overflow => {
932+
// Already reported.
933+
Overflow(OverflowError::Error(_)) => {
934+
self.tcx.sess.delay_span_bug(span, "`OverflowError` has been reported");
935+
return;
936+
}
937+
Overflow(_) => {
933938
bug!("overflow should be handled before the `report_selection_error` path");
934939
}
935940
SelectionError::ErrorReporting => {

compiler/rustc_trait_selection/src/traits/project.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_hir::def::DefKind;
2727
use rustc_hir::def_id::DefId;
2828
use rustc_hir::lang_items::LangItem;
2929
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
30+
use rustc_middle::traits::select::OverflowError;
3031
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
3132
use rustc_middle::ty::subst::Subst;
3233
use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
@@ -1139,7 +1140,9 @@ fn project<'cx, 'tcx>(
11391140
if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
11401141
// This should really be an immediate error, but some existing code
11411142
// relies on being able to recover from this.
1142-
return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow));
1143+
return Err(ProjectionError::TraitSelectionError(SelectionError::Overflow(
1144+
OverflowError::Canonical,
1145+
)));
11431146
}
11441147

11451148
if obligation.predicate.references_error() {

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

+2
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,11 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
108108
)
109109
}
110110
OverflowError::ErrorReporting => EvaluationResult::EvaluatedToErr,
111+
OverflowError::Error(_) => EvaluationResult::EvaluatedToErr,
111112
})
112113
}
113114
Err(OverflowError::ErrorReporting) => EvaluationResult::EvaluatedToErr,
115+
Err(OverflowError::Error(_)) => EvaluationResult::EvaluatedToErr,
114116
}
115117
}
116118
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
164164
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
165165
}
166166
Ok(_) => Ok(None),
167-
Err(OverflowError::Canonical) => Err(Overflow),
167+
Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
168168
Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
169+
Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
169170
})
170171
.flat_map(Result::transpose)
171172
.collect::<Result<Vec<_>, _>>()?;

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

+10-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::traits::project::ProjectionCacheKeyExt;
2525
use crate::traits::ProjectionCacheKey;
2626
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2727
use rustc_data_structures::stack::ensure_sufficient_stack;
28-
use rustc_errors::Diagnostic;
28+
use rustc_errors::{Diagnostic, ErrorGuaranteed};
2929
use rustc_hir as hir;
3030
use rustc_hir::def_id::DefId;
3131
use rustc_infer::infer::LateBoundRegionConversionTime;
@@ -316,11 +316,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
316316
obligation: &TraitObligation<'tcx>,
317317
) -> SelectionResult<'tcx, Selection<'tcx>> {
318318
let candidate = match self.select_from_obligation(obligation) {
319-
Err(SelectionError::Overflow) => {
319+
Err(SelectionError::Overflow(OverflowError::Canonical)) => {
320320
// In standard mode, overflow must have been caught and reported
321321
// earlier.
322322
assert!(self.query_mode == TraitQueryMode::Canonical);
323-
return Err(SelectionError::Overflow);
323+
return Err(SelectionError::Overflow(OverflowError::Canonical));
324324
}
325325
Err(SelectionError::Ambiguous(_)) => {
326326
return Ok(None);
@@ -335,9 +335,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
335335
};
336336

337337
match self.confirm_candidate(obligation, candidate) {
338-
Err(SelectionError::Overflow) => {
338+
Err(SelectionError::Overflow(OverflowError::Canonical)) => {
339339
assert!(self.query_mode == TraitQueryMode::Canonical);
340-
Err(SelectionError::Overflow)
340+
Err(SelectionError::Overflow(OverflowError::Canonical))
341341
}
342342
Err(e) => Err(e),
343343
Ok(candidate) => {
@@ -954,7 +954,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
954954
Ok(Some(c)) => self.evaluate_candidate(stack, &c),
955955
Err(SelectionError::Ambiguous(_)) => Ok(EvaluatedToAmbig),
956956
Ok(None) => Ok(EvaluatedToAmbig),
957-
Err(Overflow) => Err(OverflowError::Canonical),
957+
Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
958958
Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
959959
Err(..) => Ok(EvaluatedToErr),
960960
}
@@ -1113,7 +1113,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11131113
match self.query_mode {
11141114
TraitQueryMode::Standard => {
11151115
if self.infcx.is_tainted_by_errors() {
1116-
return Err(OverflowError::ErrorReporting);
1116+
return Err(OverflowError::Error(
1117+
ErrorGuaranteed::unchecked_claim_error_was_emitted(),
1118+
));
11171119
}
11181120
self.infcx.report_overflow_error(error_obligation, true);
11191121
}
@@ -1349,7 +1351,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13491351
}
13501352

13511353
if self.can_use_global_caches(param_env) {
1352-
if let Err(Overflow) = candidate {
1354+
if let Err(Overflow(OverflowError::Canonical)) = candidate {
13531355
// Don't cache overflow globally; we only produce this in certain modes.
13541356
} else if !pred.needs_infer() {
13551357
if !candidate.needs_infer() {

src/test/ui/typeck/issue-90319.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
struct Wrapper<T>(T);
2+
3+
trait Trait {
4+
fn method(&self) {}
5+
}
6+
7+
impl<'a, T> Trait for Wrapper<&'a T> where Wrapper<T>: Trait {}
8+
9+
fn get<T>() -> T {
10+
unimplemented!()
11+
}
12+
13+
fn main() {
14+
let thing = get::<Thing>();//~ERROR cannot find type `Thing` in this scope [E0412]
15+
let wrapper = Wrapper(thing);
16+
Trait::method(&wrapper);
17+
}

src/test/ui/typeck/issue-90319.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0412]: cannot find type `Thing` in this scope
2+
--> $DIR/issue-90319.rs:14:23
3+
|
4+
LL | let thing = get::<Thing>();
5+
| ^^^^^ not found in this scope
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)