Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/references.rs')
-rw-r--r--crates/ide/src/references.rs230
1 files changed, 230 insertions, 0 deletions
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 55afcb59ba..43c04b20dd 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -2510,4 +2510,234 @@ fn main() {
"#]],
)
}
+
+ // The following are tests for short_associated_function_fast_search() in crates/ide-db/src/search.rs, because find all references
+ // use `FindUsages` and I found it easy to test it here.
+
+ #[test]
+ fn goto_ref_on_short_associated_function() {
+ check(
+ r#"
+struct Foo;
+impl Foo {
+ fn new$0() {}
+}
+
+fn bar() {
+ Foo::new();
+}
+fn baz() {
+ Foo::new;
+}
+ "#,
+ expect![[r#"
+ new Function FileId(0) 27..38 30..33
+
+ FileId(0) 62..65
+ FileId(0) 91..94
+ "#]],
+ );
+ }
+
+ #[test]
+ fn goto_ref_on_short_associated_function_with_aliases() {
+ check(
+ r#"
+//- /lib.rs
+mod a;
+mod b;
+
+struct Foo;
+impl Foo {
+ fn new$0() {}
+}
+
+fn bar() {
+ b::c::Baz::new();
+}
+
+//- /a.rs
+use crate::Foo as Bar;
+
+fn baz() { Bar::new(); }
+fn quux() { <super::b::Other as super::b::Trait>::Assoc::new(); }
+
+//- /b.rs
+pub(crate) mod c;
+
+pub(crate) struct Other;
+pub(crate) trait Trait {
+ type Assoc;
+}
+impl Trait for Other {
+ type Assoc = super::Foo;
+}
+
+//- /b/c.rs
+type Itself<T> = T;
+pub(in super::super) type Baz = Itself<crate::Foo>;
+ "#,
+ expect![[r#"
+ new Function FileId(0) 42..53 45..48
+
+ FileId(0) 83..86
+ FileId(1) 40..43
+ FileId(1) 106..109
+ "#]],
+ );
+ }
+
+ #[test]
+ fn goto_ref_on_short_associated_function_self_works() {
+ check(
+ r#"
+//- /lib.rs
+mod module;
+
+struct Foo;
+impl Foo {
+ fn new$0() {}
+ fn bar() { Self::new(); }
+}
+trait Trait {
+ type Assoc;
+ fn baz();
+}
+impl Trait for Foo {
+ type Assoc = Self;
+ fn baz() { Self::new(); }
+}
+
+//- /module.rs
+impl super::Foo {
+ fn quux() { Self::new(); }
+}
+fn foo() { <super::Foo as super::Trait>::Assoc::new(); }
+ "#,
+ expect![[r#"
+ new Function FileId(0) 40..51 43..46
+
+ FileId(0) 73..76
+ FileId(0) 195..198
+ FileId(1) 40..43
+ FileId(1) 99..102
+ "#]],
+ );
+ }
+
+ #[test]
+ fn goto_ref_on_short_associated_function_overlapping_self_ranges() {
+ check(
+ r#"
+struct Foo;
+impl Foo {
+ fn new$0() {}
+ fn bar() {
+ Self::new();
+ impl Foo {
+ fn baz() { Self::new(); }
+ }
+ }
+}
+ "#,
+ expect![[r#"
+ new Function FileId(0) 27..38 30..33
+
+ FileId(0) 68..71
+ FileId(0) 123..126
+ "#]],
+ );
+ }
+
+ #[test]
+ fn goto_ref_on_short_associated_function_no_direct_self_but_path_contains_self() {
+ check(
+ r#"
+struct Foo;
+impl Foo {
+ fn new$0() {}
+}
+trait Trait {
+ type Assoc;
+}
+impl<A, B> Trait for (A, B) {
+ type Assoc = B;
+}
+impl Foo {
+ fn bar() {
+ <((), Foo) as Trait>::Assoc::new();
+ <((), Self) as Trait>::Assoc::new();
+ }
+}
+ "#,
+ expect![[r#"
+ new Function FileId(0) 27..38 30..33
+
+ FileId(0) 188..191
+ FileId(0) 233..236
+ "#]],
+ );
+ }
+
+ // Checks that we can circumvent our fast path logic using complicated type level functions.
+ // This mainly exists as a documentation. I don't believe it is fixable.
+ // Usages search is not 100% accurate anyway; we miss macros.
+ #[test]
+ fn goto_ref_on_short_associated_function_complicated_type_magic_can_confuse_our_logic() {
+ check(
+ r#"
+struct Foo;
+impl Foo {
+ fn new$0() {}
+}
+
+struct ChoiceA;
+struct ChoiceB;
+trait Choice {
+ type Choose<A, B>;
+}
+impl Choice for ChoiceA {
+ type Choose<A, B> = A;
+}
+impl Choice for ChoiceB {
+ type Choose<A, B> = B;
+}
+type Choose<A, C> = <C as Choice>::Choose<A, Foo>;
+
+fn bar() {
+ Choose::<(), ChoiceB>::new();
+}
+ "#,
+ expect![[r#"
+ new Function FileId(0) 27..38 30..33
+
+ (no references)
+ "#]],
+ );
+ }
+
+ #[test]
+ fn goto_ref_on_short_associated_function_same_path_mention_alias_and_self() {
+ check(
+ r#"
+struct Foo;
+impl Foo {
+ fn new$0() {}
+}
+
+type IgnoreFirst<A, B> = B;
+
+impl Foo {
+ fn bar() {
+ <IgnoreFirst<Foo, Self>>::new();
+ }
+}
+ "#,
+ expect![[r#"
+ new Function FileId(0) 27..38 30..33
+
+ FileId(0) 131..134
+ "#]],
+ );
+ }
}