Skip to content

Commit f6bcd09

Browse files
committed
Auto merge of #130498 - matthiaskrgr:rollup-tg4d0zi, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #130116 (Implement a Method to Seal `DiagInner`'s Suggestions) - #130489 (Ensure that `keyword_ident` lint doesn't trigger on `'r#kw` lifetime) - #130491 (more crash tests) - #130496 (Fix circular fn_sig queries to correct number of args for methods) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 60c3673 + c52d58d commit f6bcd09

File tree

25 files changed

+245
-54
lines changed

25 files changed

+245
-54
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_errors::emitter::Emitter;
1616
use rustc_errors::translation::Translate;
1717
use rustc_errors::{
1818
Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FluentBundle, Level, MultiSpan,
19-
Style,
19+
Style, Suggestions,
2020
};
2121
use rustc_fs_util::link_or_copy;
2222
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -1903,7 +1903,7 @@ impl Emitter for SharedEmitter {
19031903
// Check that we aren't missing anything interesting when converting to
19041904
// the cut-down local `DiagInner`.
19051905
assert_eq!(diag.span, MultiSpan::new());
1906-
assert_eq!(diag.suggestions, Ok(vec![]));
1906+
assert_eq!(diag.suggestions, Suggestions::Enabled(vec![]));
19071907
assert_eq!(diag.sort_span, rustc_span::DUMMY_SP);
19081908
assert_eq!(diag.is_lint, None);
19091909
// No sensible check for `diag.emitted_at`.

compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl Emitter for AnnotateSnippetEmitter {
4848
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
4949
let fluent_args = to_fluent_args(diag.args.iter());
5050

51-
let mut suggestions = diag.suggestions.unwrap_or(vec![]);
51+
let mut suggestions = diag.suggestions.unwrap_tag();
5252
self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
5353

5454
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(

compiler/rustc_errors/src/diagnostic.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@ use crate::snippet::Style;
1919
use crate::{
2020
CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level,
2121
MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle,
22+
Suggestions,
2223
};
2324

24-
/// Error type for `DiagInner`'s `suggestions` field, indicating that
25-
/// `.disable_suggestions()` was called on the `DiagInner`.
26-
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
27-
pub struct SuggestionsDisabled;
28-
2925
/// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of
3026
/// `DiagArg` are converted to `FluentArgs` (consuming the collection) at the start of diagnostic
3127
/// emission.
@@ -296,7 +292,7 @@ pub struct DiagInner {
296292
pub code: Option<ErrCode>,
297293
pub span: MultiSpan,
298294
pub children: Vec<Subdiag>,
299-
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
295+
pub suggestions: Suggestions,
300296
pub args: DiagArgMap,
301297

302298
/// This is not used for highlighting or rendering any error message. Rather, it can be used
@@ -325,7 +321,7 @@ impl DiagInner {
325321
code: None,
326322
span: MultiSpan::new(),
327323
children: vec![],
328-
suggestions: Ok(vec![]),
324+
suggestions: Suggestions::Enabled(vec![]),
329325
args: Default::default(),
330326
sort_span: DUMMY_SP,
331327
is_lint: None,
@@ -409,7 +405,7 @@ impl DiagInner {
409405
&Option<ErrCode>,
410406
&MultiSpan,
411407
&[Subdiag],
412-
&Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
408+
&Suggestions,
413409
Vec<(&DiagArgName, &DiagArgValue)>,
414410
&Option<IsLint>,
415411
) {
@@ -823,16 +819,32 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
823819
self
824820
}
825821

826-
/// Disallow attaching suggestions this diagnostic.
822+
/// Disallow attaching suggestions to this diagnostic.
827823
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
828824
/// (before and after the call to `disable_suggestions`) will be ignored.
829825
#[rustc_lint_diagnostics]
830826
pub fn disable_suggestions(&mut self) -> &mut Self {
831-
self.suggestions = Err(SuggestionsDisabled);
827+
self.suggestions = Suggestions::Disabled;
832828
self
833829
}
834830

835-
/// Helper for pushing to `self.suggestions`, if available (not disable).
831+
/// Prevent new suggestions from being added to this diagnostic.
832+
///
833+
/// Suggestions added before the call to `.seal_suggestions()` will be preserved
834+
/// and new suggestions will be ignored.
835+
#[rustc_lint_diagnostics]
836+
pub fn seal_suggestions(&mut self) -> &mut Self {
837+
if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
838+
let suggestions_slice = std::mem::take(suggestions).into_boxed_slice();
839+
self.suggestions = Suggestions::Sealed(suggestions_slice);
840+
}
841+
self
842+
}
843+
844+
/// Helper for pushing to `self.suggestions`.
845+
///
846+
/// A new suggestion is added if suggestions are enabled for this diagnostic.
847+
/// Otherwise, they are ignored.
836848
#[rustc_lint_diagnostics]
837849
fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
838850
for subst in &suggestion.substitutions {
@@ -846,7 +858,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
846858
}
847859
}
848860

849-
if let Ok(suggestions) = &mut self.suggestions {
861+
if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
850862
suggestions.push(suggestion);
851863
}
852864
}

compiler/rustc_errors/src/emitter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl Emitter for HumanEmitter {
498498
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
499499
let fluent_args = to_fluent_args(diag.args.iter());
500500

501-
let mut suggestions = diag.suggestions.unwrap_or(vec![]);
501+
let mut suggestions = diag.suggestions.unwrap_tag();
502502
self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
503503

504504
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(

compiler/rustc_errors/src/json.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ use crate::emitter::{
3333
use crate::registry::Registry;
3434
use crate::translation::{to_fluent_args, Translate};
3535
use crate::{
36-
CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, TerminalUrl,
36+
CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, Suggestions,
37+
TerminalUrl,
3738
};
3839

3940
#[cfg(test)]
@@ -292,7 +293,7 @@ impl Diagnostic {
292293
/// Converts from `rustc_errors::DiagInner` to `Diagnostic`.
293294
fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic {
294295
let args = to_fluent_args(diag.args.iter());
295-
let sugg = diag.suggestions.iter().flatten().map(|sugg| {
296+
let sugg_to_diag = |sugg: &CodeSuggestion| {
296297
let translated_message =
297298
je.translate_message(&sugg.msg, &args).map_err(Report::new).unwrap();
298299
Diagnostic {
@@ -303,7 +304,12 @@ impl Diagnostic {
303304
children: vec![],
304305
rendered: None,
305306
}
306-
});
307+
};
308+
let sugg = match &diag.suggestions {
309+
Suggestions::Enabled(suggestions) => suggestions.iter().map(sugg_to_diag),
310+
Suggestions::Sealed(suggestions) => suggestions.iter().map(sugg_to_diag),
311+
Suggestions::Disabled => [].iter().map(sugg_to_diag),
312+
};
307313

308314
// generate regular command line output and store it in the json
309315

compiler/rustc_errors/src/lib.rs

+35
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,41 @@ impl SuggestionStyle {
126126
}
127127
}
128128

129+
/// Represents the help messages seen on a diagnostic.
130+
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
131+
pub enum Suggestions {
132+
/// Indicates that new suggestions can be added or removed from this diagnostic.
133+
///
134+
/// `DiagInner`'s new_* methods initialize the `suggestions` field with
135+
/// this variant. Also, this is the default variant for `Suggestions`.
136+
Enabled(Vec<CodeSuggestion>),
137+
/// Indicates that suggestions cannot be added or removed from this diagnostic.
138+
///
139+
/// Gets toggled when `.seal_suggestions()` is called on the `DiagInner`.
140+
Sealed(Box<[CodeSuggestion]>),
141+
/// Indicates that no suggestion is available for this diagnostic.
142+
///
143+
/// Gets toggled when `.disable_suggestions()` is called on the `DiagInner`.
144+
Disabled,
145+
}
146+
147+
impl Suggestions {
148+
/// Returns the underlying list of suggestions.
149+
pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
150+
match self {
151+
Suggestions::Enabled(suggestions) => suggestions,
152+
Suggestions::Sealed(suggestions) => suggestions.into_vec(),
153+
Suggestions::Disabled => Vec::new(),
154+
}
155+
}
156+
}
157+
158+
impl Default for Suggestions {
159+
fn default() -> Self {
160+
Self::Enabled(vec![])
161+
}
162+
}
163+
129164
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
130165
pub struct CodeSuggestion {
131166
/// Each substitute can have multiple variants due to multiple

compiler/rustc_hir_analysis/src/collect/type_of.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::ops::ControlFlow;
22

3-
use rustc_errors::{Applicability, StashKey};
3+
use rustc_errors::{Applicability, StashKey, Suggestions};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::{DefId, LocalDefId};
66
use rustc_hir::HirId;
@@ -670,7 +670,7 @@ fn infer_placeholder_type<'tcx>(
670670

671671
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
672672
// We are typeck and have the real type, so remove that and suggest the actual type.
673-
if let Ok(suggestions) = &mut err.suggestions {
673+
if let Suggestions::Enabled(suggestions) = &mut err.suggestions {
674674
suggestions.clear();
675675
}
676676

compiler/rustc_middle/src/values.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
5656
&& let Some(node) = tcx.hir().get_if_local(def_id)
5757
&& let Some(sig) = node.fn_sig()
5858
{
59-
sig.decl.inputs.len() + sig.decl.implicit_self.has_implicit_self() as usize
59+
sig.decl.inputs.len()
6060
} else {
6161
tcx.dcx().abort_if_errors();
6262
unreachable!()

compiler/rustc_parse/src/lexer/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
299299
lifetime_name += lifetime_name_without_tick;
300300
let sym = Symbol::intern(&lifetime_name);
301301

302+
// Make sure we mark this as a raw identifier.
303+
self.psess.raw_identifier_spans.push(self.mk_sp(start, self.pos));
304+
302305
token::Lifetime(sym, IdentIsRaw::Yes)
303306
} else {
304307
// Otherwise, this should be parsed like `'r`. Warn about it though.

compiler/rustc_parse/src/parser/diagnostics.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_ast_pretty::pprust;
1616
use rustc_data_structures::fx::FxHashSet;
1717
use rustc_errors::{
1818
pluralize, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult,
19-
Subdiagnostic,
19+
Subdiagnostic, Suggestions,
2020
};
2121
use rustc_session::errors::ExprParenthesesNeeded;
2222
use rustc_span::edit_distance::find_best_match_for_name;
@@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
775775
}
776776

777777
// Check for misspelled keywords if there are no suggestions added to the diagnostic.
778-
if err.suggestions.as_ref().is_ok_and(|code_suggestions| code_suggestions.is_empty()) {
778+
if matches!(&err.suggestions, Suggestions::Enabled(list) if list.is_empty()) {
779779
self.check_for_misspelled_kw(&mut err, &expected);
780780
}
781781
Err(err)
@@ -803,6 +803,9 @@ impl<'a> Parser<'a> {
803803
&& let Some(misspelled_kw) = find_similar_kw(curr_ident, &expected_keywords)
804804
{
805805
err.subdiagnostic(misspelled_kw);
806+
// We don't want other suggestions to be added as they are most likely meaningless
807+
// when there is a misspelled keyword.
808+
err.seal_suggestions();
806809
} else if let Some((prev_ident, _)) = self.prev_token.ident()
807810
&& !prev_ident.is_used_keyword()
808811
{
@@ -818,6 +821,9 @@ impl<'a> Parser<'a> {
818821
// positives like suggesting keyword `for` for `extern crate foo {}`.
819822
if let Some(misspelled_kw) = find_similar_kw(prev_ident, &all_keywords) {
820823
err.subdiagnostic(misspelled_kw);
824+
// We don't want other suggestions to be added as they are most likely meaningless
825+
// when there is a misspelled keyword.
826+
err.seal_suggestions();
821827
}
822828
}
823829
}

compiler/rustc_resolve/src/late.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_ast::visit::{visit_opt, walk_list, AssocCtxt, BoundKind, FnCtxt, FnKin
1717
use rustc_ast::*;
1818
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
1919
use rustc_errors::codes::*;
20-
use rustc_errors::{Applicability, DiagArgValue, IntoDiagArg, StashKey};
20+
use rustc_errors::{Applicability, DiagArgValue, IntoDiagArg, StashKey, Suggestions};
2121
use rustc_hir::def::Namespace::{self, *};
2222
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
2323
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -4085,17 +4085,23 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
40854085
err.sort_span = parent_err.sort_span;
40864086
err.is_lint = parent_err.is_lint.clone();
40874087

4088-
// merge the parent's suggestions with the typo suggestions
4089-
fn append_result<T, E>(res1: &mut Result<Vec<T>, E>, res2: Result<Vec<T>, E>) {
4090-
match res1 {
4091-
Ok(vec1) => match res2 {
4092-
Ok(mut vec2) => vec1.append(&mut vec2),
4093-
Err(e) => *res1 = Err(e),
4094-
},
4095-
Err(_) => (),
4096-
};
4088+
// merge the parent_err's suggestions with the typo (err's) suggestions
4089+
match &mut err.suggestions {
4090+
Suggestions::Enabled(typo_suggestions) => match &mut parent_err.suggestions {
4091+
Suggestions::Enabled(parent_suggestions) => {
4092+
// If both suggestions are enabled, append parent_err's suggestions to err's suggestions.
4093+
typo_suggestions.append(parent_suggestions)
4094+
}
4095+
Suggestions::Sealed(_) | Suggestions::Disabled => {
4096+
// If the parent's suggestions are either sealed or disabled, it signifies that
4097+
// new suggestions cannot be added or removed from the diagnostic. Therefore,
4098+
// we assign both types of suggestions to err's suggestions and discard the
4099+
// existing suggestions in err.
4100+
err.suggestions = std::mem::take(&mut parent_err.suggestions);
4101+
}
4102+
},
4103+
Suggestions::Sealed(_) | Suggestions::Disabled => (),
40974104
}
4098-
append_result(&mut err.suggestions, parent_err.suggestions.clone());
40994105

41004106
parent_err.cancel();
41014107

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_data_structures::unord::UnordSet;
66
use rustc_errors::codes::*;
77
use rustc_errors::{
88
pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey,
9-
StringPart,
9+
StringPart, Suggestions,
1010
};
1111
use rustc_hir::def::Namespace;
1212
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
@@ -2137,8 +2137,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21372137
if let Some(span) = err.span.primary_span()
21382138
&& let Some(mut diag) =
21392139
self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
2140-
&& let Ok(ref mut s1) = err.suggestions
2141-
&& let Ok(ref mut s2) = diag.suggestions
2140+
&& let Suggestions::Enabled(ref mut s1) = err.suggestions
2141+
&& let Suggestions::Enabled(ref mut s2) = diag.suggestions
21422142
{
21432143
s1.append(s2);
21442144
diag.cancel()

tests/crashes/120016.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ known-bug: #120016
2+
//@ compile-flags: -Zcrate-attr=feature(const_async_blocks) --edition=2021
3+
4+
#![feature(type_alias_impl_trait, const_async_blocks)]
5+
6+
struct Bug {
7+
V1: [(); {
8+
type F = impl std::future::Future<Output = impl Sized>;
9+
fn concrete_use() -> F {
10+
//~^ ERROR to be a future that resolves to `u8`, but it resolves to `()`
11+
async {}
12+
}
13+
let f: F = async { 1 };
14+
//~^ ERROR `async` blocks are not allowed in constants
15+
1
16+
}],
17+
}
18+
19+
fn main() {}

tests/crashes/127804.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ known-bug: #127804
2+
3+
struct Thing;
4+
5+
pub trait Every {
6+
type Assoc;
7+
}
8+
impl<T: ?Sized> Every for Thing {
9+
type Assoc = T;
10+
}
11+
12+
fn foo(_: <Thing as Every>::Assoc) {}

tests/crashes/128119.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ known-bug: #128119
2+
3+
trait Trait {
4+
reuse to_reuse::foo { self }
5+
}
6+
7+
struct S;
8+
9+
mod to_reuse {
10+
pub fn foo(&self) -> u32 {}
11+
}
12+
13+
impl Trait S {
14+
reuse to_reuse::foo { self }
15+
}

tests/crashes/128232.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ known-bug: #128232
2+
3+
#![feature(generic_const_exprs, unsized_const_params)]
4+
5+
fn function() {}
6+
7+
struct Wrapper<const F: fn()>;
8+
9+
impl Wrapper<{ bar() }> {
10+
fn call() {}
11+
}
12+
13+
fn main() {
14+
Wrapper::<function>::call;
15+
}

0 commit comments

Comments
 (0)