Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/tests/expression.rs')
-rw-r--r--crates/ide-completion/src/tests/expression.rs668
1 files changed, 668 insertions, 0 deletions
diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs
new file mode 100644
index 0000000000..5984149046
--- /dev/null
+++ b/crates/ide-completion/src/tests/expression.rs
@@ -0,0 +1,668 @@
+//! Completion tests for expressions.
+use expect_test::{expect, Expect};
+
+use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
+
+fn check(ra_fixture: &str, expect: Expect) {
+ let actual = completion_list(&format!("{}{}", BASE_ITEMS_FIXTURE, ra_fixture));
+ expect.assert_eq(&actual)
+}
+
+fn check_empty(ra_fixture: &str, expect: Expect) {
+ let actual = completion_list(ra_fixture);
+ expect.assert_eq(&actual);
+}
+
+#[test]
+fn complete_literal_struct_with_a_private_field() {
+ // `FooDesc.bar` is private, the completion should not be triggered.
+ check(
+ r#"
+mod _69latrick {
+ pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, bar: bool }
+ pub fn create_foo(foo_desc: &FooDesc) -> () { () }
+}
+
+fn baz() {
+ use _69latrick::*;
+
+ let foo = create_foo(&$0);
+}
+ "#,
+ // This should not contain `FooDesc {…}`.
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw mut
+ kw return
+ kw self
+ kw super
+ kw crate
+ st FooDesc
+ fn create_foo(…) fn(&FooDesc)
+ bt u32
+ tt Trait
+ en Enum
+ st Record
+ st Tuple
+ md module
+ fn baz() fn()
+ st Unit
+ md _69latrick
+ ma makro!(…) macro_rules! makro
+ fn function() fn()
+ sc STATIC
+ un Union
+ ev TupleV(…) TupleV(u32)
+ ct CONST
+ "#]],
+ )
+}
+
+#[test]
+fn completes_various_bindings() {
+ check_empty(
+ r#"
+fn func(param0 @ (param1, param2): (i32, i32)) {
+ let letlocal = 92;
+ if let ifletlocal = 100 {
+ match 0 {
+ matcharm => 1 + $0,
+ otherwise => (),
+ }
+ }
+ let letlocal2 = 44;
+}
+"#,
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ lc matcharm i32
+ lc ifletlocal i32
+ lc letlocal i32
+ lc param0 (i32, i32)
+ lc param1 i32
+ lc param2 i32
+ fn func(…) fn((i32, i32))
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn completes_all_the_things_in_fn_body() {
+ cov_mark::check!(unqualified_skip_lifetime_completion);
+ check(
+ r#"
+use non_existant::Unresolved;
+mod qualified { pub enum Enum { Variant } }
+
+impl Unit {
+ fn foo<'lifetime, TypeParam, const CONST_PARAM: usize>(self) {
+ fn local_func() {}
+ $0
+ }
+}
+"#,
+ // `self` is in here twice, once as the module, once as the local
+ expect![[r#"
+ me self.foo() fn(self)
+ kw unsafe
+ kw fn
+ kw const
+ kw type
+ kw impl
+ kw extern
+ kw use
+ kw trait
+ kw static
+ kw mod
+ kw enum
+ kw struct
+ kw union
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw let
+ kw return
+ sn pd
+ sn ppd
+ sn macro_rules
+ kw self
+ kw super
+ kw crate
+ fn local_func() fn()
+ bt u32
+ lc self Unit
+ tp TypeParam
+ cp CONST_PARAM
+ sp Self
+ tt Trait
+ en Enum
+ st Record
+ st Tuple
+ md module
+ st Unit
+ md qualified
+ ma makro!(…) macro_rules! makro
+ ?? Unresolved
+ fn function() fn()
+ sc STATIC
+ un Union
+ ev TupleV(…) TupleV(u32)
+ ct CONST
+ "#]],
+ );
+ check(
+ r#"
+use non_existant::Unresolved;
+mod qualified { pub enum Enum { Variant } }
+
+impl Unit {
+ fn foo<'lifetime, TypeParam, const CONST_PARAM: usize>(self) {
+ fn local_func() {}
+ self::$0
+ }
+}
+"#,
+ expect![[r#"
+ tt Trait
+ en Enum
+ st Record
+ st Tuple
+ md module
+ st Unit
+ md qualified
+ ma makro!(…) macro_rules! makro
+ ?? Unresolved
+ fn function() fn()
+ sc STATIC
+ un Union
+ ev TupleV(…) TupleV(u32)
+ ct CONST
+ "#]],
+ );
+}
+
+#[test]
+fn complete_in_block() {
+ check_empty(
+ r#"
+ fn foo() {
+ if true {
+ $0
+ }
+ }
+"#,
+ expect![[r#"
+ kw unsafe
+ kw fn
+ kw const
+ kw type
+ kw impl
+ kw extern
+ kw use
+ kw trait
+ kw static
+ kw mod
+ kw enum
+ kw struct
+ kw union
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw let
+ kw return
+ sn pd
+ sn ppd
+ sn macro_rules
+ kw self
+ kw super
+ kw crate
+ fn foo() fn()
+ bt u32
+ "#]],
+ )
+}
+
+#[test]
+fn complete_after_if_expr() {
+ check_empty(
+ r#"
+ fn foo() {
+ if true {}
+ $0
+ }
+"#,
+ expect![[r#"
+ kw unsafe
+ kw fn
+ kw const
+ kw type
+ kw impl
+ kw extern
+ kw use
+ kw trait
+ kw static
+ kw mod
+ kw enum
+ kw struct
+ kw union
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw let
+ kw else
+ kw else if
+ kw return
+ sn pd
+ sn ppd
+ sn macro_rules
+ kw self
+ kw super
+ kw crate
+ fn foo() fn()
+ bt u32
+ "#]],
+ )
+}
+
+#[test]
+fn complete_in_match_arm() {
+ check_empty(
+ r#"
+ fn foo() {
+ match () {
+ () => $0
+ }
+ }
+"#,
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ fn foo() fn()
+ bt u32
+ "#]],
+ )
+}
+
+#[test]
+fn completes_in_loop_ctx() {
+ check_empty(
+ r"fn my() { loop { $0 } }",
+ expect![[r#"
+ kw unsafe
+ kw fn
+ kw const
+ kw type
+ kw impl
+ kw extern
+ kw use
+ kw trait
+ kw static
+ kw mod
+ kw enum
+ kw struct
+ kw union
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw let
+ kw continue
+ kw break
+ kw return
+ sn pd
+ sn ppd
+ sn macro_rules
+ kw self
+ kw super
+ kw crate
+ fn my() fn()
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn completes_in_let_initializer() {
+ check_empty(
+ r#"fn main() { let _ = $0 }"#,
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ fn main() fn()
+ bt u32
+ "#]],
+ )
+}
+
+#[test]
+fn struct_initializer_field_expr() {
+ check_empty(
+ r#"
+struct Foo {
+ pub f: i32,
+}
+fn foo() {
+ Foo {
+ f: $0
+ }
+}
+"#,
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ st Foo
+ fn foo() fn()
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn shadowing_shows_single_completion() {
+ cov_mark::check!(shadowing_shows_single_completion);
+
+ check_empty(
+ r#"
+fn foo() {
+ let bar = 92;
+ {
+ let bar = 62;
+ drop($0)
+ }
+}
+"#,
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ lc bar i32
+ fn foo() fn()
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn in_macro_expr_frag() {
+ check_empty(
+ r#"
+macro_rules! m { ($e:expr) => { $e } }
+fn quux(x: i32) {
+ m!($0);
+}
+"#,
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ bt u32
+ lc x i32
+ fn quux(…) fn(i32)
+ ma m!(…) macro_rules! m
+ "#]],
+ );
+ check_empty(
+ r"
+macro_rules! m { ($e:expr) => { $e } }
+fn quux(x: i32) {
+ m!(x$0);
+}
+",
+ expect![[r#"
+ kw unsafe
+ kw match
+ kw while
+ kw while let
+ kw loop
+ kw if
+ kw if let
+ kw for
+ kw true
+ kw false
+ kw return
+ kw self
+ kw super
+ kw crate
+ bt u32
+ lc x i32
+ fn quux(…) fn(i32)
+ ma m!(…) macro_rules! m
+ "#]],
+ );
+ check_empty(
+ r#"
+macro_rules! m { ($e:expr) => { $e } }
+fn quux(x: i32) {
+ let y = 92;
+ m!(x$0
+}
+"#,
+ expect![[r#""#]],
+ );
+}
+
+#[test]
+fn enum_qualified() {
+ check(
+ r#"
+impl Enum {
+ type AssocType = ();
+ const ASSOC_CONST: () = ();
+ fn assoc_fn() {}
+}
+fn func() {
+ Enum::$0
+}
+"#,
+ expect![[r#"
+ ev TupleV(…) TupleV(u32)
+ ev RecordV {…} RecordV { field: u32 }
+ ev UnitV UnitV
+ ct ASSOC_CONST const ASSOC_CONST: ()
+ fn assoc_fn() fn()
+ ta AssocType type AssocType = ()
+ "#]],
+ );
+}
+
+#[test]
+fn ty_qualified_no_drop() {
+ check_empty(
+ r#"
+//- minicore: drop
+struct Foo;
+impl Drop for Foo {
+ fn drop(&mut self) {}
+}
+fn func() {
+ Foo::$0
+}
+"#,
+ expect![[r#""#]],
+ );
+}
+
+#[test]
+fn with_parens() {
+ check_empty(
+ r#"
+enum Enum {
+ Variant()
+}
+impl Enum {
+ fn variant() -> Self { Enum::Variant() }
+}
+fn func() {
+ Enum::$0()
+}
+"#,
+ expect![[r#"
+ ev Variant(…) Variant
+ fn variant fn() -> Enum
+ "#]],
+ );
+}
+
+#[test]
+fn detail_impl_trait_in_return_position() {
+ check_empty(
+ r"
+//- minicore: sized
+trait Trait<T> {}
+fn foo<U>() -> impl Trait<U> {}
+fn main() {
+ self::$0
+}
+",
+ expect![[r"
+ tt Trait
+ fn main() fn()
+ fn foo() fn() -> impl Trait<U>
+ "]],
+ );
+}
+
+#[test]
+fn detail_async_fn() {
+ check_empty(
+ r#"
+//- minicore: future, sized
+trait Trait<T> {}
+async fn foo() -> u8 {}
+async fn bar<U>() -> impl Trait<U> {}
+fn main() {
+ self::$0
+}
+"#,
+ expect![[r"
+ tt Trait
+ fn main() fn()
+ fn bar() async fn() -> impl Trait<U>
+ fn foo() async fn() -> u8
+ "]],
+ );
+}
+
+#[test]
+fn detail_impl_trait_in_argument_position() {
+ check_empty(
+ r"
+//- minicore: sized
+trait Trait<T> {}
+struct Foo;
+impl Foo {
+ fn bar<U>(_: impl Trait<U>) {}
+}
+fn main() {
+ Foo::$0
+}
+",
+ expect![[r"
+ fn bar(…) fn(impl Trait<U>)
+ "]],
+ );
+}