about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorroife <roifewu@gmail.com>2024-04-19 21:31:54 +0800
committerroife <roifewu@gmail.com>2024-04-19 21:45:56 +0800
commitc1a4ba55d7f17379fbbde480550174d7fe0ff04a (patch)
tree9d68b348a5df494eb7eadfb1fe4e98353af24076 /src/tools/rust-analyzer
parenta1136121b8d7cd5a6eb7f9a18e3b7f91ac9e1913 (diff)
fix: add a separate setting for enum variants
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs66
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs3
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs123
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs9
-rw-r--r--src/tools/rust-analyzer/docs/user/generated_config.adoc9
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json13
8 files changed, 183 insertions, 52 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index ec57708a084..42fafd4ee80 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -188,7 +188,7 @@ impl HirDisplay for Struct {
             StructKind::Record => {
                 let has_where_clause = write_where_clause(def_id, f)?;
                 if let Some(limit) = f.entity_limit {
-                    display_fields_or_variants(&self.fields(f.db), has_where_clause, limit, f)?;
+                    display_fields(&self.fields(f.db), has_where_clause, limit, f)?;
                 }
             }
             StructKind::Unit => _ = write_where_clause(def_id, f)?,
@@ -208,7 +208,7 @@ impl HirDisplay for Enum {
 
         let has_where_clause = write_where_clause(def_id, f)?;
         if let Some(limit) = f.entity_limit {
-            display_fields_or_variants(&self.variants(f.db), has_where_clause, limit, f)?;
+            display_variants(&self.variants(f.db), has_where_clause, limit, f)?;
         }
 
         Ok(())
@@ -225,35 +225,83 @@ impl HirDisplay for Union {
 
         let has_where_clause = write_where_clause(def_id, f)?;
         if let Some(limit) = f.entity_limit {
-            display_fields_or_variants(&self.fields(f.db), has_where_clause, limit, f)?;
+            display_fields(&self.fields(f.db), has_where_clause, limit, f)?;
         }
         Ok(())
     }
 }
 
-fn display_fields_or_variants<T: HirDisplay>(
-    fields_or_variants: &[T],
+fn display_fields(
+    fields: &[Field],
     has_where_clause: bool,
     limit: usize,
     f: &mut HirFormatter<'_>,
 ) -> Result<(), HirDisplayError> {
-    let count = fields_or_variants.len().min(limit);
+    let count = fields.len().min(limit);
     f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
     if count == 0 {
-        if fields_or_variants.is_empty() {
+        if fields.is_empty() {
             f.write_str("{}")?;
         } else {
             f.write_str("{ /* … */ }")?;
         }
     } else {
         f.write_str("{\n")?;
-        for field in &fields_or_variants[..count] {
+        for field in &fields[..count] {
             f.write_str("    ")?;
             field.hir_fmt(f)?;
             f.write_str(",\n")?;
         }
 
-        if fields_or_variants.len() > count {
+        if fields.len() > count {
+            f.write_str("    /* … */\n")?;
+        }
+        f.write_str("}")?;
+    }
+
+    Ok(())
+}
+
+fn display_variants(
+    variants: &[Variant],
+    has_where_clause: bool,
+    limit: usize,
+    f: &mut HirFormatter<'_>,
+) -> Result<(), HirDisplayError> {
+    let count = variants.len().min(limit);
+    f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
+    if count == 0 {
+        if variants.is_empty() {
+            f.write_str("{}")?;
+        } else {
+            f.write_str("{ /* … */ }")?;
+        }
+    } else {
+        f.write_str("{\n")?;
+        for variant in &variants[..count] {
+            f.write_str("    ")?;
+            write!(f, "{}", variant.name(f.db).display(f.db.upcast()))?;
+            match variant.kind(f.db) {
+                StructKind::Tuple => {
+                    if variant.fields(f.db).is_empty() {
+                        f.write_str("()")?;
+                    } else {
+                        f.write_str("( /* … */ )")?;
+                    }
+                }
+                StructKind::Record => {
+                    if variant.fields(f.db).is_empty() {
+                        f.write_str(" {}")?;
+                    } else {
+                        f.write_str(" { /* … */ }")?;
+                    }
+                }
+                StructKind::Unit => {}
+            }
+            f.write_str(",\n")?;
+        }
+
+        if variants.len() > count {
             f.write_str("    /* … */\n")?;
         }
         f.write_str("}")?;
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 2a2be6e4e0c..6958ae16230 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -33,7 +33,8 @@ pub struct HoverConfig {
     pub keywords: bool,
     pub format: HoverDocFormat,
     pub max_trait_assoc_items_count: Option<usize>,
-    pub max_adt_fields_or_variants_count: Option<usize>,
+    pub max_struct_or_union_fields_count: Option<usize>,
+    pub max_enum_variants_count: Option<usize>,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index e0a9907a413..1044a3f4c11 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -410,14 +410,17 @@ pub(super) fn definition(
         Definition::Trait(trait_) => {
             trait_.display_limited(db, config.max_trait_assoc_items_count).to_string()
         }
-        Definition::Adt(adt) => {
-            adt.display_limited(db, config.max_adt_fields_or_variants_count).to_string()
+        Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => {
+            adt.display_limited(db, config.max_struct_or_union_fields_count).to_string()
+        }
+        Definition::Adt(adt @ Adt::Enum(_)) => {
+            adt.display_limited(db, config.max_enum_variants_count).to_string()
         }
         Definition::SelfType(impl_def) => {
             let self_ty = &impl_def.self_ty(db);
             match self_ty.as_adt() {
                 Some(adt) => {
-                    adt.display_limited(db, config.max_adt_fields_or_variants_count).to_string()
+                    adt.display_limited(db, config.max_struct_or_union_fields_count).to_string()
                 }
                 None => self_ty.display(db).to_string(),
             }
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 326c248b7a2..f17a0fa2cd9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -18,7 +18,8 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig {
     format: HoverDocFormat::Markdown,
     keywords: true,
     max_trait_assoc_items_count: None,
-    max_adt_fields_or_variants_count: Some(5),
+    max_struct_or_union_fields_count: Some(5),
+    max_enum_variants_count: Some(5),
 };
 
 fn check_hover_no_result(ra_fixture: &str) {
@@ -51,8 +52,8 @@ fn check(ra_fixture: &str, expect: Expect) {
 }
 
 #[track_caller]
-fn check_hover_adt_fields_or_variants_limit(
-    count: Option<usize>,
+fn check_hover_struct_or_union_fields_limit(
+    fields_count: impl Into<Option<usize>>,
     ra_fixture: &str,
     expect: Expect,
 ) {
@@ -61,7 +62,33 @@ fn check_hover_adt_fields_or_variants_limit(
         .hover(
             &HoverConfig {
                 links_in_hover: true,
-                max_adt_fields_or_variants_count: count,
+                max_struct_or_union_fields_count: fields_count.into(),
+                ..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)
+}
+
+#[track_caller]
+fn check_hover_enum_variants_limit(
+    variants_count: impl Into<Option<usize>>,
+    ra_fixture: &str,
+    expect: Expect,
+) {
+    let (analysis, position) = fixture::position(ra_fixture);
+    let hover = analysis
+        .hover(
+            &HoverConfig {
+                links_in_hover: true,
+                max_enum_variants_count: variants_count.into(),
                 ..HOVER_BASE_CONFIG
             },
             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
@@ -912,8 +939,8 @@ struct Foo$0 where u32: Copy { field: u32 }
 
 #[test]
 fn hover_record_struct_limit() {
-    check_hover_adt_fields_or_variants_limit(
-        Some(3),
+    check_hover_struct_or_union_fields_limit(
+        3,
         r#"
     struct Foo$0 { a: u32, b: i32, c: i32 }
     "#,
@@ -934,8 +961,8 @@ fn hover_record_struct_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(3),
+    check_hover_struct_or_union_fields_limit(
+        3,
         r#"
     struct Foo$0 { a: u32 }
     "#,
@@ -954,8 +981,8 @@ fn hover_record_struct_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(3),
+    check_hover_struct_or_union_fields_limit(
+        3,
         r#"
     struct Foo$0 { a: u32, b: i32, c: i32, d: u32 }
     "#,
@@ -977,7 +1004,7 @@ fn hover_record_struct_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
+    check_hover_struct_or_union_fields_limit(
         None,
         r#"
     struct Foo$0 { a: u32, b: i32, c: i32 }
@@ -995,8 +1022,8 @@ fn hover_record_struct_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(0),
+    check_hover_struct_or_union_fields_limit(
+        0,
         r#"
     struct Foo$0 { a: u32, b: i32, c: i32 }
     "#,
@@ -1017,8 +1044,8 @@ fn hover_record_struct_limit() {
 
 #[test]
 fn hover_enum_limit() {
-    check_hover_adt_fields_or_variants_limit(
-        Some(5),
+    check_hover_enum_variants_limit(
+        5,
         r#"enum Foo$0 { A, B }"#,
         expect![[r#"
             *Foo*
@@ -1036,8 +1063,8 @@ fn hover_enum_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(1),
+    check_hover_enum_variants_limit(
+        1,
         r#"enum Foo$0 { A, B }"#,
         expect![[r#"
             *Foo*
@@ -1055,8 +1082,8 @@ fn hover_enum_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(0),
+    check_hover_enum_variants_limit(
+        0,
         r#"enum Foo$0 { A, B }"#,
         expect![[r#"
             *Foo*
@@ -1071,7 +1098,7 @@ fn hover_enum_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
+    check_hover_enum_variants_limit(
         None,
         r#"enum Foo$0 { A, B }"#,
         expect![[r#"
@@ -1087,12 +1114,46 @@ fn hover_enum_limit() {
             ```
         "#]],
     );
+    check_hover_enum_variants_limit(
+        7,
+        r#"enum Enum$0 {
+               Variant {},
+               Variant2 { field: i32 },
+               Variant3 { field: i32, field2: i32 },
+               Variant4(),
+               Variant5(i32),
+               Variant6(i32, i32),
+               Variant7,
+               Variant8,
+           }"#,
+        expect![[r#"
+            *Enum*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            // size = 12 (0xC), align = 4, niches = 4294967288
+            enum Enum {
+                Variant {},
+                Variant2 { /* … */ },
+                Variant3 { /* … */ },
+                Variant4(),
+                Variant5( /* … */ ),
+                Variant6( /* … */ ),
+                Variant7,
+                /* … */
+            }
+            ```
+        "#]],
+    );
 }
 
 #[test]
 fn hover_union_limit() {
-    check_hover_adt_fields_or_variants_limit(
-        Some(5),
+    check_hover_struct_or_union_fields_limit(
+        5,
         r#"union Foo$0 { a: u32, b: i32 }"#,
         expect![[r#"
             *Foo*
@@ -1110,8 +1171,8 @@ fn hover_union_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(1),
+    check_hover_struct_or_union_fields_limit(
+        1,
         r#"union Foo$0 { a: u32, b: i32 }"#,
         expect![[r#"
             *Foo*
@@ -1129,8 +1190,8 @@ fn hover_union_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
-        Some(0),
+    check_hover_struct_or_union_fields_limit(
+        0,
         r#"union Foo$0 { a: u32, b: i32 }"#,
         expect![[r#"
             *Foo*
@@ -1145,7 +1206,7 @@ fn hover_union_limit() {
             ```
         "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
+    check_hover_struct_or_union_fields_limit(
         None,
         r#"union Foo$0 { a: u32, b: i32 }"#,
         expect![[r#"
@@ -1630,12 +1691,12 @@ impl Thing {
                 ```
             "#]],
     );
-    check_hover_adt_fields_or_variants_limit(
+    check_hover_struct_or_union_fields_limit(
         None,
         r#"
 struct Thing { x: u32 }
 impl Thing {
-    fn new() -> Self { Self$0 { x: 0 } }
+    fn new() -> Self$0 { Self { x: 0 } }
 }
 "#,
         expect![[r#"
@@ -2599,8 +2660,8 @@ fn test_hover_layout_of_enum() {
             ```rust
             // size = 16 (0x10), align = 8, niches = 254
             enum Foo {
-                Variant1(u8, u16),
-                Variant2(i32, u8, i64),
+                Variant1( /* … */ ),
+                Variant2( /* … */ ),
             }
             ```
         "#]],
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index 1378ab2ab0f..c5623062af4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -167,7 +167,8 @@ impl StaticIndex<'_> {
             keywords: true,
             format: crate::HoverDocFormat::Markdown,
             max_trait_assoc_items_count: None,
-            max_adt_fields_or_variants_count: Some(5),
+            max_struct_or_union_fields_count: Some(5),
+            max_enum_variants_count: Some(5),
         };
         let tokens = tokens.filter(|token| {
             matches!(
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 10bc19b9887..910ee70ca8c 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -312,8 +312,10 @@ config_data! {
         /// How to render the size information in a memory layout hover.
         hover_memoryLayout_size: Option<MemoryLayoutHoverRenderKindDef> = Some(MemoryLayoutHoverRenderKindDef::Both),
 
-        /// How many fields or variants of an ADT (struct, enum or union) to display when hovering on. Show none if empty.
-        hover_show_adtFieldsOrVariants: Option<usize> = Some(5),
+        /// How many variants of an enum to display when hovering on. Show none if empty.
+        hover_show_enumVariants: Option<usize> = Some(5),
+        /// How many fields of a struct or union to display when hovering on. Show none if empty.
+        hover_show_structOrUnionFields: Option<usize> = Some(5),
         /// How many associated items of a trait to display when hovering a trait.
         hover_show_traitAssocItems: Option<usize> = None,
 
@@ -1112,7 +1114,8 @@ impl Config {
             },
             keywords: self.hover_documentation_keywords_enable().to_owned(),
             max_trait_assoc_items_count: self.hover_show_traitAssocItems().to_owned(),
-            max_adt_fields_or_variants_count: self.hover_show_adtFieldsOrVariants().to_owned(),
+            max_struct_or_union_fields_count: self.hover_show_structOrUnionFields().to_owned(),
+            max_enum_variants_count: self.hover_show_enumVariants().to_owned(),
         }
     }
 
diff --git a/src/tools/rust-analyzer/docs/user/generated_config.adoc b/src/tools/rust-analyzer/docs/user/generated_config.adoc
index d275b51abc3..acc10cdb8fb 100644
--- a/src/tools/rust-analyzer/docs/user/generated_config.adoc
+++ b/src/tools/rust-analyzer/docs/user/generated_config.adoc
@@ -533,10 +533,15 @@ How to render the offset information in a memory layout hover.
 --
 How to render the size information in a memory layout hover.
 --
-[[rust-analyzer.hover.show.adtFieldsOrVariants]]rust-analyzer.hover.show.adtFieldsOrVariants (default: `5`)::
+[[rust-analyzer.hover.show.enumVariants]]rust-analyzer.hover.show.enumVariants (default: `5`)::
 +
 --
-How many fields or variants of an ADT (struct, enum or union) to display when hovering on. Show none if empty.
+How many variants of an enum to display when hovering on. Show none if empty.
+--
+[[rust-analyzer.hover.show.structOrUnionFields]]rust-analyzer.hover.show.structOrUnionFields (default: `5`)::
++
+--
+How many fields of a struct or union to display when hovering on. Show none if empty.
 --
 [[rust-analyzer.hover.show.traitAssocItems]]rust-analyzer.hover.show.traitAssocItems (default: `null`)::
 +
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 88a382f1fb8..ffbceb8ad4f 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -1152,8 +1152,17 @@
                         }
                     ]
                 },
-                "rust-analyzer.hover.show.adtFieldsOrVariants": {
-                    "markdownDescription": "How many fields or variants of an ADT (struct, enum or union) to display when hovering on. Show none if empty.",
+                "rust-analyzer.hover.show.enumVariants": {
+                    "markdownDescription": "How many variants of an enum to display when hovering on. Show none if empty.",
+                    "default": 5,
+                    "type": [
+                        "null",
+                        "integer"
+                    ],
+                    "minimum": 0
+                },
+                "rust-analyzer.hover.show.structOrUnionFields": {
+                    "markdownDescription": "How many fields of a struct or union to display when hovering on. Show none if empty.",
                     "default": 5,
                     "type": [
                         "null",