aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/handlers/raw_string.rs131
-rw-r--r--crates/ra_hir_def/Cargo.toml1
-rw-r--r--crates/ra_hir_def/src/import_map.rs300
-rw-r--r--crates/ra_hir_def/src/nameres/tests/mod_resolution.rs32
-rw-r--r--crates/ra_ide/src/call_info.rs4
-rw-r--r--crates/ra_ide/src/completion/presentation.rs16
6 files changed, 241 insertions, 243 deletions
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs
index 6d77dff13..ba1dcb610 100644
--- a/crates/ra_assists/src/handlers/raw_string.rs
+++ b/crates/ra_assists/src/handlers/raw_string.rs
@@ -4,8 +4,9 @@ use ra_syntax::{
4 ast::{self, HasQuotes, HasStringValue}, 4 ast::{self, HasQuotes, HasStringValue},
5 AstToken, 5 AstToken,
6 SyntaxKind::{RAW_STRING, STRING}, 6 SyntaxKind::{RAW_STRING, STRING},
7 TextSize, 7 TextRange, TextSize,
8}; 8};
9use test_utils::mark;
9 10
10use crate::{AssistContext, AssistId, AssistKind, Assists}; 11use crate::{AssistContext, AssistId, AssistKind, Assists};
11 12
@@ -33,8 +34,7 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext) -> Option<
33 "Rewrite as raw string", 34 "Rewrite as raw string",
34 target, 35 target,
35 |edit| { 36 |edit| {
36 let max_hash_streak = count_hashes(&value); 37 let hashes = "#".repeat(required_hashes(&value).max(1));
37 let hashes = "#".repeat(max_hash_streak + 1);
38 if matches!(value, Cow::Borrowed(_)) { 38 if matches!(value, Cow::Borrowed(_)) {
39 // Avoid replacing the whole string to better position the cursor. 39 // Avoid replacing the whole string to better position the cursor.
40 edit.insert(token.syntax().text_range().start(), format!("r{}", hashes)); 40 edit.insert(token.syntax().text_range().start(), format!("r{}", hashes));
@@ -106,7 +106,7 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio
106pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 106pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
107 let token = ctx.find_token_at_offset(RAW_STRING)?; 107 let token = ctx.find_token_at_offset(RAW_STRING)?;
108 let target = token.text_range(); 108 let target = token.text_range();
109 acc.add(AssistId("add_hash", AssistKind::Refactor), "Add # to raw string", target, |edit| { 109 acc.add(AssistId("add_hash", AssistKind::Refactor), "Add #", target, |edit| {
110 edit.insert(token.text_range().start() + TextSize::of('r'), "#"); 110 edit.insert(token.text_range().start() + TextSize::of('r'), "#");
111 edit.insert(token.text_range().end(), "#"); 111 edit.insert(token.text_range().end(), "#");
112 }) 112 })
@@ -128,49 +128,58 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
128// } 128// }
129// ``` 129// ```
130pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 130pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
131 let token = ctx.find_token_at_offset(RAW_STRING)?; 131 let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?;
132
132 let text = token.text().as_str(); 133 let text = token.text().as_str();
133 if text.starts_with("r\"") { 134 if !text.starts_with("r#") && text.ends_with("#") {
134 // no hash to remove
135 return None; 135 return None;
136 } 136 }
137 let target = token.text_range(); 137
138 acc.add( 138 let existing_hashes = text.chars().skip(1).take_while(|&it| it == '#').count();
139 AssistId("remove_hash", AssistKind::RefactorRewrite), 139
140 "Remove hash from raw string", 140 let text_range = token.syntax().text_range();
141 target, 141 let internal_text = &text[token.text_range_between_quotes()? - text_range.start()];
142 |edit| { 142
143 let result = &text[2..text.len() - 1]; 143 if existing_hashes == required_hashes(internal_text) {
144 let result = if result.starts_with('\"') { 144 mark::hit!(cant_remove_required_hash);
145 // FIXME: this logic is wrong, not only the last has has to handled specially 145 return None;
146 // no more hash, escape 146 }
147 let internal_str = &result[1..result.len() - 1]; 147
148 format!("\"{}\"", internal_str.escape_default().to_string()) 148 acc.add(AssistId("remove_hash", AssistKind::RefactorRewrite), "Remove #", text_range, |edit| {
149 } else { 149 edit.delete(TextRange::at(text_range.start() + TextSize::of('r'), TextSize::of('#')));
150 result.to_owned() 150 edit.delete(TextRange::new(text_range.end() - TextSize::of('#'), text_range.end()));
151 }; 151 })
152 edit.replace(token.text_range(), format!("r{}", result));
153 },
154 )
155} 152}
156 153
157fn count_hashes(s: &str) -> usize { 154fn required_hashes(s: &str) -> usize {
158 let mut max_hash_streak = 0usize; 155 let mut res = 0usize;
159 for idx in s.match_indices("\"#").map(|(i, _)| i) { 156 for idx in s.match_indices('"').map(|(i, _)| i) {
160 let (_, sub) = s.split_at(idx + 1); 157 let (_, sub) = s.split_at(idx + 1);
161 let nb_hash = sub.chars().take_while(|c| *c == '#').count(); 158 let n_hashes = sub.chars().take_while(|c| *c == '#').count();
162 if nb_hash > max_hash_streak { 159 res = res.max(n_hashes + 1)
163 max_hash_streak = nb_hash;
164 }
165 } 160 }
166 max_hash_streak 161 res
162}
163
164#[test]
165fn test_required_hashes() {
166 assert_eq!(0, required_hashes("abc"));
167 assert_eq!(0, required_hashes("###"));
168 assert_eq!(1, required_hashes("\""));
169 assert_eq!(2, required_hashes("\"#abc"));
170 assert_eq!(0, required_hashes("#abc"));
171 assert_eq!(3, required_hashes("#ab\"##c"));
172 assert_eq!(5, required_hashes("#ab\"##\"####c"));
167} 173}
168 174
169#[cfg(test)] 175#[cfg(test)]
170mod test { 176mod test {
171 use super::*; 177 use test_utils::mark;
178
172 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 179 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
173 180
181 use super::*;
182
174 #[test] 183 #[test]
175 fn make_raw_string_target() { 184 fn make_raw_string_target() {
176 check_assist_target( 185 check_assist_target(
@@ -372,33 +381,21 @@ string"###;
372 fn remove_hash_works() { 381 fn remove_hash_works() {
373 check_assist( 382 check_assist(
374 remove_hash, 383 remove_hash,
375 r##" 384 r##"fn f() { let s = <|>r#"random string"#; }"##,
376 fn f() { 385 r#"fn f() { let s = r"random string"; }"#,
377 let s = <|>r#"random string"#;
378 }
379 "##,
380 r#"
381 fn f() {
382 let s = r"random string";
383 }
384 "#,
385 ) 386 )
386 } 387 }
387 388
388 #[test] 389 #[test]
389 fn remove_hash_with_quote_works() { 390 fn cant_remove_required_hash() {
390 check_assist( 391 mark::check!(cant_remove_required_hash);
392 check_assist_not_applicable(
391 remove_hash, 393 remove_hash,
392 r##" 394 r##"
393 fn f() { 395 fn f() {
394 let s = <|>r#"random"str"ing"#; 396 let s = <|>r#"random"str"ing"#;
395 } 397 }
396 "##, 398 "##,
397 r#"
398 fn f() {
399 let s = r"random\"str\"ing";
400 }
401 "#,
402 ) 399 )
403 } 400 }
404 401
@@ -420,27 +417,13 @@ string"###;
420 } 417 }
421 418
422 #[test] 419 #[test]
423 fn remove_hash_not_works() { 420 fn remove_hash_doesnt_work() {
424 check_assist_not_applicable( 421 check_assist_not_applicable(remove_hash, r#"fn f() { let s = <|>"random string"; }"#);
425 remove_hash,
426 r#"
427 fn f() {
428 let s = <|>"random string";
429 }
430 "#,
431 );
432 } 422 }
433 423
434 #[test] 424 #[test]
435 fn remove_hash_no_hash_not_works() { 425 fn remove_hash_no_hash_doesnt_work() {
436 check_assist_not_applicable( 426 check_assist_not_applicable(remove_hash, r#"fn f() { let s = <|>r"random string"; }"#);
437 remove_hash,
438 r#"
439 fn f() {
440 let s = <|>r"random string";
441 }
442 "#,
443 );
444 } 427 }
445 428
446 #[test] 429 #[test]
@@ -518,14 +501,4 @@ string"###;
518 "#, 501 "#,
519 ); 502 );
520 } 503 }
521
522 #[test]
523 fn count_hashes_test() {
524 assert_eq!(0, count_hashes("abc"));
525 assert_eq!(0, count_hashes("###"));
526 assert_eq!(1, count_hashes("\"#abc"));
527 assert_eq!(0, count_hashes("#abc"));
528 assert_eq!(2, count_hashes("#ab\"##c"));
529 assert_eq!(4, count_hashes("#ab\"##\"####c"));
530 }
531} 504}
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index 1ec619b42..d96a86b80 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -33,5 +33,4 @@ ra_cfg = { path = "../ra_cfg" }
33tt = { path = "../ra_tt", package = "ra_tt" } 33tt = { path = "../ra_tt", package = "ra_tt" }
34 34
35[dev-dependencies] 35[dev-dependencies]
36insta = "0.16.0"
37expect = { path = "../expect" } 36expect = { path = "../expect" }
diff --git a/crates/ra_hir_def/src/import_map.rs b/crates/ra_hir_def/src/import_map.rs
index 869f3ca5a..9e4c30b1a 100644
--- a/crates/ra_hir_def/src/import_map.rs
+++ b/crates/ra_hir_def/src/import_map.rs
@@ -327,32 +327,14 @@ pub fn search_dependencies<'a>(
327 327
328#[cfg(test)] 328#[cfg(test)]
329mod tests { 329mod tests {
330 use super::*; 330 use expect::{expect, Expect};
331 use crate::{test_db::TestDB, AssocContainerId, Lookup}; 331 use ra_db::{fixture::WithFixture, SourceDatabase, Upcast};
332 use insta::assert_snapshot;
333 use itertools::Itertools;
334 use ra_db::fixture::WithFixture;
335 use ra_db::{SourceDatabase, Upcast};
336 332
337 fn import_map(ra_fixture: &str) -> String { 333 use crate::{test_db::TestDB, AssocContainerId, Lookup};
338 let db = TestDB::with_files(ra_fixture);
339 let crate_graph = db.crate_graph();
340
341 let s = crate_graph
342 .iter()
343 .filter_map(|krate| {
344 let cdata = &crate_graph[krate];
345 let name = cdata.display_name.as_ref()?;
346
347 let map = db.import_map(krate);
348 334
349 Some(format!("{}:\n{:?}", name, map)) 335 use super::*;
350 })
351 .join("\n");
352 s
353 }
354 336
355 fn search_dependencies_of(ra_fixture: &str, krate_name: &str, query: Query) -> String { 337 fn check_search(ra_fixture: &str, krate_name: &str, query: Query, expect: Expect) {
356 let db = TestDB::with_files(ra_fixture); 338 let db = TestDB::with_files(ra_fixture);
357 let crate_graph = db.crate_graph(); 339 let crate_graph = db.crate_graph();
358 let krate = crate_graph 340 let krate = crate_graph
@@ -363,7 +345,7 @@ mod tests {
363 }) 345 })
364 .unwrap(); 346 .unwrap();
365 347
366 search_dependencies(db.upcast(), krate, query) 348 let actual = search_dependencies(db.upcast(), krate, query)
367 .into_iter() 349 .into_iter()
368 .filter_map(|item| { 350 .filter_map(|item| {
369 let mark = match item { 351 let mark = match item {
@@ -376,14 +358,15 @@ mod tests {
376 let map = db.import_map(krate); 358 let map = db.import_map(krate);
377 let path = map.path_of(item).unwrap(); 359 let path = map.path_of(item).unwrap();
378 format!( 360 format!(
379 "{}::{} ({})", 361 "{}::{} ({})\n",
380 crate_graph[krate].display_name.as_ref().unwrap(), 362 crate_graph[krate].display_name.as_ref().unwrap(),
381 path, 363 path,
382 mark 364 mark
383 ) 365 )
384 }) 366 })
385 }) 367 })
386 .join("\n") 368 .collect::<String>();
369 expect.assert_eq(&actual)
387 } 370 }
388 371
389 fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> ItemInNs { 372 fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> ItemInNs {
@@ -409,9 +392,28 @@ mod tests {
409 } 392 }
410 } 393 }
411 394
395 fn check(ra_fixture: &str, expect: Expect) {
396 let db = TestDB::with_files(ra_fixture);
397 let crate_graph = db.crate_graph();
398
399 let actual = crate_graph
400 .iter()
401 .filter_map(|krate| {
402 let cdata = &crate_graph[krate];
403 let name = cdata.display_name.as_ref()?;
404
405 let map = db.import_map(krate);
406
407 Some(format!("{}:\n{:?}\n", name, map))
408 })
409 .collect::<String>();
410
411 expect.assert_eq(&actual)
412 }
413
412 #[test] 414 #[test]
413 fn smoke() { 415 fn smoke() {
414 let map = import_map( 416 check(
415 r" 417 r"
416 //- /main.rs crate:main deps:lib 418 //- /main.rs crate:main deps:lib
417 419
@@ -436,24 +438,23 @@ mod tests {
436 pub struct Pub2; // t + v 438 pub struct Pub2; // t + v
437 struct Priv; 439 struct Priv;
438 ", 440 ",
441 expect![[r#"
442 main:
443 - publ1 (t)
444 - real_pu2 (t)
445 - real_pub (t)
446 - real_pub::Pub (t)
447 lib:
448 - Pub (t)
449 - Pub2 (t)
450 - Pub2 (v)
451 "#]],
439 ); 452 );
440
441 assert_snapshot!(map, @r###"
442 main:
443 - publ1 (t)
444 - real_pu2 (t)
445 - real_pub (t)
446 - real_pub::Pub (t)
447 lib:
448 - Pub (t)
449 - Pub2 (t)
450 - Pub2 (v)
451 "###);
452 } 453 }
453 454
454 #[test] 455 #[test]
455 fn prefers_shortest_path() { 456 fn prefers_shortest_path() {
456 let map = import_map( 457 check(
457 r" 458 r"
458 //- /main.rs crate:main 459 //- /main.rs crate:main
459 460
@@ -465,21 +466,20 @@ mod tests {
465 pub use super::sub::subsub::Def; 466 pub use super::sub::subsub::Def;
466 } 467 }
467 ", 468 ",
469 expect![[r#"
470 main:
471 - sub (t)
472 - sub::Def (t)
473 - sub::subsub (t)
474 "#]],
468 ); 475 );
469
470 assert_snapshot!(map, @r###"
471 main:
472 - sub (t)
473 - sub::Def (t)
474 - sub::subsub (t)
475 "###);
476 } 476 }
477 477
478 #[test] 478 #[test]
479 fn type_reexport_cross_crate() { 479 fn type_reexport_cross_crate() {
480 // Reexports need to be visible from a crate, even if the original crate exports the item 480 // Reexports need to be visible from a crate, even if the original crate exports the item
481 // at a shorter path. 481 // at a shorter path.
482 let map = import_map( 482 check(
483 r" 483 r"
484 //- /main.rs crate:main deps:lib 484 //- /main.rs crate:main deps:lib
485 pub mod m { 485 pub mod m {
@@ -488,22 +488,21 @@ mod tests {
488 //- /lib.rs crate:lib 488 //- /lib.rs crate:lib
489 pub struct S; 489 pub struct S;
490 ", 490 ",
491 expect![[r#"
492 main:
493 - m (t)
494 - m::S (t)
495 - m::S (v)
496 lib:
497 - S (t)
498 - S (v)
499 "#]],
491 ); 500 );
492
493 assert_snapshot!(map, @r###"
494 main:
495 - m (t)
496 - m::S (t)
497 - m::S (v)
498 lib:
499 - S (t)
500 - S (v)
501 "###);
502 } 501 }
503 502
504 #[test] 503 #[test]
505 fn macro_reexport() { 504 fn macro_reexport() {
506 let map = import_map( 505 check(
507 r" 506 r"
508 //- /main.rs crate:main deps:lib 507 //- /main.rs crate:main deps:lib
509 pub mod m { 508 pub mod m {
@@ -515,21 +514,20 @@ mod tests {
515 () => {}; 514 () => {};
516 } 515 }
517 ", 516 ",
517 expect![[r#"
518 main:
519 - m (t)
520 - m::pub_macro (m)
521 lib:
522 - pub_macro (m)
523 "#]],
518 ); 524 );
519
520 assert_snapshot!(map, @r###"
521 main:
522 - m (t)
523 - m::pub_macro (m)
524 lib:
525 - pub_macro (m)
526 "###);
527 } 525 }
528 526
529 #[test] 527 #[test]
530 fn module_reexport() { 528 fn module_reexport() {
531 // Reexporting modules from a dependency adds all contents to the import map. 529 // Reexporting modules from a dependency adds all contents to the import map.
532 let map = import_map( 530 check(
533 r" 531 r"
534 //- /main.rs crate:main deps:lib 532 //- /main.rs crate:main deps:lib
535 pub use lib::module as reexported_module; 533 pub use lib::module as reexported_module;
@@ -538,24 +536,23 @@ mod tests {
538 pub struct S; 536 pub struct S;
539 } 537 }
540 ", 538 ",
539 expect![[r#"
540 main:
541 - reexported_module (t)
542 - reexported_module::S (t)
543 - reexported_module::S (v)
544 lib:
545 - module (t)
546 - module::S (t)
547 - module::S (v)
548 "#]],
541 ); 549 );
542
543 assert_snapshot!(map, @r###"
544 main:
545 - reexported_module (t)
546 - reexported_module::S (t)
547 - reexported_module::S (v)
548 lib:
549 - module (t)
550 - module::S (t)
551 - module::S (v)
552 "###);
553 } 550 }
554 551
555 #[test] 552 #[test]
556 fn cyclic_module_reexport() { 553 fn cyclic_module_reexport() {
557 // A cyclic reexport does not hang. 554 // A cyclic reexport does not hang.
558 let map = import_map( 555 check(
559 r" 556 r"
560 //- /lib.rs crate:lib 557 //- /lib.rs crate:lib
561 pub mod module { 558 pub mod module {
@@ -567,36 +564,35 @@ mod tests {
567 pub use super::module; 564 pub use super::module;
568 } 565 }
569 ", 566 ",
567 expect![[r#"
568 lib:
569 - module (t)
570 - module::S (t)
571 - module::S (v)
572 - sub (t)
573 "#]],
570 ); 574 );
571
572 assert_snapshot!(map, @r###"
573 lib:
574 - module (t)
575 - module::S (t)
576 - module::S (v)
577 - sub (t)
578 "###);
579 } 575 }
580 576
581 #[test] 577 #[test]
582 fn private_macro() { 578 fn private_macro() {
583 let map = import_map( 579 check(
584 r" 580 r"
585 //- /lib.rs crate:lib 581 //- /lib.rs crate:lib
586 macro_rules! private_macro { 582 macro_rules! private_macro {
587 () => {}; 583 () => {};
588 } 584 }
589 ", 585 ",
590 ); 586 expect![[r#"
587 lib:
591 588
592 assert_snapshot!(map, @r###" 589 "#]],
593 lib: 590 );
594 "###);
595 } 591 }
596 592
597 #[test] 593 #[test]
598 fn namespacing() { 594 fn namespacing() {
599 let map = import_map( 595 check(
600 r" 596 r"
601 //- /lib.rs crate:lib 597 //- /lib.rs crate:lib
602 pub struct Thing; // t + v 598 pub struct Thing; // t + v
@@ -605,16 +601,15 @@ mod tests {
605 () => {}; 601 () => {};
606 } 602 }
607 ", 603 ",
604 expect![[r#"
605 lib:
606 - Thing (m)
607 - Thing (t)
608 - Thing (v)
609 "#]],
608 ); 610 );
609 611
610 assert_snapshot!(map, @r###" 612 check(
611 lib:
612 - Thing (m)
613 - Thing (t)
614 - Thing (v)
615 "###);
616
617 let map = import_map(
618 r" 613 r"
619 //- /lib.rs crate:lib 614 //- /lib.rs crate:lib
620 pub mod Thing {} // t 615 pub mod Thing {} // t
@@ -623,13 +618,12 @@ mod tests {
623 () => {}; 618 () => {};
624 } 619 }
625 ", 620 ",
621 expect![[r#"
622 lib:
623 - Thing (m)
624 - Thing (t)
625 "#]],
626 ); 626 );
627
628 assert_snapshot!(map, @r###"
629 lib:
630 - Thing (m)
631 - Thing (t)
632 "###);
633 } 627 }
634 628
635 #[test] 629 #[test]
@@ -658,25 +652,33 @@ mod tests {
658 } 652 }
659 "#; 653 "#;
660 654
661 let res = search_dependencies_of(ra_fixture, "main", Query::new("fmt")); 655 check_search(
662 assert_snapshot!(res, @r###" 656 ra_fixture,
663 dep::fmt (t) 657 "main",
664 dep::Fmt (t) 658 Query::new("fmt"),
665 dep::Fmt (v) 659 expect![[r#"
666 dep::Fmt (m) 660 dep::fmt (t)
667 dep::fmt::Display (t) 661 dep::Fmt (t)
668 dep::format (v) 662 dep::Fmt (v)
669 dep::fmt::Display (t) 663 dep::Fmt (m)
670 "###); 664 dep::fmt::Display (t)
671 665 dep::format (v)
672 let res = search_dependencies_of(ra_fixture, "main", Query::new("fmt").anchor_end()); 666 dep::fmt::Display (t)
673 assert_snapshot!(res, @r###" 667 "#]],
674 dep::fmt (t) 668 );
675 dep::Fmt (t) 669
676 dep::Fmt (v) 670 check_search(
677 dep::Fmt (m) 671 ra_fixture,
678 dep::fmt::Display (t) 672 "main",
679 "###); 673 Query::new("fmt").anchor_end(),
674 expect![[r#"
675 dep::fmt (t)
676 dep::Fmt (t)
677 dep::Fmt (v)
678 dep::Fmt (m)
679 dep::fmt::Display (t)
680 "#]],
681 );
680 } 682 }
681 683
682 #[test] 684 #[test]
@@ -689,26 +691,32 @@ mod tests {
689 pub struct FMT; 691 pub struct FMT;
690 "#; 692 "#;
691 693
692 let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT")); 694 check_search(
693 695 ra_fixture,
694 assert_snapshot!(res, @r###" 696 "main",
695 dep::fmt (t) 697 Query::new("FMT"),
696 dep::fmt (v) 698 expect![[r#"
697 dep::FMT (t) 699 dep::fmt (t)
698 dep::FMT (v) 700 dep::fmt (v)
699 "###); 701 dep::FMT (t)
700 702 dep::FMT (v)
701 let res = search_dependencies_of(ra_fixture, "main", Query::new("FMT").case_sensitive()); 703 "#]],
704 );
702 705
703 assert_snapshot!(res, @r###" 706 check_search(
704 dep::FMT (t) 707 ra_fixture,
705 dep::FMT (v) 708 "main",
706 "###); 709 Query::new("FMT").case_sensitive(),
710 expect![[r#"
711 dep::FMT (t)
712 dep::FMT (v)
713 "#]],
714 );
707 } 715 }
708 716
709 #[test] 717 #[test]
710 fn search_limit() { 718 fn search_limit() {
711 let res = search_dependencies_of( 719 check_search(
712 r#" 720 r#"
713 //- /main.rs crate:main deps:dep 721 //- /main.rs crate:main deps:dep
714 //- /dep.rs crate:dep 722 //- /dep.rs crate:dep
@@ -728,10 +736,10 @@ mod tests {
728 "#, 736 "#,
729 "main", 737 "main",
730 Query::new("").limit(2), 738 Query::new("").limit(2),
739 expect![[r#"
740 dep::fmt (t)
741 dep::Fmt (t)
742 "#]],
731 ); 743 );
732 assert_snapshot!(res, @r###"
733 dep::fmt (t)
734 dep::Fmt (t)
735 "###);
736 } 744 }
737} 745}
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
index 3da16fbe3..ae58948c4 100644
--- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -686,27 +686,25 @@ fn unresolved_module_diagnostics() {
686 686
687 let crate_def_map = db.crate_def_map(krate); 687 let crate_def_map = db.crate_def_map(krate);
688 688
689 insta::assert_debug_snapshot!( 689 expect![[r#"
690 crate_def_map.diagnostics, 690 [
691 @r###" 691 UnresolvedModule {
692 [ 692 module: Idx::<ModuleData>(0),
693 UnresolvedModule { 693 declaration: InFile {
694 module: Idx::<ModuleData>(0), 694 file_id: HirFileId(
695 declaration: InFile {
696 file_id: HirFileId(
697 FileId(
698 FileId( 695 FileId(
699 0, 696 FileId(
697 0,
698 ),
700 ), 699 ),
701 ), 700 ),
702 ), 701 value: FileAstId::<ra_syntax::ast::generated::nodes::Module>(1),
703 value: FileAstId::<ra_syntax::ast::generated::nodes::Module>(1), 702 },
703 candidate: "bar.rs",
704 }, 704 },
705 candidate: "bar.rs", 705 ]
706 }, 706 "#]]
707 ] 707 .assert_debug_eq(&crate_def_map.diagnostics);
708 "###
709 );
710} 708}
711 709
712#[test] 710#[test]
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 14980afdd..ff602202f 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -161,6 +161,10 @@ impl ActiveParameter {
161 161
162 let idx = active_parameter?; 162 let idx = active_parameter?;
163 let mut params = signature.params(sema.db); 163 let mut params = signature.params(sema.db);
164 if !(idx < params.len()) {
165 mark::hit!(too_many_arguments);
166 return None;
167 }
164 let (pat, ty) = params.swap_remove(idx); 168 let (pat, ty) = params.swap_remove(idx);
165 let name = pat?.to_string(); 169 let name = pat?.to_string();
166 Some(ActiveParameter { ty, name }) 170 Some(ActiveParameter { ty, name })
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index c7b74e635..9a94ff476 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -1160,6 +1160,22 @@ fn go(world: &WorldSnapshot) { go(w<|>) }
1160 } 1160 }
1161 1161
1162 #[test] 1162 #[test]
1163 fn too_many_arguments() {
1164 mark::check!(too_many_arguments);
1165 check_scores(
1166 r#"
1167struct Foo;
1168fn f(foo: &Foo) { f(foo, w<|>) }
1169"#,
1170 expect![[r#"
1171 st Foo []
1172 fn f(…) []
1173 bn foo []
1174 "#]],
1175 );
1176 }
1177
1178 #[test]
1163 fn guesses_macro_braces() { 1179 fn guesses_macro_braces() {
1164 check_edit( 1180 check_edit(
1165 "vec!", 1181 "vec!",