Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/ide-assists/src/assist_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ide_db::{
SnippetCap,
assists::ExprFillDefaultMode,
imports::{import_assets::ImportPathConfig, insert_use::InsertUseConfig},
rename::RenameConfig,
};

use crate::AssistKind;
Expand All @@ -27,6 +28,7 @@ pub struct AssistConfig {
pub code_action_grouping: bool,
pub expr_fill_default: ExprFillDefaultMode,
pub prefer_self_ty: bool,
pub show_rename_conflicts: bool,
}

impl AssistConfig {
Expand All @@ -46,4 +48,8 @@ impl AssistConfig {
allow_unstable,
}
}

pub fn rename_config(&self) -> RenameConfig {
RenameConfig { show_conflicts: self.show_rename_conflicts }
}
}
4 changes: 3 additions & 1 deletion crates/ide-assists/src/handlers/remove_underscore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
"Remove underscore from a used variable",
text_range,
|builder| {
let changes = def.rename(&ctx.sema, new_name, RenameDefinition::Yes).unwrap();
let changes = def
.rename(&ctx.sema, new_name, RenameDefinition::Yes, &ctx.config.rename_config())
.unwrap();
builder.source_change = changes;
},
)
Expand Down
4 changes: 4 additions & 0 deletions crates/ide-assists/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
code_action_grouping: true,
expr_fill_default: ExprFillDefaultMode::Todo,
prefer_self_ty: false,
show_rename_conflicts: true,
};

pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig {
Expand All @@ -59,6 +60,7 @@ pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig {
code_action_grouping: false,
expr_fill_default: ExprFillDefaultMode::Todo,
prefer_self_ty: false,
show_rename_conflicts: true,
};

pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
Expand All @@ -80,6 +82,7 @@ pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
code_action_grouping: true,
expr_fill_default: ExprFillDefaultMode::Todo,
prefer_self_ty: false,
show_rename_conflicts: true,
};

pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
Expand All @@ -101,6 +104,7 @@ pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
code_action_grouping: true,
expr_fill_default: ExprFillDefaultMode::Todo,
prefer_self_ty: false,
show_rename_conflicts: true,
};

fn assists(
Expand Down
53 changes: 34 additions & 19 deletions crates/ide-db/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ use crate::{
traits::convert_to_def_in_trait,
};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RenameConfig {
pub show_conflicts: bool,
}

pub type Result<T, E = RenameError> = std::result::Result<T, E>;

#[derive(Debug)]
Expand Down Expand Up @@ -81,6 +86,7 @@ impl Definition {
sema: &Semantics<'_, RootDatabase>,
new_name: &str,
rename_definition: RenameDefinition,
config: &RenameConfig,
) -> Result<SourceChange> {
// self.krate() returns None if
// self is a built-in attr, built-in type or tool module.
Expand Down Expand Up @@ -109,10 +115,15 @@ impl Definition {
bail!("Cannot rename a builtin attr.")
}
Definition::SelfType(_) => bail!("Cannot rename `Self`"),
Definition::Macro(mac) => {
rename_reference(sema, Definition::Macro(mac), new_name, rename_definition, edition)
}
def => rename_reference(sema, def, new_name, rename_definition, edition),
Definition::Macro(mac) => rename_reference(
sema,
Definition::Macro(mac),
new_name,
rename_definition,
edition,
config,
),
def => rename_reference(sema, def, new_name, rename_definition, edition, config),
}
}

