From d7e35bc52fd0ee815ffc1208545f44c6d8794fb7 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Sat, 8 Mar 2025 14:13:51 +0100 Subject: [PATCH 1/2] Observe unsafeness when generating manual impls of former derives --- .../src/handlers/add_missing_impl_members.rs | 29 +++++++++++++++++++ crates/ide-assists/src/utils.rs | 7 ++++- crates/syntax/src/ast/make.rs | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) 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 57df39d541e9..72927c4d38aa 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -2363,4 +2363,33 @@ impl other_file_2::Trait for MyStruct { }"#, ); } + + #[test] + fn unsafeness_observed() { + check_assist( + add_missing_impl_members, + r#" +unsafe trait UnsafeTrait { + unsafe fn unsafe_fn(); +} + +struct A {} + +impl Uns$0afeTrait for A {} + "#, + r#" +unsafe trait UnsafeTrait { + unsafe fn unsafe_fn(); +} + +struct A {} + +unsafe impl UnsafeTrait for A { + unsafe fn unsafe_fn() { + ${0:todo!()} + } +} + "#, + ); + } } diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 39686f065a9c..9842c3d830cc 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -21,7 +21,8 @@ use syntax::{ syntax_factory::SyntaxFactory, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, - ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, + ted::{self, Position}, + AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, SyntaxKind::*, SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T, }; @@ -215,6 +216,10 @@ pub fn add_trait_assoc_items_to_impl( }); let assoc_item_list = impl_.get_or_create_assoc_item_list(); + if trait_.is_unsafe(sema.db) { + ted::insert(Position::first_child_of(impl_.syntax()), make::token(T![unsafe])); + } + let mut first_item = None; for item in items { first_item.get_or_insert_with(|| item.clone()); diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 231c21c38f85..f9e1c517ac92 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -1274,7 +1274,7 @@ pub mod tokens { pub(super) static SOURCE_FILE: LazyLock> = LazyLock::new(|| { SourceFile::parse( - "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] })\n;\n\nimpl A for B where: {}", Edition::CURRENT, + "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] })\n;\n\nunsafe impl A for B where: {}", Edition::CURRENT, ) }); From fc8faf0900d368f73f6171459cb7baa27e6c2fa7 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Sun, 9 Mar 2025 18:47:40 +0100 Subject: [PATCH 2/2] Observe unsafeness only for replace_derive_with_manual_impl --- .../src/handlers/add_missing_impl_members.rs | 29 ------------------- .../replace_derive_with_manual_impl.rs | 6 +++- crates/ide-assists/src/utils.rs | 5 +--- 3 files changed, 6 insertions(+), 34 deletions(-) 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 72927c4d38aa..57df39d541e9 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -2363,33 +2363,4 @@ impl other_file_2::Trait for MyStruct { }"#, ); } - - #[test] - fn unsafeness_observed() { - check_assist( - add_missing_impl_members, - r#" -unsafe trait UnsafeTrait { - unsafe fn unsafe_fn(); -} - -struct A {} - -impl Uns$0afeTrait for A {} - "#, - r#" -unsafe trait UnsafeTrait { - unsafe fn unsafe_fn(); -} - -struct A {} - -unsafe impl UnsafeTrait for A { - unsafe fn unsafe_fn() { - ${0:todo!()} - } -} - "#, - ); - } } diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 31e828eae271..6da151fa5931 100644 --- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -3,7 +3,7 @@ use ide_db::{helpers::mod_path_to_ast, imports::import_assets::NameToImport, ite use itertools::Itertools; use syntax::{ ast::{self, make, AstNode, HasName}, - ted, + ted::{self, Position}, SyntaxKind::WHITESPACE, T, }; @@ -223,6 +223,10 @@ fn impl_def_from_trait( let first_assoc_item = add_trait_assoc_items_to_impl(sema, &trait_items, trait_, &impl_def, &target_scope); + if trait_.is_unsafe(sema.db) { + ted::insert(Position::first_child_of(impl_def.syntax()), make::token(T![unsafe])); + } + // Generate a default `impl` function body for the derived trait. if let ast::AssocItem::Fn(ref func) = first_assoc_item { let _ = gen_trait_fn_body(func, trait_path, adt, None); diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 9842c3d830cc..991e6b6af778 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -21,7 +21,7 @@ use syntax::{ syntax_factory::SyntaxFactory, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, - ted::{self, Position}, + ted::{self}, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile, SyntaxKind::*, SyntaxNode, SyntaxToken, TextRange, TextSize, WalkEvent, T, @@ -216,9 +216,6 @@ pub fn add_trait_assoc_items_to_impl( }); let assoc_item_list = impl_.get_or_create_assoc_item_list(); - if trait_.is_unsafe(sema.db) { - ted::insert(Position::first_child_of(impl_.syntax()), make::token(T![unsafe])); - } let mut first_item = None; for item in items {