diff options
| author | Ali Bektas <bektasali@protonmail.com> | 2025-03-17 22:37:21 +0100 |
|---|---|---|
| committer | Ali Bektas <bektasali@protonmail.com> | 2025-03-17 22:37:21 +0100 |
| commit | d88a6159eaed3f6ef33277bbd817a48b9a11b51c (patch) | |
| tree | a2adf758956021199af5f98638982cb8ff2ba5fc | |
| parent | 1919a66f9377d49c356a49953bc0d2e6e43c8b57 (diff) | |
| download | rust-d88a6159eaed3f6ef33277bbd817a48b9a11b51c.tar.gz rust-d88a6159eaed3f6ef33277bbd817a48b9a11b51c.zip | |
Test unsafeness is respected when manual impling derives
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 8ff9fe09b56..e0693a7d5b6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -131,7 +131,7 @@ fn add_assist( target, |builder| { let insert_after = ted::Position::after(builder.make_mut(adt.clone()).syntax()); - + let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false); let impl_def_with_items = impl_def_from_trait(&ctx.sema, adt, &annotated_name, trait_, replace_trait_path); update_attribute(builder, old_derives, old_tree, old_trait_path, attr); @@ -141,6 +141,12 @@ fn add_assist( match (ctx.config.snippet_cap, impl_def_with_items) { (None, None) => { let impl_def = generate_trait_impl(adt, trait_path); + if impl_is_unsafe { + ted::insert( + Position::first_child_of(impl_def.syntax()), + make::token(T![unsafe]), + ); + } ted::insert_all( insert_after, @@ -148,6 +154,12 @@ fn add_assist( ); } (None, Some((impl_def, _))) => { + if impl_is_unsafe { + ted::insert( + Position::first_child_of(impl_def.syntax()), + make::token(T![unsafe]), + ); + } ted::insert_all( insert_after, vec![make::tokens::blank_line().into(), impl_def.syntax().clone().into()], @@ -156,6 +168,13 @@ fn add_assist( (Some(cap), None) => { let impl_def = generate_trait_impl(adt, trait_path); + if impl_is_unsafe { + ted::insert( + Position::first_child_of(impl_def.syntax()), + make::token(T![unsafe]), + ); + } + if let Some(l_curly) = impl_def.assoc_item_list().and_then(|it| it.l_curly_token()) { @@ -169,6 +188,14 @@ fn add_assist( } (Some(cap), Some((impl_def, first_assoc_item))) => { let mut added_snippet = false; + + if impl_is_unsafe { + ted::insert( + Position::first_child_of(impl_def.syntax()), + make::token(T![unsafe]), + ); + } + if let ast::AssocItem::Fn(ref func) = first_assoc_item { if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) { @@ -223,10 +250,6 @@ 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); @@ -1409,4 +1432,21 @@ impl core::fmt::Debug for Foo { "#, ) } + + #[test] + fn unsafeness_of_a_trait_observed() { + check_assist( + replace_derive_with_manual_impl, + r#" +//- minicore: send, derive +#[derive(Sen$0d)] +pub struct Foo; +"#, + r#" +pub struct Foo; + +unsafe impl Send for Foo {$0} +"#, + ) + } } |
