aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/assists')
-rw-r--r--crates/ra_assists/src/assists/add_missing_impl_members.rs127
1 files changed, 126 insertions, 1 deletions
diff --git a/crates/ra_assists/src/assists/add_missing_impl_members.rs b/crates/ra_assists/src/assists/add_missing_impl_members.rs
index 2b0726869..dd62b1b78 100644
--- a/crates/ra_assists/src/assists/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/assists/add_missing_impl_members.rs
@@ -239,9 +239,11 @@ fn substitute_type_params<N: AstNode>(
239 239
240use hir::PathResolution; 240use hir::PathResolution;
241 241
242// TODO handle partial paths, with generic args 242// TODO handle generic args
243// TODO handle associated item paths
243// TODO handle value ns? 244// TODO handle value ns?
244 245
246// FIXME extract this to a general utility as well
245fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from: hir::Module) -> N { 247fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from: hir::Module) -> N {
246 let path_replacements = node 248 let path_replacements = node
247 .value 249 .value
@@ -249,6 +251,10 @@ fn qualify_paths<N: AstNode>(db: &impl HirDatabase, node: hir::InFile<N>, from:
249 .descendants() 251 .descendants()
250 .filter_map(ast::Path::cast) 252 .filter_map(ast::Path::cast)
251 .filter_map(|p| { 253 .filter_map(|p| {
254 if p.segment().and_then(|s| s.param_list()).is_some() {
255 // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
256 return None;
257 }
252 let analyzer = hir::SourceAnalyzer::new(db, node.with_value(p.syntax()), None); 258 let analyzer = hir::SourceAnalyzer::new(db, node.with_value(p.syntax()), None);
253 let resolution = analyzer.resolve_path(db, &p)?; 259 let resolution = analyzer.resolve_path(db, &p)?;
254 match resolution { 260 match resolution {
@@ -469,6 +475,125 @@ impl foo::Foo for S {
469 } 475 }
470 476
471 #[test] 477 #[test]
478 fn test_qualify_path_generic() {
479 check_assist(
480 add_missing_impl_members,
481 "
482mod foo {
483 pub struct Bar<T>;
484 trait Foo { fn foo(&self, bar: Bar<u32>); }
485}
486struct S;
487impl foo::Foo for S { <|> }",
488 "
489mod foo {
490 pub struct Bar<T>;
491 trait Foo { fn foo(&self, bar: Bar<u32>); }
492}
493struct S;
494impl foo::Foo for S {
495 <|>fn foo(&self, bar: foo::Bar<u32>) { unimplemented!() }
496}",
497 );
498 }
499
500 #[test]
501 fn test_qualify_path_and_substitute_param() {
502 check_assist(
503 add_missing_impl_members,
504 "
505mod foo {
506 pub struct Bar<T>;
507 trait Foo<T> { fn foo(&self, bar: Bar<T>); }
508}
509struct S;
510impl foo::Foo<u32> for S { <|> }",
511 "
512mod foo {
513 pub struct Bar<T>;
514 trait Foo<T> { fn foo(&self, bar: Bar<T>); }
515}
516struct S;
517impl foo::Foo<u32> for S {
518 <|>fn foo(&self, bar: foo::Bar<u32>) { unimplemented!() }
519}",
520 );
521 }
522
523 #[test]
524 fn test_qualify_path_associated_item() {
525 check_assist(
526 add_missing_impl_members,
527 "
528mod foo {
529 pub struct Bar<T>;
530 impl Bar<T> { type Assoc = u32; }
531 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
532}
533struct S;
534impl foo::Foo for S { <|> }",
535 "
536mod foo {
537 pub struct Bar<T>;
538 impl Bar { type Assoc = u32; }
539 trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
540}
541struct S;
542impl foo::Foo for S {
543 <|>fn foo(&self, bar: foo::Bar<u32>::Assoc) { unimplemented!() }
544}",
545 );
546 }
547
548 #[test]
549 fn test_qualify_path_nested() {
550 check_assist(
551 add_missing_impl_members,
552 "
553mod foo {
554 pub struct Bar<T>;
555 pub struct Baz;
556 trait Foo { fn foo(&self, bar: Bar<Baz>); }
557}
558struct S;
559impl foo::Foo for S { <|> }",
560 "
561mod foo {
562 pub struct Bar<T>;
563 pub struct Baz;
564 trait Foo { fn foo(&self, bar: Bar<Baz>); }
565}
566struct S;
567impl foo::Foo for S {
568 <|>fn foo(&self, bar: foo::Bar<foo::Baz>) { unimplemented!() }
569}",
570 );
571 }
572
573 #[test]
574 fn test_qualify_path_fn_trait_notation() {
575 check_assist(
576 add_missing_impl_members,
577 "
578mod foo {
579 pub trait Fn<Args> { type Output; }
580 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
581}
582struct S;
583impl foo::Foo for S { <|> }",
584 "
585mod foo {
586 pub trait Fn<Args> { type Output; }
587 trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
588}
589struct S;
590impl foo::Foo for S {
591 <|>fn foo(&self, bar: dyn Fn(u32) -> i32) { unimplemented!() }
592}",
593 );
594 }
595
596 #[test]
472 fn test_empty_trait() { 597 fn test_empty_trait() {
473 check_assist_not_applicable( 598 check_assist_not_applicable(
474 add_missing_impl_members, 599 add_missing_impl_members,