@@ -84,6 +84,7 @@ pub(crate) fn rename(
8484 db : & RootDatabase ,
8585 position : FilePosition ,
8686 new_name : & str ,
87+ rename_external : bool ,
8788) -> RenameResult < SourceChange > {
8889 let sema = Semantics :: new ( db) ;
8990 let source_file = sema. parse ( position. file_id ) ;
@@ -103,7 +104,7 @@ pub(crate) fn rename(
103104 return rename_to_self ( & sema, local) ;
104105 }
105106 }
106- def. rename ( & sema, new_name)
107+ def. rename ( & sema, new_name, rename_external )
107108 } )
108109 . collect ( ) ;
109110
@@ -122,9 +123,9 @@ pub(crate) fn will_rename_file(
122123 let module = sema. to_module_def ( file_id) ?;
123124 let def = Definition :: Module ( module) ;
124125 let mut change = if is_raw_identifier ( new_name_stem) {
125- def. rename ( & sema, & SmolStr :: from_iter ( [ "r#" , new_name_stem] ) ) . ok ( ) ?
126+ def. rename ( & sema, & SmolStr :: from_iter ( [ "r#" , new_name_stem] ) , true ) . ok ( ) ?
126127 } else {
127- def. rename ( & sema, new_name_stem) . ok ( ) ?
128+ def. rename ( & sema, new_name_stem, true ) . ok ( ) ?
128129 } ;
129130 change. file_system_edits . clear ( ) ;
130131 Some ( change)
@@ -371,12 +372,21 @@ mod tests {
371372 use test_utils:: assert_eq_text;
372373 use text_edit:: TextEdit ;
373374
374- use crate :: { fixture, FileId } ;
375+ use crate :: fixture;
375376
376377 use super :: { RangeInfo , RenameError } ;
377378
378- #[ track_caller]
379379 fn check ( new_name : & str , ra_fixture_before : & str , ra_fixture_after : & str ) {
380+ check_with_rename_config ( new_name, ra_fixture_before, ra_fixture_after, true ) ;
381+ }
382+
383+ #[ track_caller]
384+ fn check_with_rename_config (
385+ new_name : & str ,
386+ ra_fixture_before : & str ,
387+ ra_fixture_after : & str ,
388+ rename_external : bool ,
389+ ) {
380390 let ra_fixture_after = & trim_indent ( ra_fixture_after) ;
381391 let ( analysis, position) = fixture:: position ( ra_fixture_before) ;
382392 if !ra_fixture_after. starts_with ( "error: " ) {
@@ -385,23 +395,22 @@ mod tests {
385395 }
386396 }
387397 let rename_result = analysis
388- . rename ( position, new_name)
398+ . rename ( position, new_name, rename_external )
389399 . unwrap_or_else ( |err| panic ! ( "Rename to '{new_name}' was cancelled: {err}" ) ) ;
390400 match rename_result {
391401 Ok ( source_change) => {
392402 let mut text_edit_builder = TextEdit :: builder ( ) ;
393- let mut file_id: Option < FileId > = None ;
394- for edit in source_change. source_file_edits {
395- file_id = Some ( edit. 0 ) ;
396- for indel in edit. 1 . 0 . into_iter ( ) {
397- text_edit_builder. replace ( indel. delete , indel. insert ) ;
398- }
399- }
400- if let Some ( file_id) = file_id {
401- let mut result = analysis. file_text ( file_id) . unwrap ( ) . to_string ( ) ;
402- text_edit_builder. finish ( ) . apply ( & mut result) ;
403- assert_eq_text ! ( ra_fixture_after, & * result) ;
403+ let ( & file_id, edit) = match source_change. source_file_edits . len ( ) {
404+ 0 => return ,
405+ 1 => source_change. source_file_edits . iter ( ) . next ( ) . unwrap ( ) ,
406+ _ => ( & position. file_id , & source_change. source_file_edits [ & position. file_id ] ) ,
407+ } ;
408+ for indel in edit. 0 . iter ( ) {
409+ text_edit_builder. replace ( indel. delete , indel. insert . clone ( ) ) ;
404410 }
411+ let mut result = analysis. file_text ( file_id) . unwrap ( ) . to_string ( ) ;
412+ text_edit_builder. finish ( ) . apply ( & mut result) ;
413+ assert_eq_text ! ( ra_fixture_after, & * result) ;
405414 }
406415 Err ( err) => {
407416 if ra_fixture_after. starts_with ( "error:" ) {
@@ -417,8 +426,10 @@ mod tests {
417426
418427 fn check_expect ( new_name : & str , ra_fixture : & str , expect : Expect ) {
419428 let ( analysis, position) = fixture:: position ( ra_fixture) ;
420- let source_change =
421- analysis. rename ( position, new_name) . unwrap ( ) . expect ( "Expect returned a RenameError" ) ;
429+ let source_change = analysis
430+ . rename ( position, new_name, true )
431+ . unwrap ( )
432+ . expect ( "Expect returned a RenameError" ) ;
422433 expect. assert_eq ( & filter_expect ( source_change) )
423434 }
424435
@@ -2617,6 +2628,18 @@ use qux as frob;
26172628
26182629 #[ test]
26192630 fn disallow_renaming_for_non_local_definition ( ) {
2631+ check_with_rename_config (
2632+ "Baz" ,
2633+ r#"
2634+ //- /lib.rs crate:lib new_source_root:library
2635+ pub struct S;
2636+ //- /main.rs crate:main deps:lib new_source_root:local
2637+ use lib::S$0;
2638+ "# ,
2639+ "error: Cannot rename a non-local definition. Set `renameExternalItems` to `true` to allow renaming for this item." ,
2640+ false ,
2641+ ) ;
2642+
26202643 check (
26212644 "Baz" ,
26222645 r#"
@@ -2625,13 +2648,13 @@ pub struct S;
26252648//- /main.rs crate:main deps:lib new_source_root:local
26262649use lib::S$0;
26272650"# ,
2628- "error: Cannot rename a non-local definition. " ,
2651+ "use lib::Baz; \n " ,
26292652 ) ;
26302653 }
26312654
26322655 #[ test]
26332656 fn disallow_renaming_for_builtin_macros ( ) {
2634- check (
2657+ check_with_rename_config (
26352658 "Baz" ,
26362659 r#"
26372660//- minicore: derive, hash
@@ -2640,8 +2663,9 @@ use core::hash::Hash;
26402663#[derive(H$0ash)]
26412664struct A;
26422665 "# ,
2643- "error: Cannot rename a non-local definition." ,
2644- )
2666+ "error: Cannot rename a non-local definition. Set `renameExternalItems` to `true` to allow renaming for this item." ,
2667+ false ,
2668+ ) ;
26452669 }
26462670
26472671 #[ test]
0 commit comments