Skip to content

Commit c7e4b1a

Browse files
authored
Merge pull request #21952 from A4-Tacks/macro-call-ty-mismatch-fixes
fix: offer 'type_mismatch' some fixes inside macro
2 parents a429358 + 6592c74 commit c7e4b1a

1 file changed

Lines changed: 61 additions & 14 deletions

File tree

crates/ide-diagnostics/src/handlers/type_mismatch.rs

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn add_missing_ok_or_some(
110110
) -> Option<()> {
111111
let root = ctx.sema.db.parse_or_expand(expr_ptr.file_id);
112112
let expr = expr_ptr.value.to_node(&root);
113-
let expr_range = expr.syntax().text_range();
113+
let expr_range = ctx.sema.original_range_opt(expr.syntax())?.range;
114114
let scope = ctx.sema.scope(expr.syntax())?;
115115

116116
let expected_adt = d.expected.as_adt()?;
@@ -144,13 +144,13 @@ fn add_missing_ok_or_some(
144144
// Empty block
145145
let indent = block_indent + 1;
146146
builder.insert(
147-
block.syntax().text_range().start() + TextSize::from(1),
147+
expr_range.start() + TextSize::from(1),
148148
format!("\n{indent}{variant_name}(())\n{block_indent}"),
149149
);
150150
} else {
151151
let indent = IndentLevel::from(1);
152152
builder.insert(
153-
block.syntax().text_range().end() - TextSize::from(1),
153+
expr_range.end() - TextSize::from(1),
154154
format!("{indent}{variant_name}(())\n{block_indent}"),
155155
);
156156
}
@@ -167,8 +167,7 @@ fn add_missing_ok_or_some(
167167
// Fix for forms like `fn foo() -> Result<(), String> { return; }`
168168
if ret_expr.expr().is_none() {
169169
let mut builder = TextEdit::builder();
170-
builder
171-
.insert(ret_expr.syntax().text_range().end(), format!(" {variant_name}(())"));
170+
builder.insert(expr_range.end(), format!(" {variant_name}(())"));
172171
let source_change = SourceChange::from_text_edit(
173172
expr_ptr.file_id.original_file(ctx.sema.db).file_id(ctx.sema.db),
174173
builder.finish(),
@@ -181,8 +180,8 @@ fn add_missing_ok_or_some(
181180
}
182181

183182
let mut builder = TextEdit::builder();
184-
builder.insert(expr.syntax().text_range().start(), format!("{variant_name}("));
185-
builder.insert(expr.syntax().text_range().end(), ")".to_owned());
183+
builder.insert(expr_range.start(), format!("{variant_name}("));
184+
builder.insert(expr_range.end(), ")".to_owned());
186185
let source_change = SourceChange::from_text_edit(
187186
expr_ptr.file_id.original_file(ctx.sema.db).file_id(ctx.sema.db),
188187
builder.finish(),
@@ -201,6 +200,7 @@ fn remove_unnecessary_wrapper(
201200
let db = ctx.sema.db;
202201
let root = db.parse_or_expand(expr_ptr.file_id);
203202
let expr = expr_ptr.value.to_node(&root);
203+
// FIXME: support inside MacroCall?
204204
let expr = ctx.sema.original_ast_node(expr)?;
205205

206206
let Expr::CallExpr(call_expr) = expr else {
@@ -287,6 +287,7 @@ fn remove_semicolon(
287287
return None;
288288
}
289289
let block = BlockExpr::cast(expr.syntax().clone())?;
290+
// FIXME: support inside MacroCall?
290291
let expr_before_semi =
291292
block.statements().last().and_then(|s| ExprStmt::cast(s.syntax().clone()))?;
292293
let type_before_semi = ctx.sema.type_of_expr(&expr_before_semi.expr()?)?.original();
@@ -320,16 +321,13 @@ fn str_ref_to_owned(
320321

321322
let root = ctx.sema.db.parse_or_expand(expr_ptr.file_id);
322323
let expr = expr_ptr.value.to_node(&root);
323-
let expr_range = expr.syntax().text_range();
324+
let hir::FileRange { file_id, range } = ctx.sema.original_range_opt(expr.syntax())?;
324325

325326
let to_owned = ".to_owned()".to_owned();
326327

327-
let edit = TextEdit::insert(expr.syntax().text_range().end(), to_owned);
328-
let source_change = SourceChange::from_text_edit(
329-
expr_ptr.file_id.original_file(ctx.sema.db).file_id(ctx.sema.db),
330-
edit,
331-
);
332-
acc.push(fix("str_ref_to_owned", "Add .to_owned() here", source_change, expr_range));
328+
let edit = TextEdit::insert(range.end(), to_owned);
329+
let source_change = SourceChange::from_text_edit(file_id.file_id(ctx.sema.db), edit);
330+
acc.push(fix("str_ref_to_owned", "Add .to_owned() here", source_change, range));
333331

334332
Some(())
335333
}
@@ -575,6 +573,32 @@ fn div(x: i32, y: i32) -> Result<i32, ()> {
575573
}
576574
Ok(x / y)
577575
}
576+
"#,
577+
);
578+
579+
check_fix(
580+
r#"
581+
//- minicore: option, result
582+
macro_rules! identity { ($($t:tt)*) => ($($t)*) }
583+
identity! {
584+
fn div(x: i32, y: i32) -> Result<i32, ()> {
585+
if y == 0 {
586+
return Err(());
587+
}
588+
x / y$0
589+
}
590+
}
591+
"#,
592+
r#"
593+
macro_rules! identity { ($($t:tt)*) => ($($t)*) }
594+
identity! {
595+
fn div(x: i32, y: i32) -> Result<i32, ()> {
596+
if y == 0 {
597+
return Err(());
598+
}
599+
Ok(x / y)
600+
}
601+
}
578602
"#,
579603
);
580604
}
@@ -1046,6 +1070,29 @@ struct String;
10461070
10471071
fn test() -> String {
10481072
"a".to_owned()
1073+
}
1074+
"#,
1075+
);
1076+
1077+
check_fix(
1078+
r#"
1079+
macro_rules! identity { ($($t:tt)*) => ($($t)*) }
1080+
struct String;
1081+
1082+
identity! {
1083+
fn test() -> String {
1084+
"a"$0
1085+
}
1086+
}
1087+
"#,
1088+
r#"
1089+
macro_rules! identity { ($($t:tt)*) => ($($t)*) }
1090+
struct String;
1091+
1092+
identity! {
1093+
fn test() -> String {
1094+
"a".to_owned()
1095+
}
10491096
}
10501097
"#,
10511098
);

0 commit comments

Comments
 (0)