From 5cb1f7132277e16ec4eecafbc274563c4d27158e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Wed, 1 Jan 2020 23:08:22 +0100 Subject: More failing tests --- .../src/assists/add_missing_impl_members.rs | 127 ++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) (limited to 'crates/ra_assists/src/assists') 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( use hir::PathResolution; -// TODO handle partial paths, with generic args +// TODO handle generic args +// TODO handle associated item paths // TODO handle value ns? +// FIXME extract this to a general utility as well fn qualify_paths(db: &impl HirDatabase, node: hir::InFile, from: hir::Module) -> N { let path_replacements = node .value @@ -249,6 +251,10 @@ fn qualify_paths(db: &impl HirDatabase, node: hir::InFile, from: .descendants() .filter_map(ast::Path::cast) .filter_map(|p| { + if p.segment().and_then(|s| s.param_list()).is_some() { + // don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway + return None; + } let analyzer = hir::SourceAnalyzer::new(db, node.with_value(p.syntax()), None); let resolution = analyzer.resolve_path(db, &p)?; match resolution { @@ -468,6 +474,125 @@ impl foo::Foo for S { ); } + #[test] + fn test_qualify_path_generic() { + check_assist( + add_missing_impl_members, + " +mod foo { + pub struct Bar; + trait Foo { fn foo(&self, bar: Bar); } +} +struct S; +impl foo::Foo for S { <|> }", + " +mod foo { + pub struct Bar; + trait Foo { fn foo(&self, bar: Bar); } +} +struct S; +impl foo::Foo for S { + <|>fn foo(&self, bar: foo::Bar) { unimplemented!() } +}", + ); + } + + #[test] + fn test_qualify_path_and_substitute_param() { + check_assist( + add_missing_impl_members, + " +mod foo { + pub struct Bar; + trait Foo { fn foo(&self, bar: Bar); } +} +struct S; +impl foo::Foo for S { <|> }", + " +mod foo { + pub struct Bar; + trait Foo { fn foo(&self, bar: Bar); } +} +struct S; +impl foo::Foo for S { + <|>fn foo(&self, bar: foo::Bar) { unimplemented!() } +}", + ); + } + + #[test] + fn test_qualify_path_associated_item() { + check_assist( + add_missing_impl_members, + " +mod foo { + pub struct Bar; + impl Bar { type Assoc = u32; } + trait Foo { fn foo(&self, bar: Bar::Assoc); } +} +struct S; +impl foo::Foo for S { <|> }", + " +mod foo { + pub struct Bar; + impl Bar { type Assoc = u32; } + trait Foo { fn foo(&self, bar: Bar::Assoc); } +} +struct S; +impl foo::Foo for S { + <|>fn foo(&self, bar: foo::Bar::Assoc) { unimplemented!() } +}", + ); + } + + #[test] + fn test_qualify_path_nested() { + check_assist( + add_missing_impl_members, + " +mod foo { + pub struct Bar; + pub struct Baz; + trait Foo { fn foo(&self, bar: Bar); } +} +struct S; +impl foo::Foo for S { <|> }", + " +mod foo { + pub struct Bar; + pub struct Baz; + trait Foo { fn foo(&self, bar: Bar); } +} +struct S; +impl foo::Foo for S { + <|>fn foo(&self, bar: foo::Bar) { unimplemented!() } +}", + ); + } + + #[test] + fn test_qualify_path_fn_trait_notation() { + check_assist( + add_missing_impl_members, + " +mod foo { + pub trait Fn { type Output; } + trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } +} +struct S; +impl foo::Foo for S { <|> }", + " +mod foo { + pub trait Fn { type Output; } + trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } +} +struct S; +impl foo::Foo for S { + <|>fn foo(&self, bar: dyn Fn(u32) -> i32) { unimplemented!() } +}", + ); + } + #[test] fn test_empty_trait() { check_assist_not_applicable( -- cgit v1.2.3