diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 4cc04fff633..89e03a98d6f 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -1346,8 +1346,8 @@ struct SomeStruct { } impl PartialEq for SomeStruct { $0fn ne(&self, other: &Self) -> bool { - !self.eq(other) - } + !self.eq(other) + } } "#, ); @@ -1520,48 +1520,47 @@ fn main() { } #[test] - fn test_add_missing_impl_members_indentation() { - // few trait members, no braces + fn test_add_missing_preserves_indentation() { + // in different modules check_assist( add_missing_impl_members, r#" mod m { - trait Foo { fn foo(&self); } - struct S; - impl Foo for S$0 -}"#, + pub trait Foo { + const CONST_MULTILINE: ( + i32, + i32 + ); + + fn foo(&self); + } +} +struct S; +impl m::Foo for S { $0 }"#, r#" mod m { - trait Foo { fn foo(&self); } - struct S; - impl Foo for S { - fn foo(&self) { - ${0:todo!()} - } + pub trait Foo { + const CONST_MULTILINE: ( + i32, + i32 + ); + + fn foo(&self); + } +} +struct S; +impl m::Foo for S { + $0const CONST_MULTILINE: ( + i32, + i32 + ); + + fn foo(&self) { + todo!() } }"#, ); - // few trait members, empty impl def. - check_assist( - add_missing_impl_members, - r#" -mod m { - trait Foo { fn foo(&self); } - struct S; - impl Foo for S { $0 } -}"#, - r#" -mod m { - trait Foo { fn foo(&self); } - struct S; - impl Foo for S { - fn foo(&self) { - ${0:todo!()} - } - } -}"#, - ); - // todo - in mod and outside + // in the same module check_assist( add_missing_impl_members, r#" @@ -1571,6 +1570,10 @@ mod m { const CONST: usize = 42; const CONST_2: i32; + const CONST_MULTILINE: ( + i32, + i32 + ); fn foo(&self); fn bar(&self); @@ -1591,6 +1594,10 @@ mod m { const CONST: usize = 42; const CONST_2: i32; + const CONST_MULTILINE: ( + i32, + i32 + ); fn foo(&self); fn bar(&self); @@ -1606,6 +1613,11 @@ mod m { const CONST_2: i32; + const CONST_MULTILINE: ( + i32, + i32 + ); + fn foo(&self) { todo!() } @@ -1618,4 +1630,56 @@ mod m { }"#, ); } + + #[test] + fn test_add_default_preserves_indentation() { + check_assist( + add_missing_default_members, + r#" +mod m { + pub trait Foo { + type Output; + + const CONST: usize = 42; + const CONST_2: i32; + const CONST_MULTILINE: = ( + i32, + i32, + ) = (3, 14); + + fn valid(some: u32) -> bool { false } + fn foo(some: u32) -> bool; + } +} +struct S; +impl m::Foo for S { $0 }"#, + r#" +mod m { + pub trait Foo { + type Output; + + const CONST: usize = 42; + const CONST_2: i32; + const CONST_MULTILINE: = ( + i32, + i32, + ) = (3, 14); + + fn valid(some: u32) -> bool { false } + fn foo(some: u32) -> bool; + } +} +struct S; +impl m::Foo for S { + $0const CONST: usize = 42; + + const CONST_MULTILINE: = ( + i32, + i32, + ) = (3, 14); + + fn valid(some: u32) -> bool { false } +}"#, + ) + } } diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 1c9d4157cd6..8f7ea26306c 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -10,7 +10,7 @@ use syntax::{ ast::{ self, edit::{AstNodeEdit, IndentLevel}, - edit_in_place::{AttrsOwnerEdit, Removable}, + edit_in_place::{AttrsOwnerEdit, Indent, Removable}, make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, ted, AstNode, AstToken, Direction, SourceFile, @@ -139,9 +139,11 @@ pub fn add_trait_assoc_items_to_impl( let transform = PathTransform::trait_impl(&target_scope, &source_scope, trait_, impl_.clone()); + let new_indent_level = IndentLevel::from_node(impl_.syntax()) + 1; let items = items.into_iter().map(|assoc_item| { transform.apply(assoc_item.syntax()); assoc_item.remove_attrs_and_docs(); + assoc_item.reindent_to(new_indent_level); assoc_item }); @@ -153,8 +155,10 @@ pub fn add_trait_assoc_items_to_impl( first_item.get_or_insert_with(|| item.clone()); match &item { ast::AssocItem::Fn(fn_) if fn_.body().is_none() => { - let body = make::block_expr(None, Some(make::ext::expr_todo())) - .indent(IndentLevel::from_node(impl_.syntax()) + 1); + let body = AstNodeEdit::indent( + &make::block_expr(None, Some(make::ext::expr_todo())), + new_indent_level, + ); ted::replace(fn_.get_or_create_body().syntax(), body.clone_for_update().syntax()) } ast::AssocItem::TypeAlias(type_alias) => {