diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-02-26 15:21:01 +1100 | 
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-02-29 11:08:27 +1100 | 
| commit | 260ae701405f1278202de219bcdd0d60e8060da9 (patch) | |
| tree | 7506c91c08a4eb61f65e98106c8fb42e9f25d3fc /compiler/rustc_middle/src | |
| parent | ec25d6db53768a4bb68f621be3584941ac3fe416 (diff) | |
| download | rust-260ae701405f1278202de219bcdd0d60e8060da9.tar.gz rust-260ae701405f1278202de219bcdd0d60e8060da9.zip | |
Overhaul how stashed diagnostics work, again.
Stashed errors used to be counted as errors, but could then be
cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed
that, closing the soundness hole. But it introduced other difficulties
because you sometimes have to account for pending stashed errors when
making decisions about whether errors have occured/will occur and it's
easy to overlook these.
This commit aims for a middle ground.
- Stashed errors (not warnings) are counted immediately as emitted
  errors, avoiding the possibility of forgetting to consider them.
- The ability to cancel (or downgrade) stashed errors is eliminated, by
  disallowing the use of `steal_diagnostic` with errors, and introducing
  the more restrictive methods `try_steal_{modify,replace}_and_emit_err`
  that can be used instead.
Other things:
- `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both
  return `Option<ErrorGuaranteed>`, which enables the removal of two
  `delayed_bug` calls and one `Ty::new_error_with_message` call. This is
  possible because we store error guarantees in
  `DiagCtxt::stashed_diagnostics`.
- Storing the guarantees also saves us having to maintain a counter.
- Calls to the `stashed_err_count` method are no longer necessary
  alongside calls to `has_errors`, which is a nice simplification, and
  eliminates two more `span_delayed_bug` calls and one FIXME comment.
- Tests are added for three of the four fixed PRs mentioned below.
- `issue-121108.rs`'s output improved slightly, omitting a non-useful
  error message.
Fixes #121451.
Fixes #121477.
Fixes #121504.
Fixes #121508.
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/region.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 4 | 
3 files changed, 13 insertions, 15 deletions
| diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9089d992cd5..6fdb03c0bab 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -847,17 +847,15 @@ impl<'tcx> OpaqueHiddenType<'tcx> { opaque_def_id: LocalDefId, tcx: TyCtxt<'tcx>, ) -> Result<Diag<'tcx>, ErrorGuaranteed> { - if let Some(diag) = tcx - .sess - .dcx() - .steal_diagnostic(tcx.def_span(opaque_def_id), StashKey::OpaqueHiddenTypeMismatch) - { - // We used to cancel here for slightly better error messages, but - // cancelling stashed diagnostics is no longer allowed because it - // causes problems when tracking whether errors have actually - // occurred. - diag.emit(); - } + // We used to cancel here for slightly better error messages, but + // cancelling stashed diagnostics is no longer allowed because it + // causes problems when tracking whether errors have actually + // occurred. + tcx.sess.dcx().try_steal_modify_and_emit_err( + tcx.def_span(opaque_def_id), + StashKey::OpaqueHiddenTypeMismatch, + |_err| {}, + ); (self.ty, other.ty).error_reported()?; // Found different concrete types for the opaque type. let sub_diag = if self.span == other.span { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index b206727f051..51a4a9f411c 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -91,8 +91,8 @@ impl<'tcx> Region<'tcx> { /// Constructs a `RegionKind::ReError` region. #[track_caller] - pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Region<'tcx> { - tcx.intern_region(ty::ReError(reported)) + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Region<'tcx> { + tcx.intern_region(ty::ReError(guar)) } /// Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 27c78d18d19..06be8191dc4 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1528,8 +1528,8 @@ impl<'tcx> Ty<'tcx> { } /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` - pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Ty<'tcx> { - Ty::new(tcx, Error(reported)) + pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Ty<'tcx> { + Ty::new(tcx, Error(guar)) } /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` to ensure it gets used. | 
