aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--crates/assists/src/assist_context.rs4
-rw-r--r--crates/assists/src/handlers/generate_enum_match_method.rs10
-rw-r--r--crates/assists/src/tests/generated.rs1
-rw-r--r--crates/hir_def/src/body/lower.rs2
-rw-r--r--crates/hir_def/src/data.rs2
-rw-r--r--crates/hir_def/src/test_db.rs2
-rw-r--r--crates/hir_ty/src/diagnostics.rs35
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs279
-rw-r--r--crates/ide/src/syntax_highlighting.rs2
-rw-r--r--crates/proc_macro_api/src/rpc.rs2
-rw-r--r--crates/stdx/Cargo.toml2
-rw-r--r--crates/test_utils/src/fixture.rs11
-rw-r--r--docs/dev/debugging.md2
-rw-r--r--xtask/src/install.rs4
15 files changed, 176 insertions, 186 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8f1a8401f..1ceae965f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,9 +17,9 @@ checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
17 17
18[[package]] 18[[package]]
19name = "always-assert" 19name = "always-assert"
20version = "0.1.1" 20version = "0.1.2"
21source = "registry+https://github.com/rust-lang/crates.io-index" 21source = "registry+https://github.com/rust-lang/crates.io-index"
22checksum = "727786f78c5bc0cda8011831616589f72084cb16b7df4213a997b78749b55a60" 22checksum = "fbf688625d06217d5b1bb0ea9d9c44a1635fd0ee3534466388d18203174f4d11"
23dependencies = [ 23dependencies = [
24 "log", 24 "log",
25] 25]
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs
index 8d93edba2..bba6c08e0 100644
--- a/crates/assists/src/assist_context.rs
+++ b/crates/assists/src/assist_context.rs
@@ -162,7 +162,7 @@ impl Assists {
162 } else { 162 } else {
163 None 163 None
164 }; 164 };
165 assist.source_change = source_change.clone(); 165 assist.source_change = source_change;
166 166
167 self.buf.push(assist); 167 self.buf.push(assist);
168 Some(()) 168 Some(())
@@ -242,7 +242,7 @@ impl AssistBuilder {
242 } 242 }
243 pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) { 243 pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
244 let file_system_edit = 244 let file_system_edit =
245 FileSystemEdit::CreateFile { dst: dst.clone(), initial_contents: content.into() }; 245 FileSystemEdit::CreateFile { dst: dst, initial_contents: content.into() };
246 self.source_change.push_file_system_edit(file_system_edit); 246 self.source_change.push_file_system_edit(file_system_edit);
247 } 247 }
248 248
diff --git a/crates/assists/src/handlers/generate_enum_match_method.rs b/crates/assists/src/handlers/generate_enum_match_method.rs
index 2345a61c1..4cf66b5d5 100644
--- a/crates/assists/src/handlers/generate_enum_match_method.rs
+++ b/crates/assists/src/handlers/generate_enum_match_method.rs
@@ -28,6 +28,7 @@ use crate::{
28// } 28// }
29// 29//
30// impl Version { 30// impl Version {
31// /// Returns `true` if the version is [`Minor`].
31// fn is_minor(&self) -> bool { 32// fn is_minor(&self) -> bool {
32// matches!(self, Self::Minor) 33// matches!(self, Self::Minor)
33// } 34// }
@@ -42,6 +43,7 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
42 return None; 43 return None;
43 } 44 }
44 45
46 let enum_lowercase_name = to_lower_snake_case(&parent_enum.name()?.to_string());
45 let fn_name = to_lower_snake_case(&variant_name.to_string()); 47 let fn_name = to_lower_snake_case(&variant_name.to_string());
46 48
47 // Return early if we've found an existing new fn 49 // Return early if we've found an existing new fn
@@ -66,9 +68,12 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
66 let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v)); 68 let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
67 format_to!( 69 format_to!(
68 buf, 70 buf,
69 " {}fn is_{}(&self) -> bool {{ 71 " /// Returns `true` if the {} is [`{}`].
72 {}fn is_{}(&self) -> bool {{
70 matches!(self, Self::{}) 73 matches!(self, Self::{})
71 }}", 74 }}",
75 enum_lowercase_name,
76 variant_name,
72 vis, 77 vis,
73 fn_name, 78 fn_name,
74 variant_name 79 variant_name
@@ -125,6 +130,7 @@ enum Variant {
125} 130}
126 131
127impl Variant { 132impl Variant {
133 /// Returns `true` if the variant is [`Minor`].
128 fn is_minor(&self) -> bool { 134 fn is_minor(&self) -> bool {
129 matches!(self, Self::Minor) 135 matches!(self, Self::Minor)
130 } 136 }
@@ -172,6 +178,7 @@ enum Variant {
172enum Variant { Undefined } 178enum Variant { Undefined }
173 179
174impl Variant { 180impl Variant {
181 /// Returns `true` if the variant is [`Undefined`].
175 fn is_undefined(&self) -> bool { 182 fn is_undefined(&self) -> bool {
176 matches!(self, Self::Undefined) 183 matches!(self, Self::Undefined)
177 } 184 }
@@ -196,6 +203,7 @@ pub(crate) enum Variant {
196} 203}
197 204
198impl Variant { 205impl Variant {
206 /// Returns `true` if the variant is [`Minor`].
199 pub(crate) fn is_minor(&self) -> bool { 207 pub(crate) fn is_minor(&self) -> bool {
200 matches!(self, Self::Minor) 208 matches!(self, Self::Minor)
201 } 209 }
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs
index 960815bd9..0dbb05f2a 100644
--- a/crates/assists/src/tests/generated.rs
+++ b/crates/assists/src/tests/generated.rs
@@ -478,6 +478,7 @@ enum Version {
478} 478}
479 479
480impl Version { 480impl Version {
481 /// Returns `true` if the version is [`Minor`].
481 fn is_minor(&self) -> bool { 482 fn is_minor(&self) -> bool {
482 matches!(self, Self::Minor) 483 matches!(self, Self::Minor)
483 } 484 }
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 28b11cdde..c18001e15 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -712,7 +712,7 @@ impl ExprCollector<'_> {
712 let statements = 712 let statements =
713 block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); 713 block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect();
714 let tail = block.tail_expr().map(|e| self.collect_expr(e)); 714 let tail = block.tail_expr().map(|e| self.collect_expr(e));
715 let syntax_node_ptr = AstPtr::new(&block.clone().into()); 715 let syntax_node_ptr = AstPtr::new(&block.into());
716 let expr_id = self.alloc_expr( 716 let expr_id = self.alloc_expr(
717 Expr::Block { id: block_id, statements, tail, label: None }, 717 Expr::Block { id: block_id, statements, tail, label: None },
718 syntax_node_ptr, 718 syntax_node_ptr,
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 42fcca386..d3380e0f4 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -43,7 +43,7 @@ impl FunctionData {
43 name: func.name.clone(), 43 name: func.name.clone(),
44 params: func.params.iter().map(|id| item_tree[*id].clone()).collect(), 44 params: func.params.iter().map(|id| item_tree[*id].clone()).collect(),
45 ret_type: item_tree[func.ret_type].clone(), 45 ret_type: item_tree[func.ret_type].clone(),
46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()).clone(), 46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
47 has_self_param: func.has_self_param, 47 has_self_param: func.has_self_param,
48 has_body: func.has_body, 48 has_body: func.has_body,
49 is_unsafe: func.is_unsafe, 49 is_unsafe: func.is_unsafe,
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
index c4e36eda5..6665d902d 100644
--- a/crates/hir_def/src/test_db.rs
+++ b/crates/hir_def/src/test_db.rs
@@ -161,7 +161,7 @@ impl TestDB {
161 let node = src.map(|ptr| ptr.to_node(&root)); 161 let node = src.map(|ptr| ptr.to_node(&root));
162 let frange = node.as_ref().original_file_range(db); 162 let frange = node.as_ref().original_file_range(db);
163 163
164 let message = d.message().to_owned(); 164 let message = d.message();
165 actual.entry(frange.file_id).or_default().push((frange.range, message)); 165 actual.entry(frange.file_id).or_default().push((frange.range, message));
166 }); 166 });
167 167
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index 323c5f963..19da51acd 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -345,6 +345,37 @@ impl fmt::Display for CaseType {
345 } 345 }
346} 346}
347 347
348#[derive(Debug)]
349pub enum IdentType {
350 Argument,
351 Constant,
352 Enum,
353 Field,
354 Function,
355 StaticVariable,
356 Structure,
357 Variable,
358 Variant,
359}
360
361impl fmt::Display for IdentType {
362 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363 let repr = match self {
364 IdentType::Argument => "Argument",
365 IdentType::Constant => "Constant",
366 IdentType::Enum => "Enum",
367 IdentType::Field => "Field",
368 IdentType::Function => "Function",
369 IdentType::StaticVariable => "Static variable",
370 IdentType::Structure => "Structure",
371 IdentType::Variable => "Variable",
372 IdentType::Variant => "Variant",
373 };
374
375 write!(f, "{}", repr)
376 }
377}
378
348// Diagnostic: incorrect-ident-case 379// Diagnostic: incorrect-ident-case
349// 380//
350// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention]. 381// This diagnostic is triggered if an item name doesn't follow https://doc.rust-lang.org/1.0.0/style/style/naming/README.html[Rust naming convention].
@@ -353,7 +384,7 @@ pub struct IncorrectCase {
353 pub file: HirFileId, 384 pub file: HirFileId,
354 pub ident: AstPtr<ast::Name>, 385 pub ident: AstPtr<ast::Name>,
355 pub expected_case: CaseType, 386 pub expected_case: CaseType,
356 pub ident_type: String, 387 pub ident_type: IdentType,
357 pub ident_text: String, 388 pub ident_text: String,
358 pub suggested_text: String, 389 pub suggested_text: String,
359} 390}
@@ -480,7 +511,7 @@ mod tests {
480 // FIXME: macros... 511 // FIXME: macros...
481 let file_id = src.file_id.original_file(&db); 512 let file_id = src.file_id.original_file(&db);
482 let range = src.value.to_node(&root).text_range(); 513 let range = src.value.to_node(&root).text_range();
483 let message = d.message().to_owned(); 514 let message = d.message();
484 actual.entry(file_id).or_default().push((range, message)); 515 actual.entry(file_id).or_default().push((range, message));
485 }); 516 });
486 517
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index eaeb6899f..6773ddea3 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -23,6 +23,7 @@ use hir_expand::{
23 diagnostics::DiagnosticSink, 23 diagnostics::DiagnosticSink,
24 name::{AsName, Name}, 24 name::{AsName, Name},
25}; 25};
26use stdx::{always, never};
26use syntax::{ 27use syntax::{
27 ast::{self, NameOwner}, 28 ast::{self, NameOwner},
28 AstNode, AstPtr, 29 AstNode, AstPtr,
@@ -31,7 +32,7 @@ use test_utils::mark;
31 32
32use crate::{ 33use crate::{
33 db::HirDatabase, 34 db::HirDatabase,
34 diagnostics::{decl_check::case_conv::*, CaseType, IncorrectCase}, 35 diagnostics::{decl_check::case_conv::*, CaseType, IdentType, IncorrectCase},
35}; 36};
36 37
37mod allow { 38mod allow {
@@ -40,7 +41,7 @@ mod allow {
40 pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types"; 41 pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types";
41} 42}
42 43
43pub(super) struct DeclValidator<'a, 'b: 'a> { 44pub(super) struct DeclValidator<'a, 'b> {
44 db: &'a dyn HirDatabase, 45 db: &'a dyn HirDatabase,
45 krate: CrateId, 46 krate: CrateId,
46 sink: &'a mut DiagnosticSink<'b>, 47 sink: &'a mut DiagnosticSink<'b>,
@@ -77,7 +78,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
77 AdtId::StructId(struct_id) => self.validate_struct(struct_id), 78 AdtId::StructId(struct_id) => self.validate_struct(struct_id),
78 AdtId::EnumId(enum_id) => self.validate_enum(enum_id), 79 AdtId::EnumId(enum_id) => self.validate_enum(enum_id),
79 AdtId::UnionId(_) => { 80 AdtId::UnionId(_) => {
80 // Unions aren't yet supported by this validator. 81 // FIXME: Unions aren't yet supported by this validator.
81 } 82 }
82 } 83 }
83 } 84 }
@@ -111,63 +112,50 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
111 112
112 // Check the function name. 113 // Check the function name.
113 let function_name = data.name.to_string(); 114 let function_name = data.name.to_string();
114 let fn_name_replacement = if let Some(new_name) = to_lower_snake_case(&function_name) { 115 let fn_name_replacement = to_lower_snake_case(&function_name).map(|new_name| Replacement {
115 let replacement = Replacement { 116 current_name: data.name.clone(),
116 current_name: data.name.clone(), 117 suggested_text: new_name,
117 suggested_text: new_name, 118 expected_case: CaseType::LowerSnakeCase,
118 expected_case: CaseType::LowerSnakeCase, 119 });
119 };
120 Some(replacement)
121 } else {
122 None
123 };
124 120
125 // Check the param names. 121 // Check the param names.
126 let mut fn_param_replacements = Vec::new(); 122 let fn_param_replacements = body
127 123 .params
128 for pat_id in body.params.iter().cloned() { 124 .iter()
129 let pat = &body[pat_id]; 125 .filter_map(|&id| match &body[id] {
130 126 Pat::Bind { name, .. } => Some(name),
131 let param_name = match pat { 127 _ => None,
132 Pat::Bind { name, .. } => name, 128 })
133 _ => continue, 129 .filter_map(|param_name| {
134 }; 130 Some(Replacement {
135
136 let name = param_name.to_string();
137 if let Some(new_name) = to_lower_snake_case(&name) {
138 let replacement = Replacement {
139 current_name: param_name.clone(), 131 current_name: param_name.clone(),
140 suggested_text: new_name, 132 suggested_text: to_lower_snake_case(&param_name.to_string())?,
141 expected_case: CaseType::LowerSnakeCase, 133 expected_case: CaseType::LowerSnakeCase,
142 }; 134 })
143 fn_param_replacements.push(replacement); 135 })
144 } 136 .collect();
145 }
146 137
147 // Check the patterns inside the function body. 138 // Check the patterns inside the function body.
148 let mut pats_replacements = Vec::new(); 139 let pats_replacements = body
149 140 .pats
150 for (pat_idx, pat) in body.pats.iter() { 141 .iter()
151 if body.params.contains(&pat_idx) { 142 // We aren't interested in function parameters, we've processed them above.
152 // We aren't interested in function parameters, we've processed them above. 143 .filter(|(pat_idx, _)| !body.params.contains(&pat_idx))
153 continue; 144 .filter_map(|(id, pat)| match pat {
154 } 145 Pat::Bind { name, .. } => Some((id, name)),
155 146 _ => None,
156 let bind_name = match pat { 147 })
157 Pat::Bind { name, .. } => name, 148 .filter_map(|(id, bind_name)| {
158 _ => continue, 149 Some((
159 }; 150 id,
160 151 Replacement {
161 let name = bind_name.to_string(); 152 current_name: bind_name.clone(),
162 if let Some(new_name) = to_lower_snake_case(&name) { 153 suggested_text: to_lower_snake_case(&bind_name.to_string())?,
163 let replacement = Replacement { 154 expected_case: CaseType::LowerSnakeCase,
164 current_name: bind_name.clone(), 155 },
165 suggested_text: new_name, 156 ))
166 expected_case: CaseType::LowerSnakeCase, 157 })
167 }; 158 .collect();
168 pats_replacements.push((pat_idx, replacement));
169 }
170 }
171 159
172 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 160 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
173 self.create_incorrect_case_diagnostic_for_func( 161 self.create_incorrect_case_diagnostic_for_func(
@@ -199,8 +187,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
199 let ast_ptr = match fn_src.value.name() { 187 let ast_ptr = match fn_src.value.name() {
200 Some(name) => name, 188 Some(name) => name,
201 None => { 189 None => {
202 // We don't want rust-analyzer to panic over this, but it is definitely some kind of error in the logic. 190 never!(
203 log::error!(
204 "Replacement ({:?}) was generated for a function without a name: {:?}", 191 "Replacement ({:?}) was generated for a function without a name: {:?}",
205 replacement, 192 replacement,
206 fn_src 193 fn_src
@@ -211,7 +198,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
211 198
212 let diagnostic = IncorrectCase { 199 let diagnostic = IncorrectCase {
213 file: fn_src.file_id, 200 file: fn_src.file_id,
214 ident_type: "Function".to_string(), 201 ident_type: IdentType::Function,
215 ident: AstPtr::new(&ast_ptr).into(), 202 ident: AstPtr::new(&ast_ptr).into(),
216 expected_case: replacement.expected_case, 203 expected_case: replacement.expected_case,
217 ident_text: replacement.current_name.to_string(), 204 ident_text: replacement.current_name.to_string(),
@@ -225,12 +212,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
225 let fn_params_list = match fn_src.value.param_list() { 212 let fn_params_list = match fn_src.value.param_list() {
226 Some(params) => params, 213 Some(params) => params,
227 None => { 214 None => {
228 if !fn_param_replacements.is_empty() { 215 always!(
229 log::error!( 216 fn_param_replacements.is_empty(),
230 "Replacements ({:?}) were generated for a function parameters which had no parameters list: {:?}", 217 "Replacements ({:?}) were generated for a function parameters which had no parameters list: {:?}",
231 fn_param_replacements, fn_src 218 fn_param_replacements,
232 ); 219 fn_src
233 } 220 );
234 return; 221 return;
235 } 222 }
236 }; 223 };
@@ -240,23 +227,25 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
240 // actual params list, but just some of them (ones that named correctly) are skipped. 227 // actual params list, but just some of them (ones that named correctly) are skipped.
241 let ast_ptr: ast::Name = loop { 228 let ast_ptr: ast::Name = loop {
242 match fn_params_iter.next() { 229 match fn_params_iter.next() {
243 Some(element) 230 Some(element) => {
244 if pat_equals_to_name(element.pat(), &param_to_rename.current_name) => 231 if let Some(ast::Pat::IdentPat(pat)) = element.pat() {
245 { 232 if pat.to_string() == param_to_rename.current_name.to_string() {
246 if let ast::Pat::IdentPat(pat) = element.pat().unwrap() { 233 if let Some(name) = pat.name() {
247 break pat.name().unwrap(); 234 break name;
248 } else { 235 }
249 // This is critical. If we consider this parameter the expected one, 236 // This is critical. If we consider this parameter the expected one,
250 // it **must** have a name. 237 // it **must** have a name.
251 panic!( 238 never!(
252 "Pattern {:?} equals to expected replacement {:?}, but has no name", 239 "Pattern {:?} equals to expected replacement {:?}, but has no name",
253 element, param_to_rename 240 element,
254 ); 241 param_to_rename
242 );
243 return;
244 }
255 } 245 }
256 } 246 }
257 Some(_) => {}
258 None => { 247 None => {
259 log::error!( 248 never!(
260 "Replacement ({:?}) was generated for a function parameter which was not found: {:?}", 249 "Replacement ({:?}) was generated for a function parameter which was not found: {:?}",
261 param_to_rename, fn_src 250 param_to_rename, fn_src
262 ); 251 );
@@ -267,7 +256,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
267 256
268 let diagnostic = IncorrectCase { 257 let diagnostic = IncorrectCase {
269 file: fn_src.file_id, 258 file: fn_src.file_id,
270 ident_type: "Argument".to_string(), 259 ident_type: IdentType::Argument,
271 ident: AstPtr::new(&ast_ptr).into(), 260 ident: AstPtr::new(&ast_ptr).into(),
272 expected_case: param_to_rename.expected_case, 261 expected_case: param_to_rename.expected_case,
273 ident_text: param_to_rename.current_name.to_string(), 262 ident_text: param_to_rename.current_name.to_string(),
@@ -309,8 +298,8 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
309 // We have to check that it's either `let var = ...` or `var @ Variant(_)` statement, 298 // We have to check that it's either `let var = ...` or `var @ Variant(_)` statement,
310 // because e.g. match arms are patterns as well. 299 // because e.g. match arms are patterns as well.
311 // In other words, we check that it's a named variable binding. 300 // In other words, we check that it's a named variable binding.
312 let is_binding = ast::LetStmt::cast(parent.clone()).is_some() 301 let is_binding = ast::LetStmt::can_cast(parent.kind())
313 || (ast::MatchArm::cast(parent).is_some() 302 || (ast::MatchArm::can_cast(parent.kind())
314 && ident_pat.at_token().is_some()); 303 && ident_pat.at_token().is_some());
315 if !is_binding { 304 if !is_binding {
316 // This pattern is not an actual variable declaration, e.g. `Some(val) => {..}` match arm. 305 // This pattern is not an actual variable declaration, e.g. `Some(val) => {..}` match arm.
@@ -319,7 +308,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
319 308
320 let diagnostic = IncorrectCase { 309 let diagnostic = IncorrectCase {
321 file: source_ptr.file_id, 310 file: source_ptr.file_id,
322 ident_type: "Variable".to_string(), 311 ident_type: IdentType::Variable,
323 ident: AstPtr::new(&name_ast).into(), 312 ident: AstPtr::new(&name_ast).into(),
324 expected_case: replacement.expected_case, 313 expected_case: replacement.expected_case,
325 ident_text: replacement.current_name.to_string(), 314 ident_text: replacement.current_name.to_string(),
@@ -341,17 +330,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
341 330
342 // Check the structure name. 331 // Check the structure name.
343 let struct_name = data.name.to_string(); 332 let struct_name = data.name.to_string();
344 let struct_name_replacement = if let Some(new_name) = to_camel_case(&struct_name) { 333 let struct_name_replacement = if !non_camel_case_allowed {
345 let replacement = Replacement { 334 to_camel_case(&struct_name).map(|new_name| Replacement {
346 current_name: data.name.clone(), 335 current_name: data.name.clone(),
347 suggested_text: new_name, 336 suggested_text: new_name,
348 expected_case: CaseType::UpperCamelCase, 337 expected_case: CaseType::UpperCamelCase,
349 }; 338 })
350 if non_camel_case_allowed {
351 None
352 } else {
353 Some(replacement)
354 }
355 } else { 339 } else {
356 None 340 None
357 }; 341 };
@@ -403,8 +387,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
403 let ast_ptr = match struct_src.value.name() { 387 let ast_ptr = match struct_src.value.name() {
404 Some(name) => name, 388 Some(name) => name,
405 None => { 389 None => {
406 // We don't want rust-analyzer to panic over this, but it is definitely some kind of error in the logic. 390 never!(
407 log::error!(
408 "Replacement ({:?}) was generated for a structure without a name: {:?}", 391 "Replacement ({:?}) was generated for a structure without a name: {:?}",
409 replacement, 392 replacement,
410 struct_src 393 struct_src
@@ -415,7 +398,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
415 398
416 let diagnostic = IncorrectCase { 399 let diagnostic = IncorrectCase {
417 file: struct_src.file_id, 400 file: struct_src.file_id,
418 ident_type: "Structure".to_string(), 401 ident_type: IdentType::Structure,
419 ident: AstPtr::new(&ast_ptr).into(), 402 ident: AstPtr::new(&ast_ptr).into(),
420 expected_case: replacement.expected_case, 403 expected_case: replacement.expected_case,
421 ident_text: replacement.current_name.to_string(), 404 ident_text: replacement.current_name.to_string(),
@@ -428,12 +411,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
428 let struct_fields_list = match struct_src.value.field_list() { 411 let struct_fields_list = match struct_src.value.field_list() {
429 Some(ast::FieldList::RecordFieldList(fields)) => fields, 412 Some(ast::FieldList::RecordFieldList(fields)) => fields,
430 _ => { 413 _ => {
431 if !struct_fields_replacements.is_empty() { 414 always!(
432 log::error!( 415 struct_fields_replacements.is_empty(),
433 "Replacements ({:?}) were generated for a structure fields which had no fields list: {:?}", 416 "Replacements ({:?}) were generated for a structure fields which had no fields list: {:?}",
434 struct_fields_replacements, struct_src 417 struct_fields_replacements,
435 ); 418 struct_src
436 } 419 );
437 return; 420 return;
438 } 421 }
439 }; 422 };
@@ -442,13 +425,14 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
442 // We assume that parameters in replacement are in the same order as in the 425 // We assume that parameters in replacement are in the same order as in the
443 // actual params list, but just some of them (ones that named correctly) are skipped. 426 // actual params list, but just some of them (ones that named correctly) are skipped.
444 let ast_ptr = loop { 427 let ast_ptr = loop {
445 match struct_fields_iter.next() { 428 match struct_fields_iter.next().and_then(|field| field.name()) {
446 Some(element) if names_equal(element.name(), &field_to_rename.current_name) => { 429 Some(field_name) => {
447 break element.name().unwrap() 430 if field_name.as_name() == field_to_rename.current_name {
431 break field_name;
432 }
448 } 433 }
449 Some(_) => {}
450 None => { 434 None => {
451 log::error!( 435 never!(
452 "Replacement ({:?}) was generated for a structure field which was not found: {:?}", 436 "Replacement ({:?}) was generated for a structure field which was not found: {:?}",
453 field_to_rename, struct_src 437 field_to_rename, struct_src
454 ); 438 );
@@ -459,7 +443,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
459 443
460 let diagnostic = IncorrectCase { 444 let diagnostic = IncorrectCase {
461 file: struct_src.file_id, 445 file: struct_src.file_id,
462 ident_type: "Field".to_string(), 446 ident_type: IdentType::Field,
463 ident: AstPtr::new(&ast_ptr).into(), 447 ident: AstPtr::new(&ast_ptr).into(),
464 expected_case: field_to_rename.expected_case, 448 expected_case: field_to_rename.expected_case,
465 ident_text: field_to_rename.current_name.to_string(), 449 ident_text: field_to_rename.current_name.to_string(),
@@ -480,31 +464,24 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
480 464
481 // Check the enum name. 465 // Check the enum name.
482 let enum_name = data.name.to_string(); 466 let enum_name = data.name.to_string();
483 let enum_name_replacement = if let Some(new_name) = to_camel_case(&enum_name) { 467 let enum_name_replacement = to_camel_case(&enum_name).map(|new_name| Replacement {
484 let replacement = Replacement { 468 current_name: data.name.clone(),
485 current_name: data.name.clone(), 469 suggested_text: new_name,
486 suggested_text: new_name, 470 expected_case: CaseType::UpperCamelCase,
487 expected_case: CaseType::UpperCamelCase, 471 });
488 };
489 Some(replacement)
490 } else {
491 None
492 };
493 472
494 // Check the field names. 473 // Check the field names.
495 let mut enum_fields_replacements = Vec::new(); 474 let enum_fields_replacements = data
496 475 .variants
497 for (_, variant) in data.variants.iter() { 476 .iter()
498 let variant_name = variant.name.to_string(); 477 .filter_map(|(_, variant)| {
499 if let Some(new_name) = to_camel_case(&variant_name) { 478 Some(Replacement {
500 let replacement = Replacement {
501 current_name: variant.name.clone(), 479 current_name: variant.name.clone(),
502 suggested_text: new_name, 480 suggested_text: to_camel_case(&variant.name.to_string())?,
503 expected_case: CaseType::UpperCamelCase, 481 expected_case: CaseType::UpperCamelCase,
504 }; 482 })
505 enum_fields_replacements.push(replacement); 483 })
506 } 484 .collect();
507 }
508 485
509 // If there is at least one element to spawn a warning on, go to the source map and generate a warning. 486 // If there is at least one element to spawn a warning on, go to the source map and generate a warning.
510 self.create_incorrect_case_diagnostic_for_enum( 487 self.create_incorrect_case_diagnostic_for_enum(
@@ -534,8 +511,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
534 let ast_ptr = match enum_src.value.name() { 511 let ast_ptr = match enum_src.value.name() {
535 Some(name) => name, 512 Some(name) => name,
536 None => { 513 None => {
537 // We don't want rust-analyzer to panic over this, but it is definitely some kind of error in the logic. 514 never!(
538 log::error!(
539 "Replacement ({:?}) was generated for a enum without a name: {:?}", 515 "Replacement ({:?}) was generated for a enum without a name: {:?}",
540 replacement, 516 replacement,
541 enum_src 517 enum_src
@@ -546,7 +522,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
546 522
547 let diagnostic = IncorrectCase { 523 let diagnostic = IncorrectCase {
548 file: enum_src.file_id, 524 file: enum_src.file_id,
549 ident_type: "Enum".to_string(), 525 ident_type: IdentType::Enum,
550 ident: AstPtr::new(&ast_ptr).into(), 526 ident: AstPtr::new(&ast_ptr).into(),
551 expected_case: replacement.expected_case, 527 expected_case: replacement.expected_case,
552 ident_text: replacement.current_name.to_string(), 528 ident_text: replacement.current_name.to_string(),
@@ -559,12 +535,12 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
559 let enum_variants_list = match enum_src.value.variant_list() { 535 let enum_variants_list = match enum_src.value.variant_list() {
560 Some(variants) => variants, 536 Some(variants) => variants,
561 _ => { 537 _ => {
562 if !enum_variants_replacements.is_empty() { 538 always!(
563 log::error!( 539 enum_variants_replacements.is_empty(),
564 "Replacements ({:?}) were generated for a enum variants which had no fields list: {:?}", 540 "Replacements ({:?}) were generated for a enum variants which had no fields list: {:?}",
565 enum_variants_replacements, enum_src 541 enum_variants_replacements,
566 ); 542 enum_src
567 } 543 );
568 return; 544 return;
569 } 545 }
570 }; 546 };
@@ -573,15 +549,14 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
573 // We assume that parameters in replacement are in the same order as in the 549 // We assume that parameters in replacement are in the same order as in the
574 // actual params list, but just some of them (ones that named correctly) are skipped. 550 // actual params list, but just some of them (ones that named correctly) are skipped.
575 let ast_ptr = loop { 551 let ast_ptr = loop {
576 match enum_variants_iter.next() { 552 match enum_variants_iter.next().and_then(|v| v.name()) {
577 Some(variant) 553 Some(variant_name) => {
578 if names_equal(variant.name(), &variant_to_rename.current_name) => 554 if variant_name.as_name() == variant_to_rename.current_name {
579 { 555 break variant_name;
580 break variant.name().unwrap() 556 }
581 } 557 }
582 Some(_) => {}
583 None => { 558 None => {
584 log::error!( 559 never!(
585 "Replacement ({:?}) was generated for a enum variant which was not found: {:?}", 560 "Replacement ({:?}) was generated for a enum variant which was not found: {:?}",
586 variant_to_rename, enum_src 561 variant_to_rename, enum_src
587 ); 562 );
@@ -592,7 +567,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
592 567
593 let diagnostic = IncorrectCase { 568 let diagnostic = IncorrectCase {
594 file: enum_src.file_id, 569 file: enum_src.file_id,
595 ident_type: "Variant".to_string(), 570 ident_type: IdentType::Variant,
596 ident: AstPtr::new(&ast_ptr).into(), 571 ident: AstPtr::new(&ast_ptr).into(),
597 expected_case: variant_to_rename.expected_case, 572 expected_case: variant_to_rename.expected_case,
598 ident_text: variant_to_rename.current_name.to_string(), 573 ident_text: variant_to_rename.current_name.to_string(),
@@ -637,7 +612,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
637 612
638 let diagnostic = IncorrectCase { 613 let diagnostic = IncorrectCase {
639 file: const_src.file_id, 614 file: const_src.file_id,
640 ident_type: "Constant".to_string(), 615 ident_type: IdentType::Constant,
641 ident: AstPtr::new(&ast_ptr).into(), 616 ident: AstPtr::new(&ast_ptr).into(),
642 expected_case: replacement.expected_case, 617 expected_case: replacement.expected_case,
643 ident_text: replacement.current_name.to_string(), 618 ident_text: replacement.current_name.to_string(),
@@ -685,7 +660,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
685 660
686 let diagnostic = IncorrectCase { 661 let diagnostic = IncorrectCase {
687 file: static_src.file_id, 662 file: static_src.file_id,
688 ident_type: "Static variable".to_string(), 663 ident_type: IdentType::StaticVariable,
689 ident: AstPtr::new(&ast_ptr).into(), 664 ident: AstPtr::new(&ast_ptr).into(),
690 expected_case: replacement.expected_case, 665 expected_case: replacement.expected_case,
691 ident_text: replacement.current_name.to_string(), 666 ident_text: replacement.current_name.to_string(),
@@ -696,22 +671,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
696 } 671 }
697} 672}
698 673
699fn names_equal(left: Option<ast::Name>, right: &Name) -> bool {
700 if let Some(left) = left {
701 &left.as_name() == right
702 } else {
703 false
704 }
705}
706
707fn pat_equals_to_name(pat: Option<ast::Pat>, name: &Name) -> bool {
708 if let Some(ast::Pat::IdentPat(ident)) = pat {
709 ident.to_string() == name.to_string()
710 } else {
711 false
712 }
713}
714
715#[cfg(test)] 674#[cfg(test)]
716mod tests { 675mod tests {
717 use test_utils::mark; 676 use test_utils::mark;
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index a3d4e4f77..9bed329d8 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -72,7 +72,7 @@ pub(crate) fn highlight(
72 } 72 }
73 }; 73 };
74 74
75 let mut hl = highlights::Highlights::new(range_to_highlight); 75 let mut hl = highlights::Highlights::new(root.text_range());
76 traverse(&mut hl, &sema, &root, range_to_highlight, syntactic_name_ref_highlighting); 76 traverse(&mut hl, &sema, &root, range_to_highlight, syntactic_name_ref_highlighting);
77 hl.to_vec() 77 hl.to_vec()
78} 78}
diff --git a/crates/proc_macro_api/src/rpc.rs b/crates/proc_macro_api/src/rpc.rs
index cf830b59f..64cfdafc5 100644
--- a/crates/proc_macro_api/src/rpc.rs
+++ b/crates/proc_macro_api/src/rpc.rs
@@ -262,7 +262,7 @@ mod tests {
262 262
263 assert_eq!(task.macro_body, back.macro_body); 263 assert_eq!(task.macro_body, back.macro_body);
264 264
265 let result = ExpansionResult { expansion: tt.clone() }; 265 let result = ExpansionResult { expansion: tt };
266 let json = serde_json::to_string(&result).unwrap(); 266 let json = serde_json::to_string(&result).unwrap();
267 let back: ExpansionResult = serde_json::from_str(&json).unwrap(); 267 let back: ExpansionResult = serde_json::from_str(&json).unwrap();
268 268
diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml
index 5866c0a28..d28b5e658 100644
--- a/crates/stdx/Cargo.toml
+++ b/crates/stdx/Cargo.toml
@@ -11,7 +11,7 @@ doctest = false
11 11
12[dependencies] 12[dependencies]
13backtrace = { version = "0.3.44", optional = true } 13backtrace = { version = "0.3.44", optional = true }
14always-assert = { version = "0.1.1", features = ["log"] } 14always-assert = { version = "0.1.2", features = ["log"] }
15# Think twice before adding anything here 15# Think twice before adding anything here
16 16
17[features] 17[features]
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index e40b61a94..e3f57f3b2 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -95,16 +95,7 @@ impl Fixture {
95 } 95 }
96 } 96 }
97 97
98 Fixture { 98 Fixture { path, text: String::new(), krate, deps, cfg_atoms, cfg_key_values, edition, env }
99 path,
100 text: String::new(),
101 krate: krate,
102 deps,
103 cfg_atoms,
104 cfg_key_values,
105 edition,
106 env,
107 }
108 } 99 }
109} 100}
110 101
diff --git a/docs/dev/debugging.md b/docs/dev/debugging.md
index cc7a790ff..5876e71bc 100644
--- a/docs/dev/debugging.md
+++ b/docs/dev/debugging.md
@@ -10,7 +10,7 @@
10- Install all TypeScript dependencies 10- Install all TypeScript dependencies
11 ```bash 11 ```bash
12 cd editors/code 12 cd editors/code
13 npm install 13 npm ci
14 ``` 14 ```
15 15
16## Common knowledge 16## Common knowledge
diff --git a/xtask/src/install.rs b/xtask/src/install.rs
index 81b9956b8..3b79cca0d 100644
--- a/xtask/src/install.rs
+++ b/xtask/src/install.rs
@@ -129,7 +129,7 @@ fn install_client(client_opt: ClientOpt) -> Result<()> {
129 129
130 let installed_extensions = if cfg!(unix) { 130 let installed_extensions = if cfg!(unix) {
131 cmd!("npm --version").run().context("`npm` is required to build the VS Code plugin")?; 131 cmd!("npm --version").run().context("`npm` is required to build the VS Code plugin")?;
132 cmd!("npm install").run()?; 132 cmd!("npm ci").run()?;
133 133
134 cmd!("npm run package --scripts-prepend-node-path").run()?; 134 cmd!("npm run package --scripts-prepend-node-path").run()?;
135 135
@@ -140,7 +140,7 @@ fn install_client(client_opt: ClientOpt) -> Result<()> {
140 cmd!("cmd.exe /c npm --version") 140 cmd!("cmd.exe /c npm --version")
141 .run() 141 .run()
142 .context("`npm` is required to build the VS Code plugin")?; 142 .context("`npm` is required to build the VS Code plugin")?;
143 cmd!("cmd.exe /c npm install").run()?; 143 cmd!("cmd.exe /c npm ci").run()?;
144 144
145 cmd!("cmd.exe /c npm run package").run()?; 145 cmd!("cmd.exe /c npm run package").run()?;
146 146