From 919a1d7b278ada6063c948df7e63d3ef735af343 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 9 Jan 2021 16:59:00 +0100 Subject: Refactor rename name checking --- crates/ide/src/hover.rs | 7 +- crates/ide/src/references/rename.rs | 156 ++++++++++++++++++++++++------------ 2 files changed, 104 insertions(+), 59 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 8cb4a51d8..88d215129 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -175,12 +175,7 @@ fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option it.target_ty(db).as_adt(), _ => None, }?; - match adt { - Adt::Struct(it) => it.try_to_nav(db), - Adt::Union(it) => it.try_to_nav(db), - Adt::Enum(it) => it.try_to_nav(db), - } - .map(to_action) + adt.try_to_nav(db).map(to_action) } fn runnable_action( diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 53d79333c..dd322631b 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -20,10 +20,11 @@ use test_utils::mark; use text_edit::TextEdit; use crate::{ - references::find_all_refs, FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, + FilePosition, FileSystemEdit, RangeInfo, Reference, ReferenceKind, ReferenceSearchResult, SourceChange, SourceFileEdit, TextRange, TextSize, }; +type RenameResult = Result; #[derive(Debug)] pub struct RenameError(pub(crate) String); @@ -38,7 +39,7 @@ impl Error for RenameError {} pub(crate) fn prepare_rename( db: &RootDatabase, position: FilePosition, -) -> Result, RenameError> { +) -> RenameResult> { let sema = Semantics::new(db); let source_file = sema.parse(position.file_id); let syntax = source_file.syntax(); @@ -49,10 +50,7 @@ pub(crate) fn prepare_rename( { rename_self_to_param(&sema, position, self_token, "dummy") } else { - let range = match find_all_refs(&sema, position, None) { - Some(RangeInfo { range, .. }) => range, - None => return Err(RenameError("No references found at position".to_string())), - }; + let RangeInfo { range, .. } = find_all_refs(&sema, position)?; Ok(RangeInfo::new(range, SourceChange::from(vec![]))) } .map(|info| RangeInfo::new(info.range, ())) @@ -62,7 +60,7 @@ pub(crate) fn rename( db: &RootDatabase, position: FilePosition, new_name: &str, -) -> Result, RenameError> { +) -> RenameResult> { let sema = Semantics::new(db); rename_with_semantics(&sema, position, new_name) } @@ -71,42 +69,18 @@ pub(crate) fn rename_with_semantics( sema: &Semantics, position: FilePosition, new_name: &str, -) -> Result, RenameError> { - let is_lifetime_name = match lex_single_syntax_kind(new_name) { - Some(res) => match res { - (SyntaxKind::IDENT, _) => false, - (SyntaxKind::UNDERSCORE, _) => false, - (SyntaxKind::SELF_KW, _) => return rename_to_self(&sema, position), - (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => true, - (SyntaxKind::LIFETIME_IDENT, _) => { - return Err(RenameError(format!( - "Invalid name `{0}`: Cannot rename lifetime to {0}", - new_name - ))) - } - (_, Some(syntax_error)) => { - return Err(RenameError(format!("Invalid name `{}`: {}", new_name, syntax_error))) - } - (_, None) => { - return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))) - } - }, - None => return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))), - }; - +) -> RenameResult> { let source_file = sema.parse(position.file_id); let syntax = source_file.syntax(); - // this is here to prevent lifetime renames from happening on modules and self - if is_lifetime_name { - rename_reference(&sema, position, new_name, is_lifetime_name) - } else if let Some(module) = find_module_at_offset(&sema, position, syntax) { + + if let Some(module) = find_module_at_offset(&sema, position, syntax) { rename_mod(&sema, position, module, new_name) } else if let Some(self_token) = syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) { rename_self_to_param(&sema, position, self_token, new_name) } else { - rename_reference(&sema, position, new_name, is_lifetime_name) + rename_reference(&sema, position, new_name) } } @@ -127,6 +101,36 @@ pub(crate) fn will_rename_file( Some(change) } +#[derive(PartialEq)] +enum IdentifierKind { + Ident, + Lifetime, + ToSelf, + Underscore, +} + +fn check_identifier(new_name: &str) -> RenameResult { + match lex_single_syntax_kind(new_name) { + Some(res) => match res { + (SyntaxKind::IDENT, _) => Ok(IdentifierKind::Ident), + (SyntaxKind::UNDERSCORE, _) => Ok(IdentifierKind::Underscore), + (SyntaxKind::SELF_KW, _) => Ok(IdentifierKind::ToSelf), + (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => { + Ok(IdentifierKind::Lifetime) + } + (SyntaxKind::LIFETIME_IDENT, _) => { + Err(format!("Invalid name `{0}`: Cannot rename lifetime to {0}", new_name)) + } + (_, Some(syntax_error)) => { + Err(format!("Invalid name `{}`: {}", new_name, syntax_error)) + } + (_, None) => Err(format!("Invalid name `{}`: not an identifier", new_name)), + }, + None => Err(format!("Invalid name `{}`: not an identifier", new_name)), + } + .map_err(RenameError) +} + fn find_module_at_offset( sema: &Semantics, position: FilePosition, @@ -155,6 +159,14 @@ fn find_module_at_offset( Some(module) } +fn find_all_refs( + sema: &Semantics, + position: FilePosition, +) -> RenameResult> { + crate::references::find_all_refs(sema, position, None) + .ok_or_else(|| RenameError("No references found at position".to_string())) +} + fn source_edit_from_reference( sema: &Semantics, reference: Reference, @@ -223,7 +235,13 @@ fn rename_mod( position: FilePosition, module: Module, new_name: &str, -) -> Result, RenameError> { +) -> RenameResult> { + if IdentifierKind::Ident != check_identifier(new_name)? { + return Err(RenameError(format!( + "Invalid name `{0}`: cannot rename module to {0}", + new_name + ))); + } let mut source_file_edits = Vec::new(); let mut file_system_edits = Vec::new(); @@ -254,8 +272,7 @@ fn rename_mod( source_file_edits.push(edit); } - let RangeInfo { range, info: refs } = find_all_refs(sema, position, None) - .ok_or_else(|| RenameError("No references found at position".to_string()))?; + let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; let ref_edits = refs .references .into_iter() @@ -310,8 +327,7 @@ fn rename_to_self( return Err(RenameError("Parameter type differs from impl block type".to_string())); } - let RangeInfo { range, info: refs } = find_all_refs(sema, position, None) - .ok_or_else(|| RenameError("No reference found at position".to_string()))?; + let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; let (param_ref, usages): (Vec, Vec) = refs .into_iter() @@ -367,6 +383,17 @@ fn rename_self_to_param( self_token: SyntaxToken, new_name: &str, ) -> Result, RenameError> { + let ident_kind = check_identifier(new_name)?; + match ident_kind { + IdentifierKind::Lifetime => { + return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))) + } + IdentifierKind::ToSelf => { + // no-op + return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default())); + } + _ => (), + } let source_file = sema.parse(position.file_id); let syn = source_file.syntax(); @@ -395,6 +422,12 @@ fn rename_self_to_param( } } + if edits.len() > 1 && ident_kind == IdentifierKind::Underscore { + return Err(RenameError(format!( + "Cannot rename reference to `_` as it is being referenced multiple times", + ))); + } + let range = ast::SelfParam::cast(self_token.parent()) .map_or(self_token.text_range(), |p| p.syntax().text_range()); @@ -405,24 +438,36 @@ fn rename_reference( sema: &Semantics, position: FilePosition, new_name: &str, - is_lifetime_name: bool, ) -> Result, RenameError> { - let RangeInfo { range, info: refs } = match find_all_refs(sema, position, None) { - Some(range_info) => range_info, - None => return Err(RenameError("No references found at position".to_string())), - }; + let ident_kind = check_identifier(new_name)?; + let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; - match (refs.declaration.kind == ReferenceKind::Lifetime, is_lifetime_name) { - (true, false) => { + match (ident_kind, &refs.declaration.kind) { + (IdentifierKind::ToSelf, ReferenceKind::Lifetime) + | (IdentifierKind::Underscore, ReferenceKind::Lifetime) + | (IdentifierKind::Ident, ReferenceKind::Lifetime) => { return Err(RenameError(format!( "Invalid name `{}`: not a lifetime identifier", new_name ))) } - (false, true) => { + (IdentifierKind::Lifetime, ReferenceKind::Lifetime) => (), + (IdentifierKind::Lifetime, _) => { return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))) } - _ => (), + (IdentifierKind::ToSelf, ReferenceKind::SelfKw) => { + //no-op + return Ok(RangeInfo::new(range, SourceChange::default())); + } + (IdentifierKind::ToSelf, _) => { + return rename_to_self(sema, position); + } + (IdentifierKind::Underscore, _) if !refs.references.is_empty() => { + return Err(RenameError(format!( + "Cannot rename reference to `_` as it is being referenced multiple times", + ))) + } + (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => (), } let edit = refs @@ -430,10 +475,6 @@ fn rename_reference( .map(|reference| source_edit_from_reference(sema, reference, new_name)) .collect::>(); - if edit.is_empty() { - return Err(RenameError("No references found at position".to_string())); - } - Ok(RangeInfo::new(range, SourceChange::from(edit))) } @@ -546,6 +587,15 @@ mod tests { ); } + #[test] + fn test_rename_to_underscore_invalid() { + check( + "_", + r#"fn main(foo$0: ()) {foo;}"#, + "error: Cannot rename reference to `_` as it is being referenced multiple times", + ); + } + #[test] fn test_rename_for_local() { check( -- cgit v1.2.3 From 2347944aaec8b78c128acdc26fa83b6ebe8b1cf2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 10 Jan 2021 21:59:44 +0100 Subject: Use local error macros in references/rename --- crates/ide/src/references/rename.rs | 69 ++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 39 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index dd322631b..6040fc1f8 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -36,6 +36,15 @@ impl fmt::Display for RenameError { impl Error for RenameError {} +macro_rules! format_err { + ($fmt:expr) => {RenameError(format!($fmt))}; + ($fmt:expr, $($arg:tt)+) => {RenameError(format!($fmt, $($arg)+))} +} + +macro_rules! bail { + ($($tokens:tt)*) => {return Err(format_err!($($tokens)*))} +} + pub(crate) fn prepare_rename( db: &RootDatabase, position: FilePosition, @@ -119,16 +128,13 @@ fn check_identifier(new_name: &str) -> RenameResult { Ok(IdentifierKind::Lifetime) } (SyntaxKind::LIFETIME_IDENT, _) => { - Err(format!("Invalid name `{0}`: Cannot rename lifetime to {0}", new_name)) + bail!("Invalid name `{0}`: Cannot rename lifetime to {0}", new_name) } - (_, Some(syntax_error)) => { - Err(format!("Invalid name `{}`: {}", new_name, syntax_error)) - } - (_, None) => Err(format!("Invalid name `{}`: not an identifier", new_name)), + (_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error), + (_, None) => bail!("Invalid name `{}`: not an identifier", new_name), }, - None => Err(format!("Invalid name `{}`: not an identifier", new_name)), + None => bail!("Invalid name `{}`: not an identifier", new_name), } - .map_err(RenameError) } fn find_module_at_offset( @@ -164,7 +170,7 @@ fn find_all_refs( position: FilePosition, ) -> RenameResult> { crate::references::find_all_refs(sema, position, None) - .ok_or_else(|| RenameError("No references found at position".to_string())) + .ok_or_else(|| format_err!("No references found at position")) } fn source_edit_from_reference( @@ -237,10 +243,7 @@ fn rename_mod( new_name: &str, ) -> RenameResult> { if IdentifierKind::Ident != check_identifier(new_name)? { - return Err(RenameError(format!( - "Invalid name `{0}`: cannot rename module to {0}", - new_name - ))); + bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); } let mut source_file_edits = Vec::new(); let mut file_system_edits = Vec::new(); @@ -291,27 +294,26 @@ fn rename_to_self( let (fn_def, fn_ast) = find_node_at_offset::(syn, position.offset) .and_then(|fn_ast| sema.to_def(&fn_ast).zip(Some(fn_ast))) - .ok_or_else(|| RenameError("No surrounding method declaration found".to_string()))?; + .ok_or_else(|| format_err!("No surrounding method declaration found"))?; let param_range = fn_ast .param_list() .and_then(|p| p.params().next()) - .ok_or_else(|| RenameError("Method has no parameters".to_string()))? + .ok_or_else(|| format_err!("Method has no parameters"))? .syntax() .text_range(); if !param_range.contains(position.offset) { - return Err(RenameError("Only the first parameter can be self".to_string())); + bail!("Only the first parameter can be self"); } let impl_block = find_node_at_offset::(syn, position.offset) .and_then(|def| sema.to_def(&def)) - .ok_or_else(|| RenameError("No impl block found for function".to_string()))?; + .ok_or_else(|| format_err!("No impl block found for function"))?; if fn_def.self_param(sema.db).is_some() { - return Err(RenameError("Method already has a self parameter".to_string())); + bail!("Method already has a self parameter"); } let params = fn_def.assoc_fn_params(sema.db); - let first_param = - params.first().ok_or_else(|| RenameError("Method has no parameters".into()))?; + let first_param = params.first().ok_or_else(|| format_err!("Method has no parameters"))?; let first_param_ty = first_param.ty(); let impl_ty = impl_block.target_ty(sema.db); let (ty, self_param) = if impl_ty.remove_ref().is_some() { @@ -324,7 +326,7 @@ fn rename_to_self( }; if ty != impl_ty { - return Err(RenameError("Parameter type differs from impl block type".to_string())); + bail!("Parameter type differs from impl block type"); } let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; @@ -334,7 +336,7 @@ fn rename_to_self( .partition(|reference| param_range.intersect(reference.file_range.range).is_some()); if param_ref.is_empty() { - return Err(RenameError("Parameter to rename not found".to_string())); + bail!("Parameter to rename not found"); } let mut edits = usages @@ -385,9 +387,7 @@ fn rename_self_to_param( ) -> Result, RenameError> { let ident_kind = check_identifier(new_name)?; match ident_kind { - IdentifierKind::Lifetime => { - return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))) - } + IdentifierKind::Lifetime => bail!("Invalid name `{}`: not an identifier", new_name), IdentifierKind::ToSelf => { // no-op return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default())); @@ -399,7 +399,7 @@ fn rename_self_to_param( let text = sema.db.file_text(position.file_id); let fn_def = find_node_at_offset::(syn, position.offset) - .ok_or_else(|| RenameError("No surrounding method declaration found".to_string()))?; + .ok_or_else(|| format_err!("No surrounding method declaration found"))?; let search_range = fn_def.syntax().text_range(); let mut edits: Vec = vec![]; @@ -414,7 +414,7 @@ fn rename_self_to_param( { let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) { text_edit_from_self_param(syn, self_param, new_name) - .ok_or_else(|| RenameError("No target type found".to_string()))? + .ok_or_else(|| format_err!("No target type found"))? } else { TextEdit::replace(usage.text_range(), String::from(new_name)) }; @@ -423,9 +423,7 @@ fn rename_self_to_param( } if edits.len() > 1 && ident_kind == IdentifierKind::Underscore { - return Err(RenameError(format!( - "Cannot rename reference to `_` as it is being referenced multiple times", - ))); + bail!("Cannot rename reference to `_` as it is being referenced multiple times"); } let range = ast::SelfParam::cast(self_token.parent()) @@ -446,15 +444,10 @@ fn rename_reference( (IdentifierKind::ToSelf, ReferenceKind::Lifetime) | (IdentifierKind::Underscore, ReferenceKind::Lifetime) | (IdentifierKind::Ident, ReferenceKind::Lifetime) => { - return Err(RenameError(format!( - "Invalid name `{}`: not a lifetime identifier", - new_name - ))) + bail!("Invalid name `{}`: not a lifetime identifier", new_name) } (IdentifierKind::Lifetime, ReferenceKind::Lifetime) => (), - (IdentifierKind::Lifetime, _) => { - return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name))) - } + (IdentifierKind::Lifetime, _) => bail!("Invalid name `{}`: not an identifier", new_name), (IdentifierKind::ToSelf, ReferenceKind::SelfKw) => { //no-op return Ok(RangeInfo::new(range, SourceChange::default())); @@ -463,9 +456,7 @@ fn rename_reference( return rename_to_self(sema, position); } (IdentifierKind::Underscore, _) if !refs.references.is_empty() => { - return Err(RenameError(format!( - "Cannot rename reference to `_` as it is being referenced multiple times", - ))) + bail!("Cannot rename reference to `_` as it is being referenced multiple times") } (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => (), } -- cgit v1.2.3 From f7af0b4b969aa1ba85744f082a30af808a684d7c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 10 Jan 2021 22:27:43 +0100 Subject: Add some more marks to rename tests --- crates/ide/src/references/rename.rs | 75 ++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 17 deletions(-) (limited to 'crates/ide') diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 6040fc1f8..44dfa9a0e 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -14,7 +14,7 @@ use ide_db::{ use syntax::{ algo::find_node_at_offset, ast::{self, NameOwner}, - lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, SyntaxToken, + lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, SyntaxToken, T, }; use test_utils::mark; use text_edit::TextEdit; @@ -55,7 +55,7 @@ pub(crate) fn prepare_rename( if let Some(module) = find_module_at_offset(&sema, position, syntax) { rename_mod(&sema, position, module, "dummy") } else if let Some(self_token) = - syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) + syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self]) { rename_self_to_param(&sema, position, self_token, "dummy") } else { @@ -85,7 +85,7 @@ pub(crate) fn rename_with_semantics( if let Some(module) = find_module_at_offset(&sema, position, syntax) { rename_mod(&sema, position, module, new_name) } else if let Some(self_token) = - syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW) + syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self]) { rename_self_to_param(&sema, position, self_token, new_name) } else { @@ -110,7 +110,7 @@ pub(crate) fn will_rename_file( Some(change) } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] enum IdentifierKind { Ident, Lifetime, @@ -122,8 +122,8 @@ fn check_identifier(new_name: &str) -> RenameResult { match lex_single_syntax_kind(new_name) { Some(res) => match res { (SyntaxKind::IDENT, _) => Ok(IdentifierKind::Ident), - (SyntaxKind::UNDERSCORE, _) => Ok(IdentifierKind::Underscore), - (SyntaxKind::SELF_KW, _) => Ok(IdentifierKind::ToSelf), + (T![_], _) => Ok(IdentifierKind::Underscore), + (T![self], _) => Ok(IdentifierKind::ToSelf), (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => { Ok(IdentifierKind::Lifetime) } @@ -390,6 +390,7 @@ fn rename_self_to_param( IdentifierKind::Lifetime => bail!("Invalid name `{}`: not an identifier", new_name), IdentifierKind::ToSelf => { // no-op + mark::hit!(rename_self_to_self); return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default())); } _ => (), @@ -409,9 +410,7 @@ fn rename_self_to_param( if !search_range.contains_inclusive(offset) { continue; } - if let Some(ref usage) = - syn.token_at_offset(offset).find(|t| t.kind() == SyntaxKind::SELF_KW) - { + if let Some(ref usage) = syn.token_at_offset(offset).find(|t| t.kind() == T![self]) { let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) { text_edit_from_self_param(syn, self_param, new_name) .ok_or_else(|| format_err!("No target type found"))? @@ -444,21 +443,26 @@ fn rename_reference( (IdentifierKind::ToSelf, ReferenceKind::Lifetime) | (IdentifierKind::Underscore, ReferenceKind::Lifetime) | (IdentifierKind::Ident, ReferenceKind::Lifetime) => { + mark::hit!(rename_not_a_lifetime_ident_ref); bail!("Invalid name `{}`: not a lifetime identifier", new_name) } - (IdentifierKind::Lifetime, ReferenceKind::Lifetime) => (), - (IdentifierKind::Lifetime, _) => bail!("Invalid name `{}`: not an identifier", new_name), + (IdentifierKind::Lifetime, ReferenceKind::Lifetime) => mark::hit!(rename_lifetime), + (IdentifierKind::Lifetime, _) => { + mark::hit!(rename_not_an_ident_ref); + bail!("Invalid name `{}`: not an identifier", new_name) + } (IdentifierKind::ToSelf, ReferenceKind::SelfKw) => { - //no-op - return Ok(RangeInfo::new(range, SourceChange::default())); + unreachable!("rename_self_to_param should've been called instead") } (IdentifierKind::ToSelf, _) => { + mark::hit!(rename_to_self); return rename_to_self(sema, position); } (IdentifierKind::Underscore, _) if !refs.references.is_empty() => { + mark::hit!(rename_underscore_multiple); bail!("Cannot rename reference to `_` as it is being referenced multiple times") } - (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => (), + (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => mark::hit!(rename_ident), } let edit = refs @@ -494,9 +498,11 @@ mod tests { text_edit_builder.replace(indel.delete, indel.insert); } } - let mut result = analysis.file_text(file_id.unwrap()).unwrap().to_string(); - text_edit_builder.finish().apply(&mut result); - assert_eq_text!(ra_fixture_after, &*result); + if let Some(file_id) = file_id { + let mut result = analysis.file_text(file_id).unwrap().to_string(); + text_edit_builder.finish().apply(&mut result); + assert_eq_text!(ra_fixture_after, &*result); + } } Err(err) => { if ra_fixture_after.starts_with("error:") { @@ -562,6 +568,7 @@ mod tests { #[test] fn test_rename_to_invalid_identifier_lifetime() { + mark::check!(rename_not_an_ident_ref); check( "'foo", r#"fn main() { let i$0 = 1; }"#, @@ -571,6 +578,7 @@ mod tests { #[test] fn test_rename_to_invalid_identifier_lifetime2() { + mark::check!(rename_not_a_lifetime_ident_ref); check( "foo", r#"fn main<'a>(_: &'a$0 ()) {}"#, @@ -580,6 +588,7 @@ mod tests { #[test] fn test_rename_to_underscore_invalid() { + mark::check!(rename_underscore_multiple); check( "_", r#"fn main(foo$0: ()) {foo;}"#, @@ -587,8 +596,18 @@ mod tests { ); } + #[test] + fn test_rename_mod_invalid() { + check( + "'foo", + r#"mod foo$0 {}"#, + "error: Invalid name `'foo`: cannot rename module to 'foo", + ); + } + #[test] fn test_rename_for_local() { + mark::check!(rename_ident); check( "k", r#" @@ -1219,6 +1238,7 @@ fn foo(f: foo::Foo) { #[test] fn test_parameter_to_self() { + mark::check!(rename_to_self); check( "self", r#" @@ -1522,6 +1542,7 @@ fn foo(Foo { i: bar }: foo) -> i32 { #[test] fn test_rename_lifetimes() { + mark::check!(rename_lifetime); check( "'yeeee", r#" @@ -1603,6 +1624,26 @@ fn foo<'a>() -> &'a () { } } } +"#, + ) + } + + #[test] + fn test_self_to_self() { + mark::check!(rename_self_to_self); + check( + "self", + r#" +struct Foo; +impl Foo { + fn foo(self$0) {} +} +"#, + r#" +struct Foo; +impl Foo { + fn foo(self) {} +} "#, ) } -- cgit v1.2.3