---
Outer
- "#]],
+ "#]],
);
}
);
}
+#[test]
+fn hover_omits_unnamed_where_preds() {
+ check(
+ r#"
+pub fn foo(bar: impl T) { }
+
+fn main() { fo$0o(); }
+ "#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ pub fn foo(bar: impl T)
+ ```
+ "#]],
+ );
+ check(
+ r#"
+pub fn foo<V: AsRef<str>>(bar: impl T, baz: V) { }
+
+fn main() { fo$0o(); }
+ "#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ pub fn foo<V>(bar: impl T, baz: V)
+ where
+ V: AsRef<str>,
+ ```
+ "#]],
+ );
+}
+
#[test]
fn hover_shows_fn_signature_with_type_params() {
check(
check(
r#"const foo$0: u32 = 123;"#,
expect![[r#"
- *foo*
+ *foo*
- ```rust
- test
- ```
+ ```rust
+ test
+ ```
- ```rust
- const foo: u32
- ```
- "#]],
+ ```rust
+ const foo: u32 = 123 (0x7B)
+ ```
+ "#]],
+ );
+ check(
+ r#"
+const foo$0: u32 = {
+ let x = foo();
+ x + 100
+};"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const foo: u32 = {
+ let x = foo();
+ x + 100
+ }
+ ```
+ "#]],
);
+
check(
r#"static foo$0: u32 = 456;"#,
expect![[r#"
- *foo*
+ *foo*
- ```rust
- test
- ```
+ ```rust
+ test
+ ```
- ```rust
- static foo: u32
- ```
- "#]],
+ ```rust
+ static foo: u32 = 456
+ ```
+ "#]],
);
}
*zz*
```rust
- let zz: Test<i32, u8>
+ let zz: Test<i32>
```
"#]],
);
+ check_hover_range(
+ r#"
+struct Test<K, T = u8> { k: K, t: T }
+
+fn main() {
+ let $0zz$0 = Test { t: 23u8, k: 33 };
+}"#,
+ expect![[r#"
+ ```rust
+ Test<i32, u8>
+ ```"#]],
+ );
}
#[test]
check(
r#"
mod wrapper {
- struct Thing { x: u32 }
+ pub struct Thing { x: u32 }
impl Thing {
- fn new() -> Thing { Thing { x: 0 } }
+ pub fn new() -> Thing { Thing { x: 0 } }
}
}
```
```rust
- fn new() -> Thing
+ pub fn new() -> Thing
```
- "#]],
+ "#]],
)
}
}
"#,
expect![[r#"
- *C*
+ *C*
- ```rust
- test
- ```
+ ```rust
+ test
+ ```
- ```rust
- const C: u32
- ```
- "#]],
+ ```rust
+ const C: u32 = 1
+ ```
+ "#]],
)
}
fn test_hover_through_literal_string_in_macro() {
check(
r#"
-macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } }
+macro_rules! arr { ($($tt:tt)*) => { [$($tt)*] } }
fn foo() {
let mastered_for_itunes = "";
let _ = arr!("Tr$0acks", &mastered_for_itunes);
);
}
+#[test]
+fn test_hover_multiple_actions() {
+ check_actions(
+ r#"
+struct Bar;
+struct Foo { bar: Bar }
+
+fn foo(Foo { b$0ar }: &Foo) {}
+ "#,
+ expect![[r#"
+ [
+ GoToType(
+ [
+ HoverGotoTypeData {
+ mod_path: "test::Bar",
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 0..11,
+ focus_range: 7..10,
+ name: "Bar",
+ kind: Struct,
+ description: "struct Bar",
+ },
+ },
+ ],
+ ),
+ ]
+ "#]],
+ )
+}
+
#[test]
fn test_hover_through_literal_string_in_builtin_macro() {
check_hover_no_result(
);
}
+#[test]
+fn test_hover_function_show_types() {
+ check(
+ r#"fn foo$0(a: i32, b:i32) -> i32 { 0 }"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ fn foo(a: i32, b: i32) -> i32
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn test_hover_function_pointer_show_identifiers() {
+ check(
+ r#"type foo$0 = fn(a: i32, b: i32) -> i32;"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ type foo = fn(a: i32, b: i32) -> i32
+ ```
+ "#]],
+ );
+}
+
+#[test]
+fn test_hover_function_pointer_no_identifier() {
+ check(
+ r#"type foo$0 = fn(i32, _: i32) -> i32;"#,
+ expect![[r#"
+ *foo*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ type foo = fn(i32, i32) -> i32
+ ```
+ "#]],
+ );
+}
+
#[test]
fn test_hover_trait_show_qualifiers() {
check_actions(
fn foo_$0test() {}
"#,
expect![[r#"
- [
- Reference(
- FilePosition {
+ [
+ Reference(
+ FilePosition {
+ file_id: FileId(
+ 0,
+ ),
+ offset: 11,
+ },
+ ),
+ Runnable(
+ Runnable {
+ use_name_in_title: false,
+ nav: NavigationTarget {
file_id: FileId(
0,
),
- offset: 11,
+ full_range: 0..24,
+ focus_range: 11..19,
+ name: "foo_test",
+ kind: Function,
},
- ),
- Runnable(
- Runnable {
- use_name_in_title: false,
- nav: NavigationTarget {
- file_id: FileId(
- 0,
- ),
- full_range: 0..24,
- focus_range: 11..19,
- name: "foo_test",
- kind: Function,
- },
- kind: Test {
- test_id: Path(
- "foo_test",
- ),
- attr: TestAttr {
- ignore: false,
- },
+ kind: Test {
+ test_id: Path(
+ "foo_test",
+ ),
+ attr: TestAttr {
+ ignore: false,
},
- cfg: None,
},
- ),
- ]
- "#]],
+ cfg: None,
+ },
+ ),
+ ]
+ "#]],
);
}
fn test_hover_async_block_impl_trait_has_goto_type_action() {
check_actions(
r#"
-//- minicore: future
+//- /main.rs crate:main deps:core
+// we don't use minicore here so that this test doesn't randomly fail
+// when someone edits minicore
struct S;
fn foo() {
let fo$0o = async { S };
}
+//- /core.rs crate:core
+pub mod future {
+ #[lang = "future_trait"]
+ pub trait Future {}
+}
"#,
expect![[r#"
- [
- GoToType(
- [
- HoverGotoTypeData {
- mod_path: "core::future::Future",
- nav: NavigationTarget {
- file_id: FileId(
- 1,
- ),
- full_range: 254..436,
- focus_range: 293..299,
- name: "Future",
- kind: Trait,
- description: "pub trait Future",
- },
+ [
+ GoToType(
+ [
+ HoverGotoTypeData {
+ mod_path: "core::future::Future",
+ nav: NavigationTarget {
+ file_id: FileId(
+ 1,
+ ),
+ full_range: 21..69,
+ focus_range: 60..66,
+ name: "Future",
+ kind: Trait,
+ description: "pub trait Future",
},
- HoverGotoTypeData {
- mod_path: "test::S",
- nav: NavigationTarget {
- file_id: FileId(
- 0,
- ),
- full_range: 0..9,
- focus_range: 7..8,
- name: "S",
- kind: Struct,
- description: "struct S",
- },
+ },
+ HoverGotoTypeData {
+ mod_path: "main::S",
+ nav: NavigationTarget {
+ file_id: FileId(
+ 0,
+ ),
+ full_range: 0..110,
+ focus_range: 108..109,
+ name: "S",
+ kind: Struct,
+ description: "struct S",
},
- ],
- ),
- ]
- "#]],
+ },
+ ],
+ ),
+ ]
+ "#]],
);
}
}
"#,
expect![[r#"
- *f*
+ *f*
- ```rust
- f: &i32
- ```
- ---
+ ```rust
+ f: &i32
+ ```
+ ---
- ```rust
- test::S
- ```
+ ```rust
+ test::S
+ ```
- ```rust
- f: i32
- ```
- "#]],
+ ```rust
+ f: i32
+ ```
+ "#]],
);
}
);
}
+#[test]
+fn hover_const_eval() {
+ check(
+ r#"
+/// This is a doc
+const FOO$0: usize = !0 & !(!0 >> 1);
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: usize = 9223372036854775808 (0x8000000000000000)
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ check(
+ r#"
+/// This is a doc
+const FOO$0: usize = {
+ let a = 3 + 2;
+ let b = a * a;
+ b
+};
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: usize = 25 (0x19)
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ check(
+ r#"
+/// This is a doc
+const FOO$0: usize = 1 << 10;
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: usize = 1024 (0x400)
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ check(
+ r#"
+/// This is a doc
+const FOO$0: usize = {
+ let b = 4;
+ let a = { let b = 2; let a = b; a } + { let a = 1; a + b };
+ a
+};
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: usize = 7
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ check(
+ r#"
+/// This is a doc
+const FOO$0: usize = 2 - 3;
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: usize = 2 - 3
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ check(
+ r#"
+/// This is a doc
+const FOO$0: i32 = 2 - 3;
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: i32 = -1
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+ check(
+ r#"
+/// This is a doc
+const FOO$0: usize = 1 << 100;
+"#,
+ expect![[r#"
+ *FOO*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ const FOO: usize = 1 << 100
+ ```
+
+ ---
+
+ This is a doc
+ "#]],
+ );
+}
+
#[test]
fn hover_const_pat() {
check(
}
"#,
expect![[r#"
- *FOO*
+ *FOO*
- ```rust
- test
- ```
+ ```rust
+ test
+ ```
- ```rust
- const FOO: usize
- ```
+ ```rust
+ const FOO: usize = 3
+ ```
- ---
+ ---
- This is a doc
+ This is a doc
+ "#]],
+ );
+}
+
+#[test]
+fn array_repeat_exp() {
+ check(
+ r#"
+fn main() {
+ let til$0e4 = [0_u32; (4 * 8 * 8) / 32];
+}
+ "#,
+ expect![[r#"
+ *tile4*
+
+ ```rust
+ let tile4: [u32; 8]
+ ```
"#]],
);
}
);
}
+#[test]
+fn hover_keyword_as_primitive() {
+ check(
+ r#"
+//- /main.rs crate:main deps:std
+type F = f$0n(i32) -> i32;
+//- /libstd.rs crate:std
+/// Docs for prim_fn
+mod prim_fn {}
+"#,
+ expect![[r#"
+ *fn*
+
+ ```rust
+ fn
+ ```
+
+ ---
+
+ Docs for prim_fn
+ "#]],
+ );
+}
+
#[test]
fn hover_builtin() {
check(
#[test]
fn hover_attr_path_qualifier() {
- cov_mark::check!(name_ref_classify_attr_path_qualifier);
check(
r#"
//- /foo.rs crate:foo
fn hover_attribute_in_macro() {
check(
r#"
+//- minicore:derive
macro_rules! identity {
($struct:item) => {
$struct
fn hover_derive_input() {
check(
r#"
+//- minicore:derive
#[rustc_builtin_macro]
pub macro Copy {}
#[derive(Copy$0)]
);
check(
r#"
+//- minicore:derive
mod foo {
#[rustc_builtin_macro]
pub macro Copy {}
"#]],
);
}
+
+#[test]
+fn hover_inert_attr() {
+ check(
+ r#"
+#[doc$0 = ""]
+pub struct Foo;
+"#,
+ expect![[r##"
+ *doc*
+
+ ```rust
+ #[doc]
+ ```
+
+ ---
+
+ Valid forms are:
+
+ * \#\[doc(hidden|inline|...)\]
+ * \#\[doc = string\]
+ "##]],
+ );
+ check(
+ r#"
+#[allow$0()]
+pub struct Foo;
+"#,
+ expect![[r##"
+ *allow*
+
+ ```rust
+ #[allow]
+ ```
+
+ ---
+
+ Valid forms are:
+
+ * \#\[allow(lint1, lint2, ..., /\*opt\*/ reason = "...")\]
+ "##]],
+ );
+}