1
Fork 0

add debug assertion for suggestions with overlapping parts

This commit is contained in:
Lukas Markeffsky 2023-01-15 14:29:20 +01:00
parent a6269dad38
commit b9e8286c85
2 changed files with 45 additions and 27 deletions

View file

@ -629,19 +629,27 @@ impl Diagnostic {
applicability: Applicability, applicability: Applicability,
style: SuggestionStyle, style: SuggestionStyle,
) -> &mut Self { ) -> &mut Self {
assert!(!suggestion.is_empty()); let mut parts = suggestion
debug_assert!( .into_iter()
!(suggestion.iter().any(|(sp, text)| sp.is_empty() && text.is_empty())), .map(|(span, snippet)| SubstitutionPart { snippet, span })
"Span must not be empty and have no suggestion" .collect::<Vec<_>>();
parts.sort_unstable_by_key(|part| part.span);
assert!(!parts.is_empty());
debug_assert_eq!(
parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
None,
"Span must not be empty and have no suggestion",
);
debug_assert_eq!(
parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
None,
"suggestion must not have overlapping parts",
); );
self.push_suggestion(CodeSuggestion { self.push_suggestion(CodeSuggestion {
substitutions: vec![Substitution { substitutions: vec![Substitution { parts }],
parts: suggestion
.into_iter()
.map(|(span, snippet)| SubstitutionPart { snippet, span })
.collect(),
}],
msg: self.subdiagnostic_message_to_diagnostic_message(msg), msg: self.subdiagnostic_message_to_diagnostic_message(msg),
style, style,
applicability, applicability,
@ -802,25 +810,34 @@ impl Diagnostic {
suggestions: impl IntoIterator<Item = Vec<(Span, String)>>, suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
applicability: Applicability, applicability: Applicability,
) -> &mut Self { ) -> &mut Self {
let suggestions: Vec<_> = suggestions.into_iter().collect(); let substitutions = suggestions
debug_assert!( .into_iter()
!(suggestions .map(|sugg| {
.iter() let mut parts = sugg
.flatten() .into_iter()
.any(|(sp, suggestion)| sp.is_empty() && suggestion.is_empty())), .map(|(span, snippet)| SubstitutionPart { snippet, span })
"Span must not be empty and have no suggestion" .collect::<Vec<_>>();
);
parts.sort_unstable_by_key(|part| part.span);
assert!(!parts.is_empty());
debug_assert_eq!(
parts.iter().find(|part| part.span.is_empty() && part.snippet.is_empty()),
None,
"Span must not be empty and have no suggestion",
);
debug_assert_eq!(
parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)),
None,
"suggestion must not have overlapping parts",
);
Substitution { parts }
})
.collect();
self.push_suggestion(CodeSuggestion { self.push_suggestion(CodeSuggestion {
substitutions: suggestions substitutions,
.into_iter()
.map(|sugg| Substitution {
parts: sugg
.into_iter()
.map(|(span, snippet)| SubstitutionPart { snippet, span })
.collect(),
})
.collect(),
msg: self.subdiagnostic_message_to_diagnostic_message(msg), msg: self.subdiagnostic_message_to_diagnostic_message(msg),
style: SuggestionStyle::ShowCode, style: SuggestionStyle::ShowCode,
applicability, applicability,

View file

@ -3,6 +3,7 @@
//! This module contains the code for creating and emitting diagnostics. //! This module contains the code for creating and emitting diagnostics.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(drain_filter)] #![feature(drain_filter)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(is_terminal)] #![feature(is_terminal)]