Remove Diagnostic::expect_range and all consumers (#20322)

Replace usage with `range().unwrap_or_default()` or more appropriate
alternatives based on context.
This commit is contained in:
Amethyst Reese 2025-09-10 17:19:20 -07:00 committed by GitHub
parent 12c337c948
commit a3ec8ca9df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 53 additions and 63 deletions

View file

@ -494,13 +494,6 @@ impl Diagnostic {
self.primary_span()?.range() self.primary_span()?.range()
} }
/// Returns the [`TextRange`] for the diagnostic.
///
/// Panics if the diagnostic has no primary span or if the span has no range.
pub fn expect_range(&self) -> TextRange {
self.range().expect("Expected a range for the primary span")
}
/// Returns the ordering of diagnostics based on the start of their ranges, if they have any. /// Returns the ordering of diagnostics based on the start of their ranges, if they have any.
/// ///
/// Panics if either diagnostic has no primary span, or if its file is not a `SourceFile`. /// Panics if either diagnostic has no primary span, or if its file is not a `SourceFile`.

View file

@ -6,7 +6,7 @@ use itertools::Itertools;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use ruff_text_size::Ranged; use ruff_text_size::{Ranged, TextRange};
use crate::fix::edits::delete_comment; use crate::fix::edits::delete_comment;
use crate::noqa::{ use crate::noqa::{
@ -68,7 +68,7 @@ pub(crate) fn check_noqa(
let noqa_offsets = diagnostic let noqa_offsets = diagnostic
.parent() .parent()
.into_iter() .into_iter()
.chain(std::iter::once(diagnostic.expect_range().start())) .chain(diagnostic.range().map(TextRange::start).into_iter())
.map(|position| noqa_line_for.resolve(position)) .map(|position| noqa_line_for.resolve(position))
.unique(); .unique();

View file

@ -513,10 +513,9 @@ fn diagnostics_to_messages(
.map(|error| create_syntax_error_diagnostic(source_file.clone(), error, error)), .map(|error| create_syntax_error_diagnostic(source_file.clone(), error, error)),
) )
.chain(diagnostics.into_iter().map(|mut diagnostic| { .chain(diagnostics.into_iter().map(|mut diagnostic| {
let noqa_offset = directives if let Some(range) = diagnostic.range() {
.noqa_line_for diagnostic.set_noqa_offset(directives.noqa_line_for.resolve(range.start()));
.resolve(diagnostic.expect_range().start()); }
diagnostic.set_noqa_offset(noqa_offset);
diagnostic diagnostic
})) }))
.collect() .collect()
@ -983,7 +982,7 @@ mod tests {
&parsed, &parsed,
target_version, target_version,
); );
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start()); diagnostics.sort_by(Diagnostic::ruff_start_ordering);
diagnostics diagnostics
} }

View file

@ -886,7 +886,10 @@ fn find_noqa_comments<'a>(
} }
} }
let noqa_offset = noqa_line_for.resolve(message.expect_range().start()); let noqa_offset = message
.range()
.map(|range| noqa_line_for.resolve(range.start()))
.unwrap_or_default();
// Or ignored by the directive itself? // Or ignored by the directive itself?
if let Some(directive_line) = directives.find_line_with_directive(noqa_offset) { if let Some(directive_line) = directives.find_line_with_directive(noqa_offset) {

View file

@ -362,8 +362,7 @@ fn check_token(
if let Some(mut diagnostic) = if let Some(mut diagnostic) =
lint_context.report_diagnostic_if_enabled(ProhibitedTrailingComma, prev.range()) lint_context.report_diagnostic_if_enabled(ProhibitedTrailingComma, prev.range())
{ {
let range = diagnostic.expect_range(); diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(prev.range)));
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range)));
return; return;
} }
} }

View file