Expand Down Expand Up @@ -338,6 +349,7 @@ fn rename_reference(
new_name: &str,
rename_definition: RenameDefinition,
edition: Edition,
config: &RenameConfig,
) -> Result<SourceChange> {
let (mut new_name, ident_kind) = IdentifierKind::classify(edition, new_name)?;

Expand Down Expand Up @@ -396,7 +408,8 @@ fn rename_reference(
if rename_definition == RenameDefinition::Yes {
// This needs to come after the references edits, because we change the annotation of existing edits
// if a conflict is detected.
let (file_id, edit) = source_edit_from_def(sema, def, &new_name, &mut source_change)?;
let (file_id, edit) =
source_edit_from_def(sema, config, def, &new_name, &mut source_change)?;
source_change.insert_source_edit(file_id, edit);
}
Ok(source_change)
Expand Down Expand Up @@ -554,6 +567,7 @@ fn source_edit_from_name_ref(

fn source_edit_from_def(
sema: &Semantics<'_, RootDatabase>,
config: &RenameConfig,
def: Definition,
new_name: &Name,
source_change: &mut SourceChange,
Expand All @@ -562,21 +576,22 @@ fn source_edit_from_def(
if let Definition::Local(local) = def {
let mut file_id = None;

let conflict_annotation = if !sema.rename_conflicts(&local, new_name).is_empty() {
Some(
source_change.insert_annotation(ChangeAnnotation {
label: "This rename will change the program's meaning".to_owned(),
needs_confirmation: true,
description: Some(
"Some variable(s) will shadow the renamed variable \
let conflict_annotation =
if config.show_conflicts && !sema.rename_conflicts(&local, new_name).is_empty() {
Some(
source_change.insert_annotation(ChangeAnnotation {
label: "This rename will change the program's meaning".to_owned(),
needs_confirmation: true,
description: Some(
"Some variable(s) will shadow the renamed variable \
or be shadowed by it if the rename is performed"
.to_owned(),
),
}),
)
} else {
None
};
.to_owned(),
),
}),
)
} else {
None
};

for source in local.sources(sema.db) {
let source = match source.source.clone().original_ast_node_rooted(sema.db) {
Expand Down
7 changes: 6 additions & 1 deletion crates/ide-diagnostics/src/handlers/incorrect_case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option<Vec<Ass
let label = format!("Rename to {}", d.suggested_text);
let mut res = unresolved_fix("change_case", &label, frange.range);
if ctx.resolve.should_resolve(&res.id) {
let source_change = def.rename(&ctx.sema, &d.suggested_text, RenameDefinition::Yes);
let source_change = def.rename(
&ctx.sema,
&d.suggested_text,
RenameDefinition::Yes,
&ctx.config.rename_config(),
);
res.source_change = Some(source_change.ok().unwrap_or_default());
}

Expand Down
7 changes: 7 additions & 0 deletions crates/ide-diagnostics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ use ide_db::{
generated::lints::{CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS, DEFAULT_LINTS, Lint, LintGroup},
imports::insert_use::InsertUseConfig,
label::Label,
rename::RenameConfig,
source_change::SourceChange,
syntax_helpers::node_ext::parse_tt_as_comma_sep_paths,
};
Expand Down Expand Up @@ -236,6 +237,7 @@ pub struct DiagnosticsConfig {
pub prefer_absolute: bool,
pub term_search_fuel: u64,
pub term_search_borrowck: bool,
pub show_rename_conflicts: bool,
}

impl DiagnosticsConfig {
Expand Down Expand Up @@ -264,8 +266,13 @@ impl DiagnosticsConfig {
prefer_absolute: false,
term_search_fuel: 400,
term_search_borrowck: true,
show_rename_conflicts: true,
}
}

pub fn rename_config(&self) -> RenameConfig {
RenameConfig { show_conflicts: self.show_rename_conflicts }
}
}

struct DiagnosticsContext<'a> {
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,8 +846,9 @@ impl Analysis {
&self,
file_id: FileId,
new_name_stem: &str,
config: &RenameConfig,
) -> Cancellable<Option<SourceChange>> {
self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem))
self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem, config))
}

pub fn structural_search_replace(
Expand Down
21 changes: 16 additions & 5 deletions crates/ide/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct RenameConfig {
pub prefer_no_std: bool,
pub prefer_prelude: bool,
pub prefer_absolute: bool,
pub show_conflicts: bool,
}

impl RenameConfig {
Expand All @@ -42,6 +43,10 @@ impl RenameConfig {
allow_unstable: true,
}
}

fn ide_db_config(&self) -> ide_db::rename::RenameConfig {
ide_db::rename::RenameConfig { show_conflicts: self.show_conflicts }
}
}

/// This is similar to `collect::<Result<Vec<_>, _>>`, but unlike it, it succeeds if there is *any* `Ok` item.
Expand Down Expand Up @@ -190,7 +195,7 @@ pub(crate) fn rename(
return rename_to_self(&sema, local);
}
}
def.rename(&sema, new_name.as_str(), rename_def)
def.rename(&sema, new_name.as_str(), rename_def, &config.ide_db_config())
})),
};

