Skip to content

Commit 68fa81b

Browse files
committed
rustc_errors: remove allow_suggestions from DiagnosticBuilder.
1 parent 42313dd commit 68fa81b

File tree

6 files changed

+64
-128
lines changed

6 files changed

+64
-128
lines changed

compiler/rustc_errors/src/diagnostic.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ use rustc_span::{MultiSpan, Span, DUMMY_SP};
1111
use std::fmt;
1212
use std::hash::{Hash, Hasher};
1313

14+
/// Error type for `Diagnostic`'s `suggestions` field, indicating that
15+
/// `.disable_suggestions()` was called on the `Diagnostic`.
16+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
17+
pub struct SuggestionsDisabled;
18+
1419
#[must_use]
1520
#[derive(Clone, Debug, Encodable, Decodable)]
1621
pub struct Diagnostic {
@@ -19,7 +24,7 @@ pub struct Diagnostic {
1924
pub code: Option<DiagnosticId>,
2025
pub span: MultiSpan,
2126
pub children: Vec<SubDiagnostic>,
22-
pub suggestions: Vec<CodeSuggestion>,
27+
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
2328

2429
/// This is not used for highlighting or rendering any error message. Rather, it can be used
2530
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
@@ -106,7 +111,7 @@ impl Diagnostic {
106111
code,
107112
span: MultiSpan::new(),
108113
children: vec![],
109-
suggestions: vec![],
114+
suggestions: Ok(vec![]),
110115
sort_span: DUMMY_SP,
111116
is_lint: false,
112117
}
@@ -300,6 +305,21 @@ impl Diagnostic {
300305
self
301306
}
302307

308+
/// Disallow attaching suggestions this diagnostic.
309+
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
310+
/// (before and after the call to `disable_suggestions`) will be ignored.
311+
pub fn disable_suggestions(&mut self) -> &mut Self {
312+
self.suggestions = Err(SuggestionsDisabled);
313+
self
314+
}
315+
316+
/// Helper for pushing to `self.suggestions`, if available (not disable).
317+
fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
318+
if let Ok(suggestions) = &mut self.suggestions {
319+
suggestions.push(suggestion);
320+
}
321+
}
322+
303323
/// Show a suggestion that has multiple parts to it.
304324
/// In other words, multiple changes need to be applied as part of this suggestion.
305325
pub fn multipart_suggestion(
@@ -340,7 +360,7 @@ impl Diagnostic {
340360
style: SuggestionStyle,
341361
) -> &mut Self {
342362
assert!(!suggestion.is_empty());
343-
self.suggestions.push(CodeSuggestion {
363+
self.push_suggestion(CodeSuggestion {
344364
substitutions: vec![Substitution {
345365
parts: suggestion
346366
.into_iter()
@@ -368,7 +388,7 @@ impl Diagnostic {
368388
applicability: Applicability,
369389
) -> &mut Self {
370390
assert!(!suggestion.is_empty());
371-
self.suggestions.push(CodeSuggestion {
391+
self.push_suggestion(CodeSuggestion {
372392
substitutions: vec![Substitution {
373393
parts: suggestion
374394
.into_iter()
@@ -426,7 +446,7 @@ impl Diagnostic {
426446
applicability: Applicability,
427447
style: SuggestionStyle,
428448
) -> &mut Self {
429-
self.suggestions.push(CodeSuggestion {
449+
self.push_suggestion(CodeSuggestion {
430450
substitutions: vec![Substitution {
431451
parts: vec![SubstitutionPart { snippet: suggestion, span: sp }],
432452
}],
@@ -471,7 +491,7 @@ impl Diagnostic {
471491
.into_iter()
472492
.map(|snippet| Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] })
473493
.collect();
474-
self.suggestions.push(CodeSuggestion {
494+
self.push_suggestion(CodeSuggestion {
475495
substitutions,
476496
msg: msg.to_owned(),
477497
style: SuggestionStyle::ShowCode,
@@ -489,7 +509,7 @@ impl Diagnostic {
489509
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
490510
applicability: Applicability,
491511
) -> &mut Self {
492-
self.suggestions.push(CodeSuggestion {
512+
self.push_suggestion(CodeSuggestion {
493513
substitutions: suggestions
494514
.map(|sugg| Substitution {
495515
parts: sugg
@@ -578,7 +598,7 @@ impl Diagnostic {
578598
applicability: Applicability,
579599
tool_metadata: Json,
580600
) {
581-
self.suggestions.push(CodeSuggestion {
601+
self.push_suggestion(CodeSuggestion {
582602
substitutions: vec![],
583603
msg: msg.to_owned(),
584604
style: SuggestionStyle::CompletelyHidden,
@@ -668,7 +688,7 @@ impl Diagnostic {
668688
&Vec<(String, Style)>,
669689
&Option<DiagnosticId>,
670690
&MultiSpan,
671-
&Vec<CodeSuggestion>,
691+
&Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
672692
Option<&Vec<SubDiagnostic>>,
673693
) {
674694
(

compiler/rustc_errors/src/diagnostic_builder.rs

+25-113
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ pub struct DiagnosticBuilder<'a>(Box<DiagnosticBuilderInner<'a>>);
2222
/// (RVO) should avoid unnecessary copying. In practice, it does not (at the
2323
/// time of writing). The split between `DiagnosticBuilder` and
2424
/// `DiagnosticBuilderInner` exists to avoid many `memcpy` calls.
25+
// FIXME(eddyb) try having two pointers in `DiagnosticBuilder`, by only boxing
26+
// `Diagnostic` (i.e. `struct DiagnosticBuilder(&Handler, Box<Diagnostic>);`).
2527
#[must_use]
2628
#[derive(Clone)]
2729
struct DiagnosticBuilderInner<'a> {
2830
handler: &'a Handler,
2931
diagnostic: Diagnostic,
30-
allow_suggestions: bool,
3132
}
3233

3334
/// In general, the `DiagnosticBuilder` uses deref to allow access to
@@ -244,164 +245,79 @@ impl<'a> DiagnosticBuilder<'a> {
244245
) -> &mut Self);
245246
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
246247

247-
/// See [`Diagnostic::multipart_suggestion()`].
248-
pub fn multipart_suggestion(
248+
forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);
249+
250+
forward!(pub fn multipart_suggestion(
249251
&mut self,
250252
msg: &str,
251253
suggestion: Vec<(Span, String)>,
252254
applicability: Applicability,
253-
) -> &mut Self {
254-
if !self.0.allow_suggestions {
255-
return self;
256-
}
257-
self.0.diagnostic.multipart_suggestion(msg, suggestion, applicability);
258-
self
259-
}
260-
261-
/// See [`Diagnostic::multipart_suggestion()`].
262-
pub fn multipart_suggestion_verbose(
255+
) -> &mut Self);
256+
forward!(pub fn multipart_suggestion_verbose(
263257
&mut self,
264258
msg: &str,
265259
suggestion: Vec<(Span, String)>,
266260
applicability: Applicability,
267-
) -> &mut Self {
268-
if !self.0.allow_suggestions {
269-
return self;
270-
}
271-
self.0.diagnostic.multipart_suggestion_verbose(msg, suggestion, applicability);
272-
self
273-
}
274-
275-
/// See [`Diagnostic::tool_only_multipart_suggestion()`].
276-
pub fn tool_only_multipart_suggestion(
261+
) -> &mut Self);
262+
forward!(pub fn tool_only_multipart_suggestion(
277263
&mut self,
278264
msg: &str,
279265
suggestion: Vec<(Span, String)>,
280266
applicability: Applicability,
281-
) -> &mut Self {
282-
if !self.0.allow_suggestions {
283-
return self;
284-
}
285-
self.0.diagnostic.tool_only_multipart_suggestion(msg, suggestion, applicability);
286-
self
287-
}
288-
289-
/// See [`Diagnostic::span_suggestion()`].
290-
pub fn span_suggestion(
267+
) -> &mut Self);
268+
forward!(pub fn span_suggestion(
291269
&mut self,
292270
sp: Span,
293271
msg: &str,
294272
suggestion: String,
295273
applicability: Applicability,
296-
) -> &mut Self {
297-
if !self.0.allow_suggestions {
298-
return self;
299-
}
300-
self.0.diagnostic.span_suggestion(sp, msg, suggestion, applicability);
301-
self
302-
}
303-
304-
/// See [`Diagnostic::span_suggestions()`].
305-
pub fn span_suggestions(
274+
) -> &mut Self);
275+
forward!(pub fn span_suggestions(
306276
&mut self,
307277
sp: Span,
308278
msg: &str,
309279
suggestions: impl Iterator<Item = String>,
310280
applicability: Applicability,
311-
) -> &mut Self {
312-
if !self.0.allow_suggestions {
313-
return self;
314-
}
315-
self.0.diagnostic.span_suggestions(sp, msg, suggestions, applicability);
316-
self
317-
}
318-
319-
/// See [`Diagnostic::multipart_suggestions()`].
320-
pub fn multipart_suggestions(
281+
) -> &mut Self);
282+
forward!(pub fn multipart_suggestions(
321283
&mut self,
322284
msg: &str,
323285
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
324286
applicability: Applicability,
325-
) -> &mut Self {
326-
if !self.0.allow_suggestions {
327-
return self;
328-
}
329-
self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability);
330-
self
331-
}
332-
333-
/// See [`Diagnostic::span_suggestion_short()`].
334-
pub fn span_suggestion_short(
287+
) -> &mut Self);
288+
forward!(pub fn span_suggestion_short(
335289
&mut self,
336290
sp: Span,
337291
msg: &str,
338292
suggestion: String,
339293
applicability: Applicability,
340-
) -> &mut Self {
341-
if !self.0.allow_suggestions {
342-
return self;
343-
}
344-
self.0.diagnostic.span_suggestion_short(sp, msg, suggestion, applicability);
345-
self
346-
}
347-
348-
/// See [`Diagnostic::span_suggestion_verbose()`].
349-
pub fn span_suggestion_verbose(
294+
) -> &mut Self);
295+
forward!(pub fn span_suggestion_verbose(
350296
&mut self,
351297
sp: Span,
352298
msg: &str,
353299
suggestion: String,
354300
applicability: Applicability,
355-
) -> &mut Self {
356-
if !self.0.allow_suggestions {
357-
return self;
358-
}
359-
self.0.diagnostic.span_suggestion_verbose(sp, msg, suggestion, applicability);
360-
self
361-
}
362-
363-
/// See [`Diagnostic::span_suggestion_hidden()`].
364-
pub fn span_suggestion_hidden(
301+
) -> &mut Self);
302+
forward!(pub fn span_suggestion_hidden(
365303
&mut self,
366304
sp: Span,
367305
msg: &str,
368306
suggestion: String,
369307
applicability: Applicability,
370-
) -> &mut Self {
371-
if !self.0.allow_suggestions {
372-
return self;
373-
}
374-
self.0.diagnostic.span_suggestion_hidden(sp, msg, suggestion, applicability);
375-
self
376-
}
377-
378-
/// See [`Diagnostic::tool_only_span_suggestion()`] for more information.
379-
pub fn tool_only_span_suggestion(
308+
) -> &mut Self);
309+
forward!(pub fn tool_only_span_suggestion(
380310
&mut self,
381311
sp: Span,
382312
msg: &str,
383313
suggestion: String,
384314
applicability: Applicability,
385-
) -> &mut Self {
386-
if !self.0.allow_suggestions {
387-
return self;
388-
}
389-
self.0.diagnostic.tool_only_span_suggestion(sp, msg, suggestion, applicability);
390-
self
391-
}
315+
) -> &mut Self);
392316

393317
forward!(pub fn set_primary_message<M: Into<String>>(&mut self, msg: M) -> &mut Self);
394318
forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
395319
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
396320

397-
/// Allow attaching suggestions this diagnostic.
398-
/// If this is set to `false`, then any suggestions attached with the `span_suggestion_*`
399-
/// methods after this is set to `false` will be ignored.
400-
pub fn allow_suggestions(&mut self, allow: bool) -> &mut Self {
401-
self.0.allow_suggestions = allow;
402-
self
403-
}
404-
405321
/// Convenience function for internal use, clients should use one of the
406322
/// `struct_*` methods on [`Handler`].
407323
crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> {
@@ -424,11 +340,7 @@ impl<'a> DiagnosticBuilder<'a> {
424340
/// diagnostic.
425341
crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
426342
debug!("Created new diagnostic");
427-
DiagnosticBuilder(Box::new(DiagnosticBuilderInner {
428-
handler,
429-
diagnostic,
430-
allow_suggestions: true,
431-
}))
343+
DiagnosticBuilder(Box::new(DiagnosticBuilderInner { handler, diagnostic }))
432344
}
433345
}
434346

compiler/rustc_errors/src/emitter.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ pub trait Emitter {
227227
diag: &'a Diagnostic,
228228
) -> (MultiSpan, &'a [CodeSuggestion]) {
229229
let mut primary_span = diag.span.clone();
230-
if let Some((sugg, rest)) = diag.suggestions.split_first() {
230+
let suggestions = diag.suggestions.as_ref().map_or(&[][..], |suggestions| &suggestions[..]);
231+
if let Some((sugg, rest)) = suggestions.split_first() {
231232
if rest.is_empty() &&
232233
// ^ if there is only one suggestion
233234
// don't display multi-suggestions as labels
@@ -282,10 +283,10 @@ pub trait Emitter {
282283
// to be consistent. We could try to figure out if we can
283284
// make one (or the first one) inline, but that would give
284285
// undue importance to a semi-random suggestion
285-
(primary_span, &diag.suggestions)
286+
(primary_span, suggestions)
286287
}
287288
} else {
288-
(primary_span, &diag.suggestions)
289+
(primary_span, suggestions)
289290
}
290291
}
291292

compiler/rustc_errors/src/json.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ struct UnusedExterns<'a, 'b, 'c> {
345345

346346
impl Diagnostic {
347347
fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic {
348-
let sugg = diag.suggestions.iter().map(|sugg| Diagnostic {
348+
let sugg = diag.suggestions.iter().flatten().map(|sugg| Diagnostic {
349349
message: sugg.msg.clone(),
350350
code: None,
351351
level: "help",

compiler/rustc_middle/src/lint.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ pub fn struct_lint_level<'s, 'd>(
262262
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
263263
// Any suggestions made here are likely to be incorrect, so anything we
264264
// emit shouldn't be automatically fixed by rustfix.
265-
err.allow_suggestions(false);
265+
err.disable_suggestions();
266266

267267
// If this is a future incompatible that is not an edition fixing lint
268268
// it'll become a hard error, so we have to emit *something*. Also,

compiler/rustc_typeck/src/collect/type_of.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,10 @@ fn infer_placeholder_type<'a>(
726726
if !ty.references_error() {
727727
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
728728
// We are typeck and have the real type, so remove that and suggest the actual type.
729-
err.suggestions.clear();
729+
// FIXME(eddyb) this looks like it should be functionality on `Diagnostic`.
730+
if let Ok(suggestions) = &mut err.suggestions {
731+
suggestions.clear();
732+
}
730733

731734
// Suggesting unnameable types won't help.
732735
let mut mk_nameable = MakeNameable::new(tcx);

0 commit comments

Comments
 (0)