@ -642,7 +642,7 @@ mod tests {
#[test_case(Path::new("order_by_type.py"))] #[test_case(Path::new("order_by_type.py"))]
fn order_by_type(path: &Path) -> Result<()> { fn order_by_type(path: &Path) -> Result<()> {
let snapshot = format!("order_by_type_false_{}", path.to_string_lossy()); let snapshot = format!("order_by_type_false_{}", path.to_string_lossy());
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -653,7 +653,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -664,7 +663,7 @@ mod tests {
"order_by_type_with_custom_classes_{}", "order_by_type_with_custom_classes_{}",
path.to_string_lossy() path.to_string_lossy()
); );
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -681,7 +680,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -692,7 +690,7 @@ mod tests {
"order_by_type_with_custom_constants_{}", "order_by_type_with_custom_constants_{}",
path.to_string_lossy() path.to_string_lossy()
); );
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -711,7 +709,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -722,7 +719,7 @@ mod tests {
"order_by_type_with_custom_variables_{}", "order_by_type_with_custom_variables_{}",
path.to_string_lossy() path.to_string_lossy()
); );
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -739,7 +736,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -749,7 +745,7 @@ mod tests {
#[test_case(Path::new("force_sort_within_sections_future.py"))] #[test_case(Path::new("force_sort_within_sections_future.py"))]
fn force_sort_within_sections(path: &Path) -> Result<()> { fn force_sort_within_sections(path: &Path) -> Result<()> {
let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy()); let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy());
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -761,7 +757,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -769,7 +764,7 @@ mod tests {
#[test_case(Path::new("force_sort_within_sections_lines_between.py"))] #[test_case(Path::new("force_sort_within_sections_lines_between.py"))]
fn force_sort_within_sections_lines_between(path: &Path) -> Result<()> { fn force_sort_within_sections_lines_between(path: &Path) -> Result<()> {
let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy()); let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy());
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -781,7 +776,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1114,7 +1108,7 @@ mod tests {
#[test_case(Path::new("no_lines_before.py"))] #[test_case(Path::new("no_lines_before.py"))]
fn no_lines_before(path: &Path) -> Result<()> { fn no_lines_before(path: &Path) -> Result<()> {
let snapshot = format!("no_lines_before.py_{}", path.to_string_lossy()); let snapshot = format!("no_lines_before.py_{}", path.to_string_lossy());
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -1131,7 +1125,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1142,7 +1135,7 @@ mod tests {
"no_lines_before_with_empty_sections.py_{}", "no_lines_before_with_empty_sections.py_{}",
path.to_string_lossy() path.to_string_lossy()
); );
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -1156,7 +1149,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1167,7 +1159,7 @@ mod tests {
#[test_case(Path::new("lines_after_imports_class_after.py"))] #[test_case(Path::new("lines_after_imports_class_after.py"))]
fn lines_after_imports(path: &Path) -> Result<()> { fn lines_after_imports(path: &Path) -> Result<()> {
let snapshot = format!("lines_after_imports_{}", path.to_string_lossy()); let snapshot = format!("lines_after_imports_{}", path.to_string_lossy());
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -1178,7 +1170,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1188,7 +1179,7 @@ mod tests {
#[test_case(Path::new("lines_after_imports_class_after.py"))] #[test_case(Path::new("lines_after_imports_class_after.py"))]
fn lines_after_imports_default_settings(path: &Path) -> Result<()> { fn lines_after_imports_default_settings(path: &Path) -> Result<()> {
let snapshot = path.to_string_lossy(); let snapshot = path.to_string_lossy();
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
src: vec![test_resource_path("fixtures/isort")], src: vec![test_resource_path("fixtures/isort")],
@ -1199,7 +1190,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(&*snapshot, diagnostics); assert_diagnostics!(&*snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1207,7 +1197,7 @@ mod tests {
#[test_case(Path::new("lines_between_types.py"))] #[test_case(Path::new("lines_between_types.py"))]
fn lines_between_types(path: &Path) -> Result<()> { fn lines_between_types(path: &Path) -> Result<()> {
let snapshot = format!("lines_between_types{}", path.to_string_lossy()); let snapshot = format!("lines_between_types{}", path.to_string_lossy());
let mut diagnostics = test_path( let diagnostics = test_path(
Path::new("isort").join(path).as_path(), Path::new("isort").join(path).as_path(),
&LinterSettings { &LinterSettings {
isort: super::settings::Settings { isort: super::settings::Settings {
@ -1218,7 +1208,6 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
diagnostics.sort_by_key(|diagnostic| diagnostic.expect_range().start());
assert_diagnostics!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }

View file

@ -168,11 +168,11 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
{ {
let (trailing, trailing_len) = line.trailing_whitespace(token); let (trailing, trailing_len) = line.trailing_whitespace(token);
if !matches!(trailing, Whitespace::None) { if !matches!(trailing, Whitespace::None) {
let range = TextRange::at(token.end(), trailing_len);
if let Some(mut diagnostic) = context.report_diagnostic_if_enabled( if let Some(mut diagnostic) = context.report_diagnostic_if_enabled(
WhitespaceAfterOpenBracket { symbol }, WhitespaceAfterOpenBracket { symbol },
TextRange::at(token.end(), trailing_len), range,
) { ) {
let range = diagnostic.expect_range();
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range)));
} }
} }
@ -184,11 +184,11 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
if let (Whitespace::Single | Whitespace::Many | Whitespace::Tab, offset) = if let (Whitespace::Single | Whitespace::Many | Whitespace::Tab, offset) =
line.leading_whitespace(token) line.leading_whitespace(token)
{ {
let range = TextRange::at(token.start() - offset, offset);
if let Some(mut diagnostic) = context.report_diagnostic_if_enabled( if let Some(mut diagnostic) = context.report_diagnostic_if_enabled(
WhitespaceBeforeCloseBracket { symbol }, WhitespaceBeforeCloseBracket { symbol },
TextRange::at(token.start() - offset, offset), range,
) { ) {
let range = diagnostic.expect_range();
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range)));
} }
} }
@ -210,13 +210,13 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
// If we're in the second half of a double colon, disallow // If we're in the second half of a double colon, disallow
// any whitespace (e.g., `foo[1: :2]` or `foo[1 : : 2]`). // any whitespace (e.g., `foo[1: :2]` or `foo[1 : : 2]`).
if matches!(prev_token, Some(TokenKind::Colon)) { if matches!(prev_token, Some(TokenKind::Colon)) {
let range = TextRange::at(token.start() - offset, offset);
if let Some(mut diagnostic) = context if let Some(mut diagnostic) = context
.report_diagnostic_if_enabled( .report_diagnostic_if_enabled(
WhitespaceBeforePunctuation { symbol }, WhitespaceBeforePunctuation { symbol },
TextRange::at(token.start() - offset, offset), range,
) )
{ {
let range = diagnostic.expect_range();
diagnostic diagnostic
.set_fix(Fix::safe_edit(Edit::range_deletion(range))); .set_fix(Fix::safe_edit(Edit::range_deletion(range)));
} }
@ -227,13 +227,13 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
// Or `foo[index :, 2]`, but not `foo[index :, 2]`. // Or `foo[index :, 2]`, but not `foo[index :, 2]`.
if let (Whitespace::Many | Whitespace::Tab, offset) = whitespace if let (Whitespace::Many | Whitespace::Tab, offset) = whitespace
{ {
let range = TextRange::at(token.start() - offset, offset);
if let Some(mut diagnostic) = context if let Some(mut diagnostic) = context
.report_diagnostic_if_enabled( .report_diagnostic_if_enabled(
WhitespaceBeforePunctuation { symbol }, WhitespaceBeforePunctuation { symbol },
TextRange::at(token.start() - offset, offset), range,
) )
{ {
let range = diagnostic.expect_range();
diagnostic.set_fix(Fix::safe_edit( diagnostic.set_fix(Fix::safe_edit(
Edit::range_deletion(range), Edit::range_deletion(range),
)); ));
@ -255,13 +255,13 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
// whitespace before the colon and so should the fix // whitespace before the colon and so should the fix
if let (Whitespace::Many | Whitespace::Tab, offset) = whitespace if let (Whitespace::Many | Whitespace::Tab, offset) = whitespace
{ {
let range = TextRange::at(token.start() - offset, offset);
if let Some(mut diagnostic) = context if let Some(mut diagnostic) = context
.report_diagnostic_if_enabled( .report_diagnostic_if_enabled(
WhitespaceBeforePunctuation { symbol }, WhitespaceBeforePunctuation { symbol },
TextRange::at(token.start() - offset, offset), range,
) )
{ {
let range = diagnostic.expect_range();
diagnostic.set_fix(Fix::safe_edits( diagnostic.set_fix(Fix::safe_edits(
Edit::range_deletion(range), Edit::range_deletion(range),
[Edit::insertion( [Edit::insertion(
@ -278,13 +278,13 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
.filter(|next| matches!(next.kind(), TokenKind::Colon)) .filter(|next| matches!(next.kind(), TokenKind::Colon))
.unwrap_or(&token); .unwrap_or(&token);
if line.trailing_whitespace(token) != whitespace { if line.trailing_whitespace(token) != whitespace {
let range = TextRange::at(token.start() - offset, offset);
if let Some(mut diagnostic) = context if let Some(mut diagnostic) = context
.report_diagnostic_if_enabled( .report_diagnostic_if_enabled(
WhitespaceBeforePunctuation { symbol }, WhitespaceBeforePunctuation { symbol },
TextRange::at(token.start() - offset, offset), range,
) )
{ {
let range = diagnostic.expect_range();
diagnostic.set_fix(Fix::safe_edit( diagnostic.set_fix(Fix::safe_edit(
Edit::range_deletion(range), Edit::range_deletion(range),
)); ));
@ -299,11 +299,11 @@ pub(crate) fn extraneous_whitespace(line: &LogicalLine, context: &LintContext) {
// Avoid removing any whitespace for f-string debug expressions. // Avoid removing any whitespace for f-string debug expressions.
continue; continue;
} }
let range = TextRange::at(token.start() - offset, offset);
if let Some(mut diagnostic) = context.report_diagnostic_if_enabled( if let Some(mut diagnostic) = context.report_diagnostic_if_enabled(
WhitespaceBeforePunctuation { symbol }, WhitespaceBeforePunctuation { symbol },
TextRange::at(token.start() - offset, offset), range,
) { ) {
let range = diagnostic.expect_range();
diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range))); diagnostic.set_fix(Fix::safe_edit(Edit::range_deletion(range)));
} }
} }

View file

@ -788,7 +788,7 @@ mod tests {
&parsed, &parsed,
target_version, target_version,
); );
messages.sort_by_key(|diagnostic| diagnostic.expect_range().start()); messages.sort_by(Diagnostic::ruff_start_ordering);
let actual = messages let actual = messages
.iter() .iter()
.filter(|msg| !msg.is_invalid_syntax()) .filter(|msg| !msg.is_invalid_syntax())

View file

@ -383,19 +383,22 @@ Either ensure you always emit a fix or change `Violation::FIX_AVAILABILITY` to e
// Not strictly necessary but adds some coverage for this code path by overriding the // Not strictly necessary but adds some coverage for this code path by overriding the
// noqa offset and the source file // noqa offset and the source file
let range = diagnostic.expect_range(); if let Some(range) = diagnostic.range() {
diagnostic.set_noqa_offset(directives.noqa_line_for.resolve(range.start())); diagnostic.set_noqa_offset(directives.noqa_line_for.resolve(range.start()));
}
// This part actually is necessary to avoid long relative paths in snapshots. // This part actually is necessary to avoid long relative paths in snapshots.
for annotation in diagnostic.annotations_mut() { for annotation in diagnostic.annotations_mut() {
let range = annotation.get_span().range().unwrap(); if let Some(range) = annotation.get_span().range() {
annotation.set_span(Span::from(source_code.clone()).with_range(range)); annotation.set_span(Span::from(source_code.clone()).with_range(range));
} }
}
for sub in diagnostic.sub_diagnostics_mut() { for sub in diagnostic.sub_diagnostics_mut() {
for annotation in sub.annotations_mut() { for annotation in sub.annotations_mut() {
let range = annotation.get_span().range().unwrap(); if let Some(range) = annotation.get_span().range() {
annotation.set_span(Span::from(source_code.clone()).with_range(range)); annotation.set_span(Span::from(source_code.clone()).with_range(range));
} }
} }
}
diagnostic diagnostic
}) })

View file

@ -234,7 +234,7 @@ fn to_lsp_diagnostic(
index: &LineIndex, index: &LineIndex,
encoding: PositionEncoding, encoding: PositionEncoding,
) -> (usize, lsp_types::Diagnostic) { ) -> (usize, lsp_types::Diagnostic) {
let diagnostic_range = diagnostic.expect_range(); let diagnostic_range = diagnostic.range().unwrap_or_default();
let name = diagnostic.name(); let name = diagnostic.name();
let body = diagnostic.body().to_string(); let body = diagnostic.body().to_string();
let fix = diagnostic.fix(); let fix = diagnostic.fix();

View file

@ -231,8 +231,12 @@ impl Workspace {
.map(|msg| ExpandedMessage { .map(|msg| ExpandedMessage {
code: msg.secondary_code_or_id().to_string(), code: msg.secondary_code_or_id().to_string(),
message: msg.body().to_string(), message: msg.body().to_string(),
start_location: source_code.line_column(msg.expect_range().start()).into(), start_location: source_code
end_location: source_code.line_column(msg.expect_range().end()).into(), .line_column(msg.range().unwrap_or_default().start())
.into(),
end_location: source_code
.line_column(msg.range().unwrap_or_default().end())
.into(),
fix: msg.fix().map(|fix| ExpandedFix { fix: msg.fix().map(|fix| ExpandedFix {
message: msg.first_help_text().map(ToString::to_string), message: msg.first_help_text().map(ToString::to_string),
edits: fix edits: fix