Skip to content

Commit 949a6ec

Browse files
committed
internal: refactor missing or or some diagnostic
1 parent 74f3cca commit 949a6ec

File tree

5 files changed

+44
-58
lines changed

5 files changed

+44
-58
lines changed

crates/hir/src/diagnostics.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ diagnostics![
3737
MacroError,
3838
MismatchedArgCount,
3939
MissingFields,
40+
MissingOkOrSomeInTailExpr,
4041
MissingUnsafe,
4142
NoSuchField,
4243
RemoveThisSemicolon,
@@ -157,41 +158,13 @@ pub struct RemoveThisSemicolon {
157158
pub expr: InFile<AstPtr<ast::Expr>>,
158159
}
159160

160-
// Diagnostic: missing-ok-or-some-in-tail-expr
161-
//
162-
// This diagnostic is triggered if a block that should return `Result` returns a value not wrapped in `Ok`,
163-
// or if a block that should return `Option` returns a value not wrapped in `Some`.
164-
//
165-
// Example:
166-
//
167-
// ```rust
168-
// fn foo() -> Result<u8, ()> {
169-
// 10
170-
// }
171-
// ```
172161
#[derive(Debug)]
173162
pub struct MissingOkOrSomeInTailExpr {
174-
pub file: HirFileId,
175-
pub expr: AstPtr<ast::Expr>,
163+
pub expr: InFile<AstPtr<ast::Expr>>,
176164
// `Some` or `Ok` depending on whether the return type is Result or Option
177165
pub required: String,
178166
}
179167

180-
impl Diagnostic for MissingOkOrSomeInTailExpr {
181-
fn code(&self) -> DiagnosticCode {
182-
DiagnosticCode("missing-ok-or-some-in-tail-expr")
183-
}
184-
fn message(&self) -> String {
185-
format!("wrap return expression in {}", self.required)
186-
}
187-
fn display_source(&self) -> InFile<SyntaxNodePtr> {
188-
InFile { file_id: self.file, value: self.expr.clone().into() }
189-
}
190-
fn as_any(&self) -> &(dyn Any + Send + 'static) {
191-
self
192-
}
193-
}
194-
195168
// Diagnostic: missing-match-arm
196169
//
197170
// This diagnostic is triggered if `match` block is missing one or more match arms.

crates/hir/src/lib.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,11 +1190,7 @@ impl Function {
11901190
}
11911191
BodyValidationDiagnostic::MissingOkOrSomeInTailExpr { expr, required } => {
11921192
match source_map.expr_syntax(expr) {
1193-
Ok(source_ptr) => sink.push(MissingOkOrSomeInTailExpr {
1194-
file: source_ptr.file_id,
1195-
expr: source_ptr.value,
1196-
required,
1197-
}),
1193+
Ok(expr) => acc.push(MissingOkOrSomeInTailExpr { expr, required }.into()),
11981194
Err(SyntheticSyntax) => (),
11991195
}
12001196
}

crates/ide/src/diagnostics.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod inactive_code;
99
mod macro_error;
1010
mod mismatched_arg_count;
1111
mod missing_fields;
12+
mod missing_ok_or_some_in_tail_expr;
1213
mod missing_unsafe;
1314
mod no_such_field;
1415
mod remove_this_semicolon;
@@ -163,9 +164,6 @@ pub(crate) fn diagnostics(
163164
}
164165
let res = RefCell::new(res);
165166
let sink_builder = DiagnosticSinkBuilder::new()
166-
.on::<hir::diagnostics::MissingOkOrSomeInTailExpr, _>(|d| {
167-
res.borrow_mut().push(diagnostic_with_fix(d, &sema, resolve));
168-
})
169167
.on::<hir::diagnostics::IncorrectCase, _>(|d| {
170168
res.borrow_mut().push(warning_with_fix(d, &sema, resolve));
171169
})
@@ -223,6 +221,7 @@ pub(crate) fn diagnostics(
223221
AnyDiagnostic::MacroError(d) => macro_error::macro_error(&ctx, &d),
224222
AnyDiagnostic::MismatchedArgCount(d) => mismatched_arg_count::mismatched_arg_count(&ctx, &d),
225223
AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d),
224+
AnyDiagnostic::MissingOkOrSomeInTailExpr(d) => missing_ok_or_some_in_tail_expr::missing_ok_or_some_in_tail_expr(&ctx, &d),
226225
AnyDiagnostic::MissingUnsafe(d) => missing_unsafe::missing_unsafe(&ctx, &d),
227226
AnyDiagnostic::NoSuchField(d) => no_such_field::no_such_field(&ctx, &d),
228227
AnyDiagnostic::RemoveThisSemicolon(d) => remove_this_semicolon::remove_this_semicolon(&ctx, &d),

crates/ide/src/diagnostics/fixes.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! The same module also has all curret custom fixes for the diagnostics implemented.
33
mod change_case;
44
mod replace_with_find_map;
5-
mod wrap_tail_expr;
65

76
use hir::{diagnostics::Diagnostic, Semantics};
87
use ide_assists::AssistResolveStrategy;

crates/ide/src/diagnostics/fixes/wrap_tail_expr.rs renamed to crates/ide/src/diagnostics/missing_ok_or_some_in_tail_expr.rs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,45 @@
1-
use hir::{db::AstDatabase, diagnostics::MissingOkOrSomeInTailExpr, Semantics};
2-
use ide_assists::{Assist, AssistResolveStrategy};
3-
use ide_db::{source_change::SourceChange, RootDatabase};
1+
use hir::{db::AstDatabase, Semantics};
2+
use ide_assists::Assist;
3+
use ide_db::source_change::SourceChange;
44
use syntax::AstNode;
55
use text_edit::TextEdit;
66

7-
use crate::diagnostics::{fix, DiagnosticWithFixes};
8-
9-
impl DiagnosticWithFixes for MissingOkOrSomeInTailExpr {
10-
fn fixes(
11-
&self,
12-
sema: &Semantics<RootDatabase>,
13-
_resolve: &AssistResolveStrategy,
14-
) -> Option<Vec<Assist>> {
15-
let root = sema.db.parse_or_expand(self.file)?;
16-
let tail_expr = self.expr.to_node(&root);
17-
let tail_expr_range = tail_expr.syntax().text_range();
18-
let replacement = format!("{}({})", self.required, tail_expr.syntax());
19-
let edit = TextEdit::replace(tail_expr_range, replacement);
20-
let source_change = SourceChange::from_text_edit(self.file.original_file(sema.db), edit);
21-
let name = if self.required == "Ok" { "Wrap with Ok" } else { "Wrap with Some" };
22-
Some(vec![fix("wrap_tail_expr", name, source_change, tail_expr_range)])
23-
}
7+
use crate::diagnostics::{fix, Diagnostic, DiagnosticsContext};
8+
9+
// Diagnostic: missing-ok-or-some-in-tail-expr
10+
//
11+
// This diagnostic is triggered if a block that should return `Result` returns a value not wrapped in `Ok`,
12+
// or if a block that should return `Option` returns a value not wrapped in `Some`.
13+
//
14+
// Example:
15+
//
16+
// ```rust
17+
// fn foo() -> Result<u8, ()> {
18+
// 10
19+
// }
20+
// ```
21+
pub(super) fn missing_ok_or_some_in_tail_expr(
22+
ctx: &DiagnosticsContext<'_>,
23+
d: &hir::MissingOkOrSomeInTailExpr,
24+
) -> Diagnostic {
25+
Diagnostic::new(
26+
"missing-ok-or-some-in-tail-expr",
27+
format!("wrap return expression in {}", d.required),
28+
ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
29+
)
30+
.with_fixes(fixes(ctx, d))
31+
}
32+
33+
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingOkOrSomeInTailExpr) -> Option<Vec<Assist>> {
34+
let root = ctx.sema.db.parse_or_expand(d.expr.file_id)?;
35+
let tail_expr = d.expr.value.to_node(&root);
36+
let tail_expr_range = tail_expr.syntax().text_range();
37+
let replacement = format!("{}({})", d.required, tail_expr.syntax());
38+
let edit = TextEdit::replace(tail_expr_range, replacement);
39+
let source_change =
40+
SourceChange::from_text_edit(d.expr.file_id.original_file(ctx.sema.db), edit);
41+
let name = if d.required == "Ok" { "Wrap with Ok" } else { "Wrap with Some" };
42+
Some(vec![fix("wrap_tail_expr", name, source_change, tail_expr_range)])
2443
}
2544

2645
#[cfg(test)]

0 commit comments

Comments
 (0)