diff options
Diffstat (limited to 'crates/ra_ide/src/diagnostics.rs')
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 15dc50cf1..e1bfd72f9 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -21,7 +21,7 @@ use ra_syntax::{ | |||
21 | }; | 21 | }; |
22 | use ra_text_edit::{TextEdit, TextEditBuilder}; | 22 | use ra_text_edit::{TextEdit, TextEditBuilder}; |
23 | 23 | ||
24 | use crate::{Diagnostic, FileId, FileSystemEdit, Fix, SourceChange, SourceFileEdit}; | 24 | use crate::{Diagnostic, FileId, FileSystemEdit, Fix, SourceFileEdit}; |
25 | 25 | ||
26 | #[derive(Debug, Copy, Clone)] | 26 | #[derive(Debug, Copy, Clone)] |
27 | pub enum Severity { | 27 | pub enum Severity { |
@@ -115,7 +115,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic> | |||
115 | let node = d.ast(db); | 115 | let node = d.ast(db); |
116 | let replacement = format!("Ok({})", node.syntax()); | 116 | let replacement = format!("Ok({})", node.syntax()); |
117 | let edit = TextEdit::replace(node.syntax().text_range(), replacement); | 117 | let edit = TextEdit::replace(node.syntax().text_range(), replacement); |
118 | let source_change = SourceChange::source_file_edit_from(file_id, edit); | 118 | let source_change = SourceFileEdit { file_id, edit }.into(); |
119 | let fix = Fix::new("Wrap with ok", source_change); | 119 | let fix = Fix::new("Wrap with ok", source_change); |
120 | res.borrow_mut().push(Diagnostic { | 120 | res.borrow_mut().push(Diagnostic { |
121 | range: sema.diagnostics_range(d).range, | 121 | range: sema.diagnostics_range(d).range, |
@@ -187,7 +187,8 @@ fn check_struct_shorthand_initialization( | |||
187 | if let (Some(name_ref), Some(expr)) = (record_field.name_ref(), record_field.expr()) { | 187 | if let (Some(name_ref), Some(expr)) = (record_field.name_ref(), record_field.expr()) { |
188 | let field_name = name_ref.syntax().text().to_string(); | 188 | let field_name = name_ref.syntax().text().to_string(); |
189 | let field_expr = expr.syntax().text().to_string(); | 189 | let field_expr = expr.syntax().text().to_string(); |
190 | if field_name == field_expr { | 190 | let field_name_is_tup_index = name_ref.as_tuple_field().is_some(); |
191 | if field_name == field_expr && !field_name_is_tup_index { | ||
191 | let mut edit_builder = TextEditBuilder::default(); | 192 | let mut edit_builder = TextEditBuilder::default(); |
192 | edit_builder.delete(record_field.syntax().text_range()); | 193 | edit_builder.delete(record_field.syntax().text_range()); |
193 | edit_builder.insert(record_field.syntax().text_range().start(), field_name); | 194 | edit_builder.insert(record_field.syntax().text_range().start(), field_name); |
@@ -321,29 +322,26 @@ mod tests { | |||
321 | fn test_wrap_return_type() { | 322 | fn test_wrap_return_type() { |
322 | let before = r#" | 323 | let before = r#" |
323 | //- /main.rs | 324 | //- /main.rs |
324 | use std::{string::String, result::Result::{self, Ok, Err}}; | 325 | use core::result::Result::{self, Ok, Err}; |
325 | 326 | ||
326 | fn div(x: i32, y: i32) -> Result<i32, String> { | 327 | fn div(x: i32, y: i32) -> Result<i32, ()> { |
327 | if y == 0 { | 328 | if y == 0 { |
328 | return Err("div by zero".into()); | 329 | return Err(()); |
329 | } | 330 | } |
330 | x / y<|> | 331 | x / y<|> |
331 | } | 332 | } |
332 | 333 | ||
333 | //- /std/lib.rs | 334 | //- /core/lib.rs |
334 | pub mod string { | ||
335 | pub struct String { } | ||
336 | } | ||
337 | pub mod result { | 335 | pub mod result { |
338 | pub enum Result<T, E> { Ok(T), Err(E) } | 336 | pub enum Result<T, E> { Ok(T), Err(E) } |
339 | } | 337 | } |
340 | "#; | 338 | "#; |
341 | let after = r#" | 339 | let after = r#" |
342 | use std::{string::String, result::Result::{self, Ok, Err}}; | 340 | use core::result::Result::{self, Ok, Err}; |
343 | 341 | ||
344 | fn div(x: i32, y: i32) -> Result<i32, String> { | 342 | fn div(x: i32, y: i32) -> Result<i32, ()> { |
345 | if y == 0 { | 343 | if y == 0 { |
346 | return Err("div by zero".into()); | 344 | return Err(()); |
347 | } | 345 | } |
348 | Ok(x / y) | 346 | Ok(x / y) |
349 | } | 347 | } |
@@ -355,7 +353,7 @@ mod tests { | |||
355 | fn test_wrap_return_type_handles_generic_functions() { | 353 | fn test_wrap_return_type_handles_generic_functions() { |
356 | let before = r#" | 354 | let before = r#" |
357 | //- /main.rs | 355 | //- /main.rs |
358 | use std::result::Result::{self, Ok, Err}; | 356 | use core::result::Result::{self, Ok, Err}; |
359 | 357 | ||
360 | fn div<T>(x: T) -> Result<T, i32> { | 358 | fn div<T>(x: T) -> Result<T, i32> { |
361 | if x == 0 { | 359 | if x == 0 { |
@@ -364,13 +362,13 @@ mod tests { | |||
364 | <|>x | 362 | <|>x |
365 | } | 363 | } |
366 | 364 | ||
367 | //- /std/lib.rs | 365 | //- /core/lib.rs |
368 | pub mod result { | 366 | pub mod result { |
369 | pub enum Result<T, E> { Ok(T), Err(E) } | 367 | pub enum Result<T, E> { Ok(T), Err(E) } |
370 | } | 368 | } |
371 | "#; | 369 | "#; |
372 | let after = r#" | 370 | let after = r#" |
373 | use std::result::Result::{self, Ok, Err}; | 371 | use core::result::Result::{self, Ok, Err}; |
374 | 372 | ||
375 | fn div<T>(x: T) -> Result<T, i32> { | 373 | fn div<T>(x: T) -> Result<T, i32> { |
376 | if x == 0 { | 374 | if x == 0 { |
@@ -386,32 +384,29 @@ mod tests { | |||
386 | fn test_wrap_return_type_handles_type_aliases() { | 384 | fn test_wrap_return_type_handles_type_aliases() { |
387 | let before = r#" | 385 | let before = r#" |
388 | //- /main.rs | 386 | //- /main.rs |
389 | use std::{string::String, result::Result::{self, Ok, Err}}; | 387 | use core::result::Result::{self, Ok, Err}; |
390 | 388 | ||
391 | type MyResult<T> = Result<T, String>; | 389 | type MyResult<T> = Result<T, ()>; |
392 | 390 | ||
393 | fn div(x: i32, y: i32) -> MyResult<i32> { | 391 | fn div(x: i32, y: i32) -> MyResult<i32> { |
394 | if y == 0 { | 392 | if y == 0 { |
395 | return Err("div by zero".into()); | 393 | return Err(()); |
396 | } | 394 | } |
397 | x <|>/ y | 395 | x <|>/ y |
398 | } | 396 | } |
399 | 397 | ||
400 | //- /std/lib.rs | 398 | //- /core/lib.rs |
401 | pub mod string { | ||
402 | pub struct String { } | ||
403 | } | ||
404 | pub mod result { | 399 | pub mod result { |
405 | pub enum Result<T, E> { Ok(T), Err(E) } | 400 | pub enum Result<T, E> { Ok(T), Err(E) } |
406 | } | 401 | } |
407 | "#; | 402 | "#; |
408 | let after = r#" | 403 | let after = r#" |
409 | use std::{string::String, result::Result::{self, Ok, Err}}; | 404 | use core::result::Result::{self, Ok, Err}; |
410 | 405 | ||
411 | type MyResult<T> = Result<T, String>; | 406 | type MyResult<T> = Result<T, ()>; |
412 | fn div(x: i32, y: i32) -> MyResult<i32> { | 407 | fn div(x: i32, y: i32) -> MyResult<i32> { |
413 | if y == 0 { | 408 | if y == 0 { |
414 | return Err("div by zero".into()); | 409 | return Err(()); |
415 | } | 410 | } |
416 | Ok(x / y) | 411 | Ok(x / y) |
417 | } | 412 | } |
@@ -423,16 +418,13 @@ mod tests { | |||
423 | fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() { | 418 | fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() { |
424 | let content = r#" | 419 | let content = r#" |
425 | //- /main.rs | 420 | //- /main.rs |
426 | use std::{string::String, result::Result::{self, Ok, Err}}; | 421 | use core::result::Result::{self, Ok, Err}; |
427 | 422 | ||
428 | fn foo() -> Result<String, i32> { | 423 | fn foo() -> Result<(), i32> { |
429 | 0<|> | 424 | 0<|> |
430 | } | 425 | } |
431 | 426 | ||
432 | //- /std/lib.rs | 427 | //- /core/lib.rs |
433 | pub mod string { | ||
434 | pub struct String { } | ||
435 | } | ||
436 | pub mod result { | 428 | pub mod result { |
437 | pub enum Result<T, E> { Ok(T), Err(E) } | 429 | pub enum Result<T, E> { Ok(T), Err(E) } |
438 | } | 430 | } |
@@ -444,7 +436,7 @@ mod tests { | |||
444 | fn test_wrap_return_type_not_applicable_when_return_type_is_not_result() { | 436 | fn test_wrap_return_type_not_applicable_when_return_type_is_not_result() { |
445 | let content = r#" | 437 | let content = r#" |
446 | //- /main.rs | 438 | //- /main.rs |
447 | use std::{string::String, result::Result::{self, Ok, Err}}; | 439 | use core::result::Result::{self, Ok, Err}; |
448 | 440 | ||
449 | enum SomeOtherEnum { | 441 | enum SomeOtherEnum { |
450 | Ok(i32), | 442 | Ok(i32), |
@@ -455,10 +447,7 @@ mod tests { | |||
455 | 0<|> | 447 | 0<|> |
456 | } | 448 | } |
457 | 449 | ||
458 | //- /std/lib.rs | 450 | //- /core/lib.rs |
459 | pub mod string { | ||
460 | pub struct String { } | ||
461 | } | ||
462 | pub mod result { | 451 | pub mod result { |
463 | pub enum Result<T, E> { Ok(T), Err(E) } | 452 | pub enum Result<T, E> { Ok(T), Err(E) } |
464 | } | 453 | } |
@@ -731,6 +720,18 @@ mod tests { | |||
731 | "#, | 720 | "#, |
732 | check_struct_shorthand_initialization, | 721 | check_struct_shorthand_initialization, |
733 | ); | 722 | ); |
723 | check_not_applicable( | ||
724 | r#" | ||
725 | struct A(usize); | ||
726 | |||
727 | fn main() { | ||
728 | A { | ||
729 | 0: 0 | ||
730 | } | ||
731 | } | ||
732 | "#, | ||
733 | check_struct_shorthand_initialization, | ||
734 | ); | ||
734 | 735 | ||
735 | check_apply( | 736 | check_apply( |
736 | r#" | 737 | r#" |