From ee93037ed91f0c0e15aec28a744d14a3d97ca72c Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 28 Dec 2020 01:20:44 +0800 Subject: Use another name instead of dbg for test --- crates/completion/src/completions/dot.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/completion/src/completions/dot.rs b/crates/completion/src/completions/dot.rs index 2e25c8ba2..d04eef65a 100644 --- a/crates/completion/src/completions/dot.rs +++ b/crates/completion/src/completions/dot.rs @@ -373,20 +373,20 @@ fn foo(a: A) { fn macro_expansion_resilient() { check( r#" -macro_rules! dbg { +macro_rules! d { () => {}; ($val:expr) => { match $val { tmp => { tmp } } }; // Trailing comma with single argument is ignored - ($val:expr,) => { $crate::dbg!($val) }; + ($val:expr,) => { $crate::d!($val) }; ($($val:expr),+ $(,)?) => { - ($($crate::dbg!($val)),+,) + ($($crate::d!($val)),+,) }; } struct A { the_field: u32 } fn foo(a: A) { - dbg!(a.$0) + d!(a.$0) } "#, expect![[r#" -- cgit v1.2.3 From 66b132b4b21fb7034c698c22a9ca43e6b63ebd2f Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 28 Dec 2020 01:21:41 +0800 Subject: Remove unused dbg --- xtask/tests/tidy.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs index 7e5b1f7b5..e3572424b 100644 --- a/xtask/tests/tidy.rs +++ b/xtask/tests/tidy.rs @@ -94,10 +94,9 @@ fn rust_files_are_tidy() { #[test] fn check_merge_commits() { - let stdout = - dbg!(cmd!("git rev-list --merges --invert-grep --author 'bors\\[bot\\]' HEAD~19..")) - .read() - .unwrap(); + let stdout = cmd!("git rev-list --merges --invert-grep --author 'bors\\[bot\\]' HEAD~19..") + .read() + .unwrap(); if !stdout.is_empty() { panic!( " -- cgit v1.2.3 From 8584d269262e73aa7c3ebe25b1d61483375de267 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 28 Dec 2020 11:27:54 +0800 Subject: Add check for dbg! macro --- xtask/tests/tidy.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs index e3572424b..a957e36af 100644 --- a/xtask/tests/tidy.rs +++ b/xtask/tests/tidy.rs @@ -85,6 +85,7 @@ fn rust_files_are_tidy() { for path in rust_files(&project_root().join("crates")) { let text = read_file(&path).unwrap(); check_todo(&path, &text); + check_dbg(&path, &text); check_trailing_ws(&path, &text); deny_clippy(&path, &text); tidy_docs.visit(&path, &text); @@ -223,7 +224,7 @@ Zlib OR Apache-2.0 OR MIT fn check_todo(path: &Path, text: &str) { let need_todo = &[ // This file itself obviously needs to use todo (<- like this!). - "tests/cli.rs", + "tests/tidy.rs", // Some of our assists generate `todo!()`. "handlers/add_turbo_fish.rs", "handlers/generate_function.rs", @@ -251,6 +252,32 @@ fn check_todo(path: &Path, text: &str) { } } +fn check_dbg(path: &Path, text: &str) { + let need_dbg = &[ + // This file itself obviously needs to use dbg. + "tests/tidy.rs", + // Assists to remove `dbg!()` + "handlers/remove_dbg.rs", + // We have .dbg postfix + "completion/src/completions/postfix.rs", + // The documentation in string literals may contain anything for its own purposes + "completion/src/lib.rs", + "completion/src/generated_lint_completions.rs", + // test for doc test for remove_dbg + "src/tests/generated.rs", + ]; + if need_dbg.iter().any(|p| path.ends_with(p)) { + return; + } + if text.contains("dbg!") { + panic!( + "\ndbg! macros should not be committed to the master branch,\n\ + {}\n", + path.display(), + ) + } +} + fn check_trailing_ws(path: &Path, text: &str) { if is_exclude_dir(path, &["test_data"]) { return; -- cgit v1.2.3 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(-) 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(-) 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(-) 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 From 1da68e87af7b78257adaad27f266f4f50ac4588c Mon Sep 17 00:00:00 2001 From: kjeremy Date: Mon, 11 Jan 2021 08:27:16 -0500 Subject: Unfreeze cargo_metadata It now pulls in a newer version of semver-parser. --- Cargo.lock | 15 +++++++++++++-- crates/flycheck/Cargo.toml | 2 +- crates/proc_macro_srv/Cargo.toml | 2 +- crates/project_model/Cargo.toml | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc38c5a37..5563fdeb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,13 +126,24 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "cargo-platform" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7" +dependencies = [ + "serde", +] + [[package]] name = "cargo_metadata" -version = "0.12.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5a5f7b42f606b7f23674f6f4d877628350682bc40687d3fae65679a58d55345" +checksum = "11a47b6286279a9998588ef7050d1ebc2500c69892a557c90fe5d071c64415dc" dependencies = [ + "cargo-platform", "semver", + "semver-parser", "serde", "serde_json", ] diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml index 1bad64a1b..1d19c7886 100644 --- a/crates/flycheck/Cargo.toml +++ b/crates/flycheck/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] crossbeam-channel = "0.5.0" log = "0.4.8" -cargo_metadata = "=0.12.0" +cargo_metadata = "0.12.2" serde_json = "1.0.48" jod-thread = "0.1.1" diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml index f78c17194..83f9ead17 100644 --- a/crates/proc_macro_srv/Cargo.toml +++ b/crates/proc_macro_srv/Cargo.toml @@ -20,7 +20,7 @@ proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } test_utils = { path = "../test_utils", version = "0.0.0" } [dev-dependencies] -cargo_metadata = "=0.12.0" +cargo_metadata = "0.12.2" # used as proc macro test targets serde_derive = "1.0.106" diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml index a65e42261..855fb83ea 100644 --- a/crates/project_model/Cargo.toml +++ b/crates/project_model/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] log = "0.4.8" rustc-hash = "1.1.0" -cargo_metadata = "=0.12.0" +cargo_metadata = "0.12.2" serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.48" anyhow = "1.0.26" -- cgit v1.2.3 From 2d0464a6f3c572d7736670c22c71efe8aca93749 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 11 Jan 2021 16:29:29 +0300 Subject: Encourage gifs --- docs/dev/style.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/dev/style.md b/docs/dev/style.md index 7481f8008..9859f6148 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -78,6 +78,8 @@ Use original span for FileId This makes it easier to prepare a changelog. +If the change adds a new user-visible functionality, consider recording a GIF with [peek](https://github.com/phw/peek) and pasting it into the PR description. + **Rationale:** clean history is potentially useful, but rarely used. But many users read changelogs. -- cgit v1.2.3