rustc_errors: remove allow_suggestions
from DiagnosticBuilder
.
This commit is contained in:
parent
42313dd29b
commit
68fa81baa3
6 changed files with 64 additions and 128 deletions
|
@ -11,6 +11,11 @@ use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
|||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
/// Error type for `Diagnostic`'s `suggestions` field, indicating that
|
||||
/// `.disable_suggestions()` was called on the `Diagnostic`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
pub struct SuggestionsDisabled;
|
||||
|
||||
#[must_use]
|
||||
#[derive(Clone, Debug, Encodable, Decodable)]
|
||||
pub struct Diagnostic {
|
||||
|
@ -19,7 +24,7 @@ pub struct Diagnostic {
|
|||
pub code: Option<DiagnosticId>,
|
||||
pub span: MultiSpan,
|
||||
pub children: Vec<SubDiagnostic>,
|
||||
pub suggestions: Vec<CodeSuggestion>,
|
||||
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
|
||||
|
||||
/// This is not used for highlighting or rendering any error message. Rather, it can be used
|
||||
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
|
||||
|
@ -106,7 +111,7 @@ impl Diagnostic {
|
|||
code,
|
||||
span: MultiSpan::new(),
|
||||
children: vec![],
|
||||
suggestions: vec![],
|
||||
suggestions: Ok(vec![]),
|
||||
sort_span: DUMMY_SP,
|
||||
is_lint: false,
|
||||
}
|
||||
|
@ -300,6 +305,21 @@ impl Diagnostic {
|
|||
self
|
||||
}
|
||||
|
||||
/// Disallow attaching suggestions this diagnostic.
|
||||
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
|
||||
/// (before and after the call to `disable_suggestions`) will be ignored.
|
||||
pub fn disable_suggestions(&mut self) -> &mut Self {
|
||||
self.suggestions = Err(SuggestionsDisabled);
|
||||
self
|
||||
}
|
||||
|
||||
/// Helper for pushing to `self.suggestions`, if available (not disable).
|
||||
fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
|
||||
if let Ok(suggestions) = &mut self.suggestions {
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
/// Show a suggestion that has multiple parts to it.
|
||||
/// In other words, multiple changes need to be applied as part of this suggestion.
|
||||
pub fn multipart_suggestion(
|
||||
|
@ -340,7 +360,7 @@ impl Diagnostic {
|
|||
style: SuggestionStyle,
|
||||
) -> &mut Self {
|
||||
assert!(!suggestion.is_empty());
|
||||
self.suggestions.push(CodeSuggestion {
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: vec![Substitution {
|
||||
parts: suggestion
|
||||
.into_iter()
|
||||
|
@ -368,7 +388,7 @@ impl Diagnostic {
|
|||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
assert!(!suggestion.is_empty());
|
||||
self.suggestions.push(CodeSuggestion {
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: vec![Substitution {
|
||||
parts: suggestion
|
||||
.into_iter()
|
||||
|
@ -426,7 +446,7 @@ impl Diagnostic {
|
|||
applicability: Applicability,
|
||||
style: SuggestionStyle,
|
||||
) -> &mut Self {
|
||||
self.suggestions.push(CodeSuggestion {
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: vec![Substitution {
|
||||
parts: vec![SubstitutionPart { snippet: suggestion, span: sp }],
|
||||
}],
|
||||
|
@ -471,7 +491,7 @@ impl Diagnostic {
|
|||
.into_iter()
|
||||
.map(|snippet| Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] })
|
||||
.collect();
|
||||
self.suggestions.push(CodeSuggestion {
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions,
|
||||
msg: msg.to_owned(),
|
||||
style: SuggestionStyle::ShowCode,
|
||||
|
@ -489,7 +509,7 @@ impl Diagnostic {
|
|||
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
self.suggestions.push(CodeSuggestion {
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: suggestions
|
||||
.map(|sugg| Substitution {
|
||||
parts: sugg
|
||||
|
@ -578,7 +598,7 @@ impl Diagnostic {
|
|||
applicability: Applicability,
|
||||
tool_metadata: Json,
|
||||
) {
|
||||
self.suggestions.push(CodeSuggestion {
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: vec![],
|
||||
msg: msg.to_owned(),
|
||||
style: SuggestionStyle::CompletelyHidden,
|
||||
|
@ -668,7 +688,7 @@ impl Diagnostic {
|
|||
&Vec<(String, Style)>,
|
||||
&Option<DiagnosticId>,
|
||||
&MultiSpan,
|
||||
&Vec<CodeSuggestion>,
|
||||
&Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
|
||||
Option<&Vec<SubDiagnostic>>,
|
||||
) {
|
||||
(
|
||||
|
|
|
@ -22,12 +22,13 @@ pub struct DiagnosticBuilder<'a>(Box<DiagnosticBuilderInner<'a>>);
|
|||
/// (RVO) should avoid unnecessary copying. In practice, it does not (at the
|
||||
/// time of writing). The split between `DiagnosticBuilder` and
|
||||
/// `DiagnosticBuilderInner` exists to avoid many `memcpy` calls.
|
||||
// FIXME(eddyb) try having two pointers in `DiagnosticBuilder`, by only boxing
|
||||
// `Diagnostic` (i.e. `struct DiagnosticBuilder(&Handler, Box<Diagnostic>);`).
|
||||
#[must_use]
|
||||
#[derive(Clone)]
|
||||
struct DiagnosticBuilderInner<'a> {
|
||||
handler: &'a Handler,
|
||||
diagnostic: Diagnostic,
|
||||
allow_suggestions: bool,
|
||||
}
|
||||
|
||||
/// In general, the `DiagnosticBuilder` uses deref to allow access to
|
||||
|
@ -244,164 +245,79 @@ impl<'a> DiagnosticBuilder<'a> {
|
|||
) -> &mut Self);
|
||||
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
|
||||
|
||||
/// See [`Diagnostic::multipart_suggestion()`].
|
||||
pub fn multipart_suggestion(
|
||||
forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);
|
||||
|
||||
forward!(pub fn multipart_suggestion(
|
||||
&mut self,
|
||||
msg: &str,
|
||||
suggestion: Vec<(Span, String)>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.multipart_suggestion(msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::multipart_suggestion()`].
|
||||
pub fn multipart_suggestion_verbose(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn multipart_suggestion_verbose(
|
||||
&mut self,
|
||||
msg: &str,
|
||||
suggestion: Vec<(Span, String)>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.multipart_suggestion_verbose(msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::tool_only_multipart_suggestion()`].
|
||||
pub fn tool_only_multipart_suggestion(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn tool_only_multipart_suggestion(
|
||||
&mut self,
|
||||
msg: &str,
|
||||
suggestion: Vec<(Span, String)>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.tool_only_multipart_suggestion(msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::span_suggestion()`].
|
||||
pub fn span_suggestion(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn span_suggestion(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
suggestion: String,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.span_suggestion(sp, msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::span_suggestions()`].
|
||||
pub fn span_suggestions(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn span_suggestions(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
suggestions: impl Iterator<Item = String>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.span_suggestions(sp, msg, suggestions, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::multipart_suggestions()`].
|
||||
pub fn multipart_suggestions(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn multipart_suggestions(
|
||||
&mut self,
|
||||
msg: &str,
|
||||
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::span_suggestion_short()`].
|
||||
pub fn span_suggestion_short(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn span_suggestion_short(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
suggestion: String,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.span_suggestion_short(sp, msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::span_suggestion_verbose()`].
|
||||
pub fn span_suggestion_verbose(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn span_suggestion_verbose(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
suggestion: String,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.span_suggestion_verbose(sp, msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::span_suggestion_hidden()`].
|
||||
pub fn span_suggestion_hidden(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn span_suggestion_hidden(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
suggestion: String,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.span_suggestion_hidden(sp, msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
|
||||
/// See [`Diagnostic::tool_only_span_suggestion()`] for more information.
|
||||
pub fn tool_only_span_suggestion(
|
||||
) -> &mut Self);
|
||||
forward!(pub fn tool_only_span_suggestion(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
suggestion: String,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
if !self.0.allow_suggestions {
|
||||
return self;
|
||||
}
|
||||
self.0.diagnostic.tool_only_span_suggestion(sp, msg, suggestion, applicability);
|
||||
self
|
||||
}
|
||||
) -> &mut Self);
|
||||
|
||||
forward!(pub fn set_primary_message<M: Into<String>>(&mut self, msg: M) -> &mut Self);
|
||||
forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
|
||||
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
|
||||
|
||||
/// Allow attaching suggestions this diagnostic.
|
||||
/// If this is set to `false`, then any suggestions attached with the `span_suggestion_*`
|
||||
/// methods after this is set to `false` will be ignored.
|
||||
pub fn allow_suggestions(&mut self, allow: bool) -> &mut Self {
|
||||
self.0.allow_suggestions = allow;
|
||||
self
|
||||
}
|
||||
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
/// `struct_*` methods on [`Handler`].
|
||||
crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> {
|
||||
|
@ -424,11 +340,7 @@ impl<'a> DiagnosticBuilder<'a> {
|
|||
/// diagnostic.
|
||||
crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
|
||||
debug!("Created new diagnostic");
|
||||
DiagnosticBuilder(Box::new(DiagnosticBuilderInner {
|
||||
handler,
|
||||
diagnostic,
|
||||
allow_suggestions: true,
|
||||
}))
|
||||
DiagnosticBuilder(Box::new(DiagnosticBuilderInner { handler, diagnostic }))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,8 @@ pub trait Emitter {
|
|||
diag: &'a Diagnostic,
|
||||
) -> (MultiSpan, &'a [CodeSuggestion]) {
|
||||
let mut primary_span = diag.span.clone();
|
||||
if let Some((sugg, rest)) = diag.suggestions.split_first() {
|
||||
let suggestions = diag.suggestions.as_ref().map_or(&[][..], |suggestions| &suggestions[..]);
|
||||
if let Some((sugg, rest)) = suggestions.split_first() {
|
||||
if rest.is_empty() &&
|
||||
// ^ if there is only one suggestion
|
||||
// don't display multi-suggestions as labels
|
||||
|
@ -282,10 +283,10 @@ pub trait Emitter {
|
|||
// to be consistent. We could try to figure out if we can
|
||||
// make one (or the first one) inline, but that would give
|
||||
// undue importance to a semi-random suggestion
|
||||
(primary_span, &diag.suggestions)
|
||||
(primary_span, suggestions)
|
||||
}
|
||||
} else {
|
||||
(primary_span, &diag.suggestions)
|
||||
(primary_span, suggestions)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ struct UnusedExterns<'a, 'b, 'c> {
|
|||
|
||||
impl Diagnostic {
|
||||
fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic {
|
||||
let sugg = diag.suggestions.iter().map(|sugg| Diagnostic {
|
||||
let sugg = diag.suggestions.iter().flatten().map(|sugg| Diagnostic {
|
||||
message: sugg.msg.clone(),
|
||||
code: None,
|
||||
level: "help",
|
||||
|
|
|
@ -262,7 +262,7 @@ pub fn struct_lint_level<'s, 'd>(
|
|||
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
|
||||
// Any suggestions made here are likely to be incorrect, so anything we
|
||||
// emit shouldn't be automatically fixed by rustfix.
|
||||
err.allow_suggestions(false);
|
||||
err.disable_suggestions();
|
||||
|
||||
// If this is a future incompatible that is not an edition fixing lint
|
||||
// it'll become a hard error, so we have to emit *something*. Also,
|
||||
|
|
|
@ -726,7 +726,10 @@ fn infer_placeholder_type<'a>(
|
|||
if !ty.references_error() {
|
||||
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
|
||||
// We are typeck and have the real type, so remove that and suggest the actual type.
|
||||
err.suggestions.clear();
|
||||
// FIXME(eddyb) this looks like it should be functionality on `Diagnostic`.
|
||||
if let Ok(suggestions) = &mut err.suggestions {
|
||||
suggestions.clear();
|
||||
}
|
||||
|
||||
// Suggesting unnameable types won't help.
|
||||
let mut mk_nameable = MakeNameable::new(tcx);
|
||||
|
|
Loading…
Add table
Reference in a new issue