Expand All @@ -205,11 +210,13 @@ pub(crate) fn will_rename_file(
db: &RootDatabase,
file_id: FileId,
new_name_stem: &str,
config: &RenameConfig,
) -> Option<SourceChange> {
let sema = Semantics::new(db);
let module = sema.file_to_module_def(file_id)?;
let def = Definition::Module(module);
let mut change = def.rename(&sema, new_name_stem, RenameDefinition::Yes).ok()?;
let mut change =
def.rename(&sema, new_name_stem, RenameDefinition::Yes, &config.ide_db_config()).ok()?;
change.file_system_edits.clear();
Some(change)
}
Expand Down Expand Up @@ -803,8 +810,12 @@ mod tests {

use super::{RangeInfo, RenameConfig, RenameError};

const TEST_CONFIG: RenameConfig =
RenameConfig { prefer_no_std: false, prefer_prelude: true, prefer_absolute: false };
const TEST_CONFIG: RenameConfig = RenameConfig {
prefer_no_std: false,
prefer_prelude: true,
prefer_absolute: false,
show_conflicts: true,
};

#[track_caller]
fn check(
Expand Down Expand Up @@ -893,7 +904,7 @@ mod tests {
) {
let (analysis, position) = fixture::position(ra_fixture);
let source_change = analysis
.will_rename_file(position.file_id, new_name)
.will_rename_file(position.file_id, new_name, &TEST_CONFIG)
.unwrap()
.expect("Expect returned a RenameError");
expect.assert_eq(&filter_expect(source_change))
Expand Down
1 change: 1 addition & 0 deletions crates/rust-analyzer/src/cli/analysis_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,7 @@ impl flags::AnalysisStats {
style_lints: false,
term_search_fuel: 400,
term_search_borrowck: true,
show_rename_conflicts: true,
},
ide::AssistResolveStrategy::All,
analysis.editioned_file_id_to_vfs(file_id),
Expand Down
6 changes: 6 additions & 0 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,9 @@ config_data! {
///
/// E.g. `use ::std::io::Read;`.
imports_prefixExternPrelude: bool = false,

/// Whether to warn when a rename will cause conflicts (change the meaning of the code).
rename_showConflicts: bool = true,
}
}

Expand Down Expand Up @@ -1702,6 +1705,7 @@ impl Config {
ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore,
},
prefer_self_ty: *self.assist_preferSelf(source_root),
show_rename_conflicts: *self.rename_showConflicts(source_root),
}
}

Expand All @@ -1710,6 +1714,7 @@ impl Config {
prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
show_conflicts: *self.rename_showConflicts(source_root),
}
}

Expand Down Expand Up @@ -1809,6 +1814,7 @@ impl Config {
style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(),
term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
show_rename_conflicts: *self.rename_showConflicts(source_root),
}
}

Expand Down
6 changes: 5 additions & 1 deletion crates/rust-analyzer/src/handlers/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,11 @@ pub(crate) fn handle_will_rename_files(
}
})
.filter_map(|(file_id, new_name)| {
snap.analysis.will_rename_file(file_id?, &new_name).ok()?
let file_id = file_id?;
let source_root = snap.analysis.source_root_id(file_id).ok();
snap.analysis
.will_rename_file(file_id, &new_name, &snap.config.rename(source_root))
.ok()?
})
.collect();

Expand Down
1 change: 1 addition & 0 deletions crates/rust-analyzer/src/integrated_benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ fn integrated_diagnostics_benchmark() {
prefer_absolute: false,
term_search_fuel: 400,
term_search_borrowck: true,
show_rename_conflicts: true,
};
host.analysis()
.full_diagnostics(&diagnostics_config, ide::AssistResolveStrategy::None, file_id)
Expand Down
7 changes: 7 additions & 0 deletions docs/book/src/configuration_generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,13 @@ Default: `false`
Exclude tests from find-all-references and call-hierarchy.


## rust-analyzer.rename.showConflicts {#rename.showConflicts}

Default: `true`

Whether to warn when a rename will cause conflicts (change the meaning of the code).


## rust-analyzer.runnables.command {#runnables.command}

Default: `null`
Expand Down
10 changes: 10 additions & 0 deletions editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2769,6 +2769,16 @@
}
}
},
{
"title": "Rename",
"properties": {
"rust-analyzer.rename.showConflicts": {
"markdownDescription": "Whether to warn when a rename will cause conflicts (change the meaning of the code).",
"default": true,
"type": "boolean"
}
}
},
{
"title": "Runnables",
"properties": {
Expand Down