Rollup merge of #130116 - veera-sivarajan:freeze-suggestions, r=chenyukang

Implement a Method to Seal `DiagInner`'s Suggestions

This PR adds a method on `DiagInner` called `.seal_suggestions()` to prevent new suggestions from being added while preserving existing suggestions.

This is useful because currently there is no way to prevent new suggestions from being added to a diagnostic. `.disable_suggestions()` is the closest but it gets rid of all suggestions before and after the call.

Therefore, `.seal_suggestions()` can be used when, for example, misspelled keyword is detected and reported. In such cases, we may want to prevent other suggestions from being added to the diagnostic, as they would likely be meaningless once the misspelled keyword is identified. For context: https://github.com/rust-lang/rust/pull/129899#discussion_r1741307132

To store an additional state, the type of the `suggestions` field in `DiagInner` was changed into a three variant enum. While this change affects files across different crates, care was taken to preserve the existing code's semantics. This is validated by the fact that all UI tests pass without any modifications.

r? chenyukang
This commit is contained in:
Matthias Krüger 2024-09-18 04:42:31 +02:00 committed by GitHub
commit 09b255d3d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 102 additions and 53 deletions

View file

@ -16,7 +16,7 @@ use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{
pluralize, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult,
Subdiagnostic,
Subdiagnostic, Suggestions,
};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::edit_distance::find_best_match_for_name;
@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
}
// Check for misspelled keywords if there are no suggestions added to the diagnostic.
if err.suggestions.as_ref().is_ok_and(|code_suggestions| code_suggestions.is_empty()) {
if matches!(&err.suggestions, Suggestions::Enabled(list) if list.is_empty()) {
self.check_for_misspelled_kw(&mut err, &expected);
}
Err(err)
@ -803,6 +803,9 @@ impl<'a> Parser<'a> {
&& let Some(misspelled_kw) = find_similar_kw(curr_ident, &expected_keywords)
{
err.subdiagnostic(misspelled_kw);
// We don't want other suggestions to be added as they are most likely meaningless
// when there is a misspelled keyword.
err.seal_suggestions();
} else if let Some((prev_ident, _)) = self.prev_token.ident()
&& !prev_ident.is_used_keyword()
{
@ -818,6 +821,9 @@ impl<'a> Parser<'a> {
// positives like suggesting keyword `for` for `extern crate foo {}`.
if let Some(misspelled_kw) = find_similar_kw(prev_ident, &all_keywords) {
err.subdiagnostic(misspelled_kw);
// We don't want other suggestions to be added as they are most likely meaningless
// when there is a misspelled keyword.
err.seal_suggestions();
}
}
}