-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix ErrorGuaranteed
unsoundness with stash/steal.
#120828
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -306,6 +306,12 @@ pub struct InferCtxt<'tcx> { | |
// FIXME(matthewjasper) Merge into `tainted_by_errors` | ||
err_count_on_creation: usize, | ||
|
||
/// Track how many errors were stashed when this infcx is created. | ||
/// Used for the same purpose as `err_count_on_creation`, even | ||
/// though it's weaker because the count can go up and down. | ||
// FIXME(matthewjasper) Merge into `tainted_by_errors` | ||
stashed_err_count_on_creation: usize, | ||
|
||
/// What is the innermost universe we have created? Starts out as | ||
/// `UniverseIndex::root()` but grows from there as we enter | ||
/// universal quantifiers. | ||
|
@@ -711,6 +717,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { | |
reported_signature_mismatch: Default::default(), | ||
tainted_by_errors: Cell::new(None), | ||
err_count_on_creation: tcx.dcx().err_count(), | ||
stashed_err_count_on_creation: tcx.dcx().stashed_err_count(), | ||
universe: Cell::new(ty::UniverseIndex::ROOT), | ||
intercrate, | ||
next_trait_solver, | ||
|
@@ -1261,26 +1268,24 @@ impl<'tcx> InferCtxt<'tcx> { | |
/// inference variables, regionck errors). | ||
#[must_use = "this method does not have any side effects"] | ||
pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> { | ||
debug!( | ||
"is_tainted_by_errors(err_count={}, err_count_on_creation={}, \ | ||
tainted_by_errors={})", | ||
self.dcx().err_count(), | ||
self.err_count_on_creation, | ||
self.tainted_by_errors.get().is_some() | ||
); | ||
|
||
if let Some(e) = self.tainted_by_errors.get() { | ||
return Some(e); | ||
} | ||
|
||
if self.dcx().err_count() > self.err_count_on_creation { | ||
// errors reported since this infcx was made | ||
let e = self.dcx().has_errors().unwrap(); | ||
self.set_tainted_by_errors(e); | ||
return Some(e); | ||
if let Some(guar) = self.tainted_by_errors.get() { | ||
Some(guar) | ||
} else if self.dcx().err_count() > self.err_count_on_creation { | ||
// Errors reported since this infcx was made. | ||
let guar = self.dcx().has_errors().unwrap(); | ||
self.set_tainted_by_errors(guar); | ||
Some(guar) | ||
} else if self.dcx().stashed_err_count() > self.stashed_err_count_on_creation { | ||
// Errors stashed since this infcx was made. Not entirely reliable | ||
// because the count of stashed errors can go down. But without | ||
// this case we get a moderate number of uninteresting and | ||
// extraneous "type annotations needed" errors. | ||
let guar = self.dcx().delayed_bug("tainted_by_errors: stashed bug awaiting emission"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is harder due to the stashing. I'm considering differentiating between "avoid There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC, if the we get rid of the |
||
self.set_tainted_by_errors(guar); | ||
Some(guar) | ||
} else { | ||
None | ||
} | ||
|
||
None | ||
} | ||
|
||
/// Set the "tainted by errors" flag to true. We call this when we | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am planning on getting rid of this one by correctly bubbling up errors instead.