diff options
| -rw-r--r-- | crates/ide-assists/src/handlers/extract_function.rs | 43 | ||||
| -rw-r--r-- | crates/ide-db/src/rename.rs | 17 | ||||
| -rw-r--r-- | crates/ide/src/rename.rs | 29 |
3 files changed, 67 insertions, 22 deletions
diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index ea7a21e77a4..de591cfde94 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -531,7 +531,7 @@ impl FunctionBody { fn extracted_from_trait_impl(&self) -> bool { match self.node().ancestors().find_map(ast::Impl::cast) { - Some(c) => return c.trait_().is_some(), + Some(c) => c.trait_().is_some(), None => false, } } @@ -1048,23 +1048,17 @@ impl GenericParent { fn generic_parents(parent: &SyntaxNode) -> Vec<GenericParent> { let mut list = Vec::new(); if let Some(parent_item) = parent.ancestors().find_map(ast::Item::cast) { - match parent_item { - ast::Item::Fn(ref fn_) => { - if let Some(parent_parent) = parent_item - .syntax() - .parent() - .and_then(|it| it.parent()) - .and_then(ast::Item::cast) - { - match parent_parent { - ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)), - ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)), - _ => (), - } + if let ast::Item::Fn(ref fn_) = parent_item { + if let Some(parent_parent) = + parent_item.syntax().parent().and_then(|it| it.parent()).and_then(ast::Item::cast) + { + match parent_parent { + ast::Item::Impl(impl_) => list.push(GenericParent::Impl(impl_)), + ast::Item::Trait(trait_) => list.push(GenericParent::Trait(trait_)), + _ => (), } - list.push(GenericParent::Fn(fn_.clone())); } - _ => (), + list.push(GenericParent::Fn(fn_.clone())); } } list @@ -1728,7 +1722,7 @@ fn make_body( let block = match &fun.body { FunctionBody::Expr(expr) => { let expr = rewrite_body_segment(ctx, &fun.params, &handler, expr.syntax()); - let expr = ast::Expr::cast(expr).unwrap(); + let expr = ast::Expr::cast(expr).expect("Body segment should be an expr"); match expr { ast::Expr::BlockExpr(block) => { // If the extracted expression is itself a block, there is no need to wrap it inside another block. @@ -1868,9 +1862,8 @@ fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr if let Some(stmt_list) = block.stmt_list() { stmt_list.syntax().children_with_tokens().for_each(|node_or_token| { - match &node_or_token { - syntax::NodeOrToken::Token(_) => elements.push(node_or_token), - _ => (), + if let syntax::NodeOrToken::Token(_) = &node_or_token { + elements.push(node_or_token) }; }); } @@ -1934,12 +1927,18 @@ fn fix_param_usages(ctx: &AssistContext<'_>, params: &[Param], syntax: &SyntaxNo Some(ast::Expr::RefExpr(node)) if param.kind() == ParamKind::MutRef && node.mut_token().is_some() => { - ted::replace(node.syntax(), node.expr().unwrap().syntax()); + ted::replace( + node.syntax(), + node.expr().expect("RefExpr::expr() cannot be None").syntax(), + ); } Some(ast::Expr::RefExpr(node)) if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() => { - ted::replace(node.syntax(), node.expr().unwrap().syntax()); + ted::replace( + node.syntax(), + node.expr().expect("RefExpr::expr() cannot be None").syntax(), + ); } Some(_) | None => { let p = &make::expr_prefix(T![*], usage.clone()).clone_for_update(); diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs index aa0bb7cce69..353a9749a37 100644 --- a/crates/ide-db/src/rename.rs +++ b/crates/ide-db/src/rename.rs @@ -71,12 +71,29 @@ impl Definition { sema: &Semantics<'_, RootDatabase>, new_name: &str, ) -> Result<SourceChange> { + // self.krate() returns None if + // self is a built-in attr, built-in type or tool module. + // it is not allowed for these defs to be renamed. + // cases where self.krate() is None is handled below. + if let Some(krate) = self.krate(sema.db) { + if !krate.origin(sema.db).is_local() { + bail!("Cannot rename a non-local definition.") + } + } + match *self { Definition::Module(module) => rename_mod(sema, module, new_name), + Definition::ToolModule(_) => { + bail!("Cannot rename a tool module") + } Definition::BuiltinType(_) => { bail!("Cannot rename builtin type") } + Definition::BuiltinAttr(_) => { + bail!("Cannot rename a builtin attr.") + } Definition::SelfType(_) => bail!("Cannot rename `Self`"), + Definition::Macro(mac) => rename_reference(sema, Definition::Macro(mac), new_name), def => rename_reference(sema, def, new_name), } } diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index dae8e71e8a0..ac9df5ed6d1 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -2634,4 +2634,33 @@ use qux as frob; // ", // ); } + + #[test] + fn disallow_renaming_for_non_local_definition() { + check( + "Baz", + r#" +//- /lib.rs crate:lib new_source_root:library +pub struct S; +//- /main.rs crate:main deps:lib new_source_root:local +use lib::S$0; +"#, + "error: Cannot rename a non-local definition.", + ); + } + + #[test] + fn disallow_renaming_for_builtin_macros() { + check( + "Baz", + r#" +//- minicore: derive, hash +//- /main.rs crate:main +use core::hash::Hash; +#[derive(H$0ash)] +struct A; + "#, + "error: Cannot rename a non-local definition.", + ) + } } |
