Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/hover/tests.rs')
| -rw-r--r-- | crates/ide/src/hover/tests.rs | 854 |
1 files changed, 694 insertions, 160 deletions
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 57bf0f9ad5..a2f9697758 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -2,14 +2,21 @@ use expect_test::{expect, Expect}; use ide_db::base_db::{FileLoader, FileRange}; use syntax::TextRange; -use crate::{fixture, HoverConfig, HoverDocFormat}; +use crate::{ + fixture, HoverConfig, HoverDocFormat, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, +}; const HOVER_BASE_CONFIG: HoverConfig = HoverConfig { links_in_hover: false, + memory_layout: Some(MemoryLayoutHoverConfig { + size: Some(MemoryLayoutHoverRenderKind::Both), + offset: Some(MemoryLayoutHoverRenderKind::Both), + alignment: Some(MemoryLayoutHoverRenderKind::Both), + niches: true, + }), documentation: true, format: HoverDocFormat::Markdown, keywords: true, - interpret_tests: false, }; fn check_hover_no_result(ra_fixture: &str) { @@ -58,6 +65,23 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) { expect.assert_eq(&actual) } +fn check_hover_no_memory_layout(ra_fixture: &str, expect: Expect) { + let (analysis, position) = fixture::position(ra_fixture); + let hover = analysis + .hover( + &HoverConfig { memory_layout: None, ..HOVER_BASE_CONFIG }, + FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) }, + ) + .unwrap() + .unwrap(); + + let content = analysis.db.file_text(position.file_id); + let hovered_element = &content[hover.range]; + + let actual = format!("*{hovered_element}*\n{}\n", hover.info.markup); + expect.assert_eq(&actual) +} + fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) { let (analysis, position) = fixture::position(ra_fixture); let hover = analysis @@ -97,6 +121,15 @@ fn check_hover_range(ra_fixture: &str, expect: Expect) { expect.assert_eq(hover.info.markup.as_str()) } +fn check_hover_range_actions(ra_fixture: &str, expect: Expect) { + let (analysis, range) = fixture::range(ra_fixture); + let hover = analysis + .hover(&HoverConfig { links_in_hover: true, ..HOVER_BASE_CONFIG }, range) + .unwrap() + .unwrap(); + expect.assert_debug_eq(&hover.info.actions); +} + fn check_hover_range_no_results(ra_fixture: &str) { let (analysis, range) = fixture::range(ra_fixture); let hover = analysis.hover(&HOVER_BASE_CONFIG, range).unwrap(); @@ -124,7 +157,7 @@ fn foo() { *local* ```rust - let local: i32 + let local: i32 // size = 4, align = 4 ``` "#]], ); @@ -199,6 +232,181 @@ fn main() { } #[test] +fn hover_closure() { + check( + r#" +//- minicore: copy +fn main() { + let x = 2; + let y = $0|z| x + z; +} +"#, + expect![[r#" + *|* + ```rust + {closure#0} // size = 8, align = 8, niches = 1 + impl Fn(i32) -> i32 + ``` + + ## Captures + * `x` by immutable borrow + "#]], + ); + + check( + r#" +//- minicore: copy +fn foo(x: impl Fn(i32) -> i32) { + +} +fn main() { + foo($0|x: i32| x) +} +"#, + expect![[r#" + *|* + ```rust + {closure#0} // size = 0, align = 1 + impl Fn(i32) -> i32 + ``` + + ## Captures + This closure captures nothing + "#]], + ); + + check( + r#" +//- minicore: copy + +struct Z { f: i32 } + +struct Y(&'static mut Z) + +struct X { + f1: Y, + f2: (Y, Y), +} + +fn main() { + let x: X; + let y = $0|| { + x.f1; + &mut x.f2.0 .0.f; + }; +} +"#, + expect![[r#" + *|* + ```rust + {closure#0} // size = 16 (0x10), align = 8, niches = 1 + impl FnOnce() + ``` + + ## Captures + * `x.f1` by move + * `(*x.f2.0.0).f` by mutable borrow + "#]], + ); + check( + r#" +//- minicore: copy, option + +fn do_char(c: char) {} + +fn main() { + let x = None; + let y = |$0| { + match x { + Some(c) => do_char(c), + None => x = None, + } + }; +} +"#, + expect![[r#" + *|* + ```rust + {closure#0} // size = 8, align = 8, niches = 1 + impl FnMut() + ``` + + ## Captures + * `x` by mutable borrow + "#]], + ); +} + +#[test] +fn hover_ranged_closure() { + check_hover_range( + r#" +//- minicore: fn +struct S; +struct S2; +fn main() { + let x = &S; + let y = ($0|| {x; S2}$0).call(); +} +"#, + expect![[r#" + ```rust + {closure#0} // size = 8, align = 8, niches = 1 + impl FnOnce() -> S2 + ``` + Coerced to: &impl FnOnce() -> S2 + + ## Captures + * `x` by move"#]], + ); + check_hover_range_actions( + r#" +//- minicore: fn +struct S; +struct S2; +fn main() { + let x = &S; + let y = ($0|| {x; S2}$0).call(); +} +"#, + expect![[r#" + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "test::S2", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 10..20, + focus_range: 17..19, + name: "S2", + kind: Struct, + description: "struct S2", + }, + }, + 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", + }, + }, + ], + ), + ] + "#]], + ); +} + +#[test] fn hover_shows_long_type_of_an_expression() { check( r#" @@ -222,12 +430,12 @@ fn main() { } "#, expect![[r#" - *iter* + *iter* - ```rust - let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>> - ``` - "#]], + ```rust + let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, impl Fn(&mut u32, &u32, &mut u32) -> Option<u32>, u32>> // size = 8, align = 4 + ``` + "#]], ); } @@ -604,12 +812,12 @@ fn main() { let zz$0 = Test { t: 23u8, k: 33 }; }"#, expect![[r#" - *zz* + *zz* - ```rust - let zz: Test<i32> - ``` - "#]], + ```rust + let zz: Test<i32> // size = 8, align = 4 + ``` + "#]], ); check_hover_range( r#" @@ -655,12 +863,12 @@ use Option::Some; fn main() { let b$0ar = Some(12); } "#, expect![[r#" - *bar* + *bar* - ```rust - let bar: Option<i32> - ``` - "#]], + ```rust + let bar: Option<i32> // size = 4, align = 4 + ``` + "#]], ); } @@ -724,12 +932,12 @@ fn hover_for_local_variable() { check( r#"fn func(foo: i32) { fo$0o; }"#, expect![[r#" - *foo* + *foo* - ```rust - foo: i32 - ``` - "#]], + ```rust + foo: i32 // size = 4, align = 4 + ``` + "#]], ) } @@ -738,12 +946,12 @@ fn hover_for_local_variable_pat() { check( r#"fn func(fo$0o: i32) {}"#, expect![[r#" - *foo* + *foo* - ```rust - foo: i32 - ``` - "#]], + ```rust + foo: i32 // size = 4, align = 4 + ``` + "#]], ) } @@ -752,12 +960,12 @@ fn hover_local_var_edge() { check( r#"fn func(foo: i32) { if true { $0foo; }; }"#, expect![[r#" - *foo* + *foo* - ```rust - foo: i32 - ``` - "#]], + ```rust + foo: i32 // size = 4, align = 4 + ``` + "#]], ) } @@ -766,12 +974,12 @@ fn hover_for_param_edge() { check( r#"fn func($0foo: i32) {}"#, expect![[r#" - *foo* + *foo* - ```rust - foo: i32 - ``` - "#]], + ```rust + foo: i32 // size = 4, align = 4 + ``` + "#]], ) } @@ -810,12 +1018,12 @@ impl Thing { fn main() { let foo_$0test = Thing::new(); } "#, expect![[r#" - *foo_test* + *foo_test* - ```rust - let foo_test: Thing - ``` - "#]], + ```rust + let foo_test: Thing // size = 4, align = 4 + ``` + "#]], ) } @@ -970,12 +1178,12 @@ fn y() { } "#, expect![[r#" - *x* + *x* - ```rust - let x: i32 - ``` - "#]], + ```rust + let x: i32 // size = 4, align = 4 + ``` + "#]], ) } @@ -1100,12 +1308,12 @@ macro_rules! id { ($($tt:tt)*) => { $($tt)* } } fn foo(bar:u32) { let a = id!(ba$0r); } "#, expect![[r#" - *bar* + *bar* - ```rust - bar: u32 - ``` - "#]], + ```rust + bar: u32 // size = 4, align = 4 + ``` + "#]], ); } @@ -1118,12 +1326,12 @@ macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } fn foo(bar:u32) { let a = id!(ba$0r); } "#, expect![[r#" - *bar* + *bar* - ```rust - bar: u32 - ``` - "#]], + ```rust + bar: u32 // size = 4, align = 4 + ``` + "#]], ); } @@ -1320,16 +1528,16 @@ fn test_hover_function_pointer_show_identifiers() { check( r#"type foo$0 = fn(a: i32, b: i32) -> i32;"#, expect![[r#" - *foo* + *foo* - ```rust - test - ``` + ```rust + test + ``` - ```rust - type foo = fn(a: i32, b: i32) -> i32 - ``` - "#]], + ```rust + type foo = fn(a: i32, b: i32) -> i32 // size = 8, align = 8, niches = 1 + ``` + "#]], ); } @@ -1338,16 +1546,16 @@ fn test_hover_function_pointer_no_identifier() { check( r#"type foo$0 = fn(i32, _: i32) -> i32;"#, expect![[r#" - *foo* + *foo* - ```rust - test - ``` + ```rust + test + ``` - ```rust - type foo = fn(i32, i32) -> i32 - ``` - "#]], + ```rust + type foo = fn(i32, i32) -> i32 // size = 8, align = 8, niches = 1 + ``` + "#]], ); } @@ -1668,6 +1876,86 @@ pub fn fo$0o() {} } #[test] +fn test_hover_layout_of_variant() { + check( + r#"enum Foo { + Va$0riant1(u8, u16), + Variant2(i32, u8, i64), + }"#, + expect![[r#" + *Variant1* + + ```rust + test::Foo + ``` + + ```rust + Variant1(u8, u16) // size = 4, align = 2 + ``` + "#]], + ); +} + +#[test] +fn test_hover_layout_of_enum() { + check( + r#"enum $0Foo { + Variant1(u8, u16), + Variant2(i32, u8, i64), + }"#, + expect![[r#" + *Foo* + + ```rust + test + ``` + + ```rust + enum Foo // size = 16 (0x10), align = 8, niches = 254 + ``` + "#]], + ); +} + +#[test] +fn test_hover_no_memory_layout() { + check_hover_no_memory_layout( + r#"struct Foo { fiel$0d_a: u8, field_b: i32, field_c: i16 }"#, + expect![[r#" + *field_a* + + ```rust + test::Foo + ``` + + ```rust + field_a: u8 + ``` + "#]], + ); + + check_hover_no_memory_layout( + r#" +//- minicore: copy +fn main() { + let x = 2; + let y = $0|z| x + z; +} +"#, + expect![[r#" + *|* + ```rust + {closure#0} + impl Fn(i32) -> i32 + ``` + + ## Captures + * `x` by immutable borrow + "#]], + ); +} + +#[test] fn test_hover_macro_generated_struct_fn_doc_comment() { cov_mark::check!(hover_macro_generated_struct_fn_doc_comment); @@ -2021,6 +2309,19 @@ fn main() { let s$0t = S{ f1:Arg(0) }; } } #[test] +fn test_hover_generic_excludes_sized_go_to_action() { + check_actions( + r#" +//- minicore: sized +struct S<T$0>(T); + "#, + expect![[r#" + [] + "#]], + ); +} + +#[test] fn test_hover_generic_struct_has_flattened_goto_type_actions() { check_actions( r#" @@ -2079,52 +2380,53 @@ mod M { fn main() { let s$0t = (A(1), B(2), M::C(3) ); } "#, expect![[r#" - [ - GoToType( - [ - HoverGotoTypeData { - mod_path: "test::A", - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 0..14, - focus_range: 7..8, - name: "A", - kind: Struct, - description: "struct A", - }, + [ + GoToType( + [ + HoverGotoTypeData { + mod_path: "test::A", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 0..14, + focus_range: 7..8, + name: "A", + kind: Struct, + description: "struct A", }, - HoverGotoTypeData { - mod_path: "test::B", - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 15..29, - focus_range: 22..23, - name: "B", - kind: Struct, - description: "struct B", - }, + }, + HoverGotoTypeData { + mod_path: "test::B", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 15..29, + focus_range: 22..23, + name: "B", + kind: Struct, + description: "struct B", }, - HoverGotoTypeData { - mod_path: "test::M::C", - nav: NavigationTarget { - file_id: FileId( - 0, - ), - full_range: 42..60, - focus_range: 53..54, - name: "C", - kind: Struct, - description: "pub struct C", - }, + }, + HoverGotoTypeData { + mod_path: "test::M::C", + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 42..60, + focus_range: 53..54, + name: "C", + kind: Struct, + container_name: "M", + description: "pub struct C", }, - ], - ), - ] - "#]], + }, + ], + ), + ] + "#]], ); } @@ -2453,6 +2755,7 @@ pub mod future { focus_range: 60..66, name: "Future", kind: Trait, + container_name: "future", description: "pub trait Future", }, }, @@ -2908,7 +3211,7 @@ fn main() { *f* ```rust - f: &i32 + f: &i32 // size = 8, align = 8, niches = 1 ``` --- @@ -2958,7 +3261,7 @@ fn main() { *value* ```rust - let value: Const<1> + let value: Const<1> // size = 0, align = 1 ``` "#]], ); @@ -2978,7 +3281,7 @@ fn main() { *value* ```rust - let value: Const<0> + let value: Const<0> // size = 0, align = 1 ``` "#]], ); @@ -2998,7 +3301,7 @@ fn main() { *value* ```rust - let value: Const<-1> + let value: Const<-1> // size = 0, align = 1 ``` "#]], ); @@ -3018,7 +3321,7 @@ fn main() { *value* ```rust - let value: Const<true> + let value: Const<true> // size = 0, align = 1 ``` "#]], ); @@ -3038,7 +3341,7 @@ fn main() { *value* ```rust - let value: Const<'🦀'> + let value: Const<'🦀'> // size = 0, align = 1 ``` "#]], ); @@ -3054,12 +3357,12 @@ impl Foo { } "#, expect![[r#" - *self* + *self* - ```rust - self: &Foo - ``` - "#]], + ```rust + self: &Foo // size = 8, align = 8, niches = 1 + ``` + "#]], ); } @@ -3074,12 +3377,12 @@ impl Foo { } "#, expect![[r#" - *self* + *self* - ```rust - self: Arc<Foo> - ``` - "#]], + ```rust + self: Arc<Foo> // size = 0, align = 1 + ``` + "#]], ); } @@ -3115,7 +3418,7 @@ mod Foo$0 { } #[test] -fn hover_doc_outer_inner_attribue() { +fn hover_doc_outer_inner_attribute() { check( r#" #[doc = "Be quick;"] @@ -3146,7 +3449,7 @@ mod Foo$0 { } #[test] -fn hover_doc_block_style_indentend() { +fn hover_doc_block_style_indent_end() { check( r#" /** @@ -3455,16 +3758,16 @@ struct Foo<const LEN: usize>; type Fo$0o2 = Foo<2>; "#, expect![[r#" - *Foo2* + *Foo2* - ```rust - test - ``` + ```rust + test + ``` - ```rust - type Foo2 = Foo<2> - ``` - "#]], + ```rust + type Foo2 = Foo<2> // size = 0, align = 1 + ``` + "#]], ); } @@ -3504,7 +3807,7 @@ enum E { ``` ```rust - A = 8 + A = 8 // size = 1, align = 1 ``` --- @@ -3529,7 +3832,7 @@ enum E { ``` ```rust - A = 12 (0xC) + A = 12 (0xC) // size = 1, align = 1 ``` --- @@ -3555,7 +3858,7 @@ enum E { ``` ```rust - B = 2 + B = 2 // size = 1, align = 1 ``` --- @@ -3581,7 +3884,7 @@ enum E { ``` ```rust - B = 5 + B = 5 // size = 1, align = 1 ``` --- @@ -4035,6 +4338,235 @@ const FOO$0: f64 = 1.0f64; } #[test] +fn hover_const_eval_floating_point() { + check( + r#" +extern "rust-intrinsic" { + pub fn expf64(x: f64) -> f64; +} + +const FOO$0: f64 = expf64(1.2); +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: f64 = 3.3201169227365472 + ``` + "#]], + ); +} + +#[test] +fn hover_const_eval_enum() { + check( + r#" +enum Enum { + V1, + V2, +} + +const VX: Enum = Enum::V1; + +const FOO$0: Enum = VX; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: Enum = V1 + ``` + "#]], + ); + check( + r#" +//- minicore: option +const FOO$0: Option<i32> = Some(2); +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: Option<i32> = Some(2) + ``` + "#]], + ); + check( + r#" +//- minicore: option +const FOO$0: Option<&i32> = Some(2).as_ref(); +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: Option<&i32> = Some(&2) + ``` + "#]], + ); +} + +#[test] +fn hover_const_eval_slice() { + check( + r#" +//- minicore: slice, index, coerce_unsized +const FOO$0: &[i32] = &[1, 2, 3 + 4]; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: &[i32] = &[1, 2, 7] + ``` + "#]], + ); + check( + r#" +//- minicore: slice, index, coerce_unsized +const FOO$0: &[i32; 5] = &[12; 5]; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: &[i32; 5] = &[12, 12, 12, 12, 12] + ``` + "#]], + ); + check( + r#" +//- minicore: slice, index, coerce_unsized + +const FOO$0: (&i32, &[i32], &i32) = { + let a: &[i32] = &[1, 2, 3]; + (&a[0], a, &a[0]) +} +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: (&i32, &[i32], &i32) = (&1, &[1, 2, 3], &1) + ``` + "#]], + ); + check( + r#" +//- minicore: slice, index, coerce_unsized + +struct Tree(&[Tree]); + +const FOO$0: Tree = { + let x = &[Tree(&[]), Tree(&[Tree(&[])])]; + Tree(&[Tree(x), Tree(x)]) +} +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: Tree = Tree(&[Tree(&[Tree(&[]), Tree(&[Tree(&[])])]), Tree(&[Tree(&[]), Tree(&[Tree(&[])])])]) + ``` + "#]], + ); +} + +#[test] +fn hover_const_eval_str() { + check( + r#" +const FOO$0: &str = "foo"; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: &str = "foo" + ``` + "#]], + ); + check( + r#" +struct X { + a: &'static str, + b: &'static str, +} +const FOO$0: X = X { + a: "axiom", + b: "buy N large", +}; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: X = X { a: "axiom", b: "buy N large" } + ``` + "#]], + ); + check( + r#" +const FOO$0: (&str, &str) = { + let x = "foo"; + (x, x) +}; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: (&str, &str) = ("foo", "foo") + ``` + "#]], + ); +} + +#[test] fn hover_const_eval_in_generic_trait() { // Doesn't compile, but we shouldn't crash. check( @@ -4115,7 +4647,7 @@ fn foo(e: E) { ``` ```rust - A = 3 + A = 3 // size = 0, align = 1 ``` --- @@ -4137,9 +4669,9 @@ fn main() { *tile4* ```rust - let tile4: [u32; 8] + let tile4: [u32; 8] // size = 32 (0x20), align = 4 ``` - "#]], + "#]], ); } @@ -4242,7 +4774,7 @@ fn foo() { /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads mod move_keyword {} "#, - expect - [closures](https://doc.rust-lang.org/nightly/book/ch13-01-closures.html) - [threads](https://doc.rust-lang.org/nightly/book/ch16-01-threads.html#using-move-closures-with-threads) + [closure](https://doc.rust-lang.org/stable/book/ch13-01-closures.html) + [closures](https://doc.rust-lang.org/stable/book/ch13-01-closures.html) + [threads](https://doc.rust-lang.org/stable/book/ch16-01-threads.html#using-move-closures-with-threads) <https://doc.rust-lang.org/nightly/book/ch13-01-closures.html> - "##]], + "#]], ); } @@ -4288,7 +4820,7 @@ fn hover_builtin() { check( r#" //- /main.rs crate:main deps:std -cosnt _: &str$0 = ""; } +const _: &str$0 = ""; } //- /libstd.rs crate:std /// Docs for prim_str @@ -5009,7 +5541,7 @@ fn foo() { fn hover_try_expr_res() { check_hover_range( r#" -//- minicore:result +//- minicore: try, from, result struct FooError; fn foo() -> Result<(), FooError> { @@ -5023,7 +5555,7 @@ fn foo() -> Result<(), FooError> { ); check_hover_range( r#" -//- minicore:result +//- minicore: try, from, result struct FooError; struct BarError; @@ -5044,6 +5576,7 @@ fn foo() -> Result<(), FooError> { fn hover_try_expr() { check_hover_range( r#" +//- minicore: try struct NotResult<T, U>(T, U); struct Short; struct Looooong; @@ -5061,6 +5594,7 @@ fn foo() -> NotResult<(), Looooong> { ); check_hover_range( r#" +//- minicore: try struct NotResult<T, U>(T, U); struct Short; struct Looooong; @@ -5092,7 +5626,7 @@ fn foo() -> Option<()> { "#, expect![[r#" ```rust - <Option<i32> as Try>::Output + i32 ```"#]], ); } @@ -5312,7 +5846,7 @@ enum Enum { ``` ```rust - RecordV { field: u32 } + RecordV { field: u32 } // size = 4, align = 4 ``` "#]], ); |