diff options
| author | Ryan Mehri <ryan.mehri1@gmail.com> | 2023-10-27 10:25:29 -0700 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2024-01-02 10:33:48 +0100 |
| commit | 9f6a2c4564b786cceb75f165e25fab53c1047ccf (patch) | |
| tree | 57d6ab585c8b7a4ad54bff21ada01ea0f7044f7c | |
| parent | b5e0edf427e13711c20b3a01e624e60954172232 (diff) | |
| download | rust-9f6a2c4564b786cceb75f165e25fab53c1047ccf.tar.gz rust-9f6a2c4564b786cceb75f165e25fab53c1047ccf.zip | |
fix: use original range to deal with macros in bool_to_enum
| -rw-r--r-- | crates/ide-assists/src/handlers/bool_to_enum.rs | 100 |
1 files changed, 91 insertions, 9 deletions
diff --git a/crates/ide-assists/src/handlers/bool_to_enum.rs b/crates/ide-assists/src/handlers/bool_to_enum.rs index 0c4d4ad0e55..0751be1fd14 100644 --- a/crates/ide-assists/src/handlers/bool_to_enum.rs +++ b/crates/ide-assists/src/handlers/bool_to_enum.rs @@ -169,8 +169,8 @@ fn replace_bool_expr(edit: &mut SourceChangeBuilder, expr: ast::Expr) { /// Converts an expression of type `bool` to one of the new enum type. fn bool_expr_to_enum_expr(expr: ast::Expr) -> ast::Expr { - let true_expr = make::expr_path(make::path_from_text("Bool::True")).clone_for_update(); - let false_expr = make::expr_path(make::path_from_text("Bool::False")).clone_for_update(); + let true_expr = make::expr_path(make::path_from_text("Bool::True")); + let false_expr = make::expr_path(make::path_from_text("Bool::False")); if let ast::Expr::Literal(literal) = &expr { match literal.kind() { @@ -184,7 +184,6 @@ fn bool_expr_to_enum_expr(expr: ast::Expr) -> ast::Expr { make::tail_only_block_expr(true_expr), Some(ast::ElseBranch::Block(make::tail_only_block_expr(false_expr))), ) - .clone_for_update() } } @@ -239,7 +238,7 @@ fn replace_usages( cov_mark::hit!(replaces_record_expr); let enum_expr = bool_expr_to_enum_expr(initializer); - replace_record_field_expr(edit, record_field, enum_expr); + replace_record_field_expr(ctx, edit, record_field, enum_expr); } else if let Some(pat) = find_record_pat_field_usage(&name) { match pat { ast::Pat::IdentPat(ident_pat) => { @@ -283,6 +282,7 @@ fn replace_usages( ) { replace_record_field_expr( + ctx, edit, record_field, make::expr_bin_op( @@ -312,19 +312,19 @@ fn replace_usages( /// Replaces the record expression, handling field shorthands. fn replace_record_field_expr( + ctx: &AssistContext<'_>, edit: &mut SourceChangeBuilder, record_field: ast::RecordExprField, initializer: ast::Expr, ) { if let Some(ast::Expr::PathExpr(path_expr)) = record_field.expr() { // replace field shorthand - edit.insert( - path_expr.syntax().text_range().end(), - format!(": {}", initializer.syntax().text()), - ) + let file_range = ctx.sema.original_range(path_expr.syntax()); + edit.insert(file_range.range.end(), format!(": {}", initializer.syntax().text())) } else if let Some(expr) = record_field.expr() { // just replace expr - edit.replace_ast(expr, initializer); + let file_range = ctx.sema.original_range(expr.syntax()); + edit.replace(file_range.range, initializer.syntax().text()); } } @@ -839,6 +839,48 @@ fn main() { } #[test] + fn local_var_init_struct_usage_in_macro() { + check_assist( + bool_to_enum, + r#" +struct Struct { + boolean: bool, +} + +macro_rules! identity { + ($body:expr) => { + $body + } +} + +fn new() -> Struct { + let $0boolean = true; + identity![Struct { boolean }] +} +"#, + r#" +struct Struct { + boolean: bool, +} + +macro_rules! identity { + ($body:expr) => { + $body + } +} + +#[derive(PartialEq, Eq)] +enum Bool { True, False } + +fn new() -> Struct { + let boolean = Bool::True; + identity![Struct { boolean: boolean == Bool::True }] +} +"#, + ) + } + + #[test] fn field_struct_basic() { cov_mark::check!(replaces_record_expr); check_assist( @@ -1360,6 +1402,46 @@ fn main() { } #[test] + fn field_in_macro() { + check_assist( + bool_to_enum, + r#" +struct Struct { + $0boolean: bool, +} + +fn boolean(x: Struct) { + let Struct { boolean } = x; +} + +macro_rules! identity { ($body:expr) => { $body } } + +fn new() -> Struct { + identity!(Struct { boolean: true }) +} +"#, + r#" +#[derive(PartialEq, Eq)] +enum Bool { True, False } + +struct Struct { + boolean: Bool, +} + +fn boolean(x: Struct) { + let Struct { boolean } = x; +} + +macro_rules! identity { ($body:expr) => { $body } } + +fn new() -> Struct { + identity!(Struct { boolean: Bool::True }) +} +"#, + ) + } + + #[test] fn field_non_bool() { cov_mark::check!(not_applicable_non_bool_field); check_assist_not_applicable( |
