about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/lib.rs5
-rw-r--r--crates/ide/src/inlay_hints/discriminant.rs88
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs2
3 files changed, 49 insertions, 46 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 3e508747428..d78d8f1e489 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1075,6 +1075,10 @@ impl Enum {
         db.enum_data(self.id).variants.iter().map(|(id, _)| Variant { parent: self, id }).collect()
     }
 
+    pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
+        db.enum_data(self.id).repr
+    }
+
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         Type::from_def(db, self.id)
     }
@@ -1112,6 +1116,7 @@ impl Enum {
         )
     }
 
+    /// Returns true if at least one variant of this enum is a non-unit variant.
     pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool {
         self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
     }
diff --git a/crates/ide/src/inlay_hints/discriminant.rs b/crates/ide/src/inlay_hints/discriminant.rs
index 9bff98f6110..c4d2ac75cfa 100644
--- a/crates/ide/src/inlay_hints/discriminant.rs
+++ b/crates/ide/src/inlay_hints/discriminant.rs
@@ -20,21 +20,23 @@ pub(super) fn enum_hints(
     _: FileId,
     enum_: ast::Enum,
 ) -> Option<()> {
-    let enabled = match config.discriminant_hints {
-        DiscriminantHints::Always => true,
-        DiscriminantHints::Fieldless => {
-            !sema.to_def(&enum_)?.is_data_carrying(sema.db)
-                || enum_.variant_list()?.variants().any(|v| v.expr().is_some())
-        }
-        DiscriminantHints::Never => false,
-    };
-    if !enabled {
+    if let DiscriminantHints::Never = config.discriminant_hints {
+        return None;
+    }
+
+    let def = sema.to_def(&enum_)?;
+    let data_carrying = def.is_data_carrying(sema.db);
+    if matches!(config.discriminant_hints, DiscriminantHints::Fieldless) && data_carrying {
+        return None;
+    }
+    // data carrying enums without a primitive repr have no stable discriminants
+    if data_carrying && def.repr(sema.db).map_or(true, |r| r.int.is_none()) {
         return None;
     }
     for variant in enum_.variant_list()?.variants() {
         variant_hints(acc, sema, &variant);
     }
-    None
+    Some(())
 }
 
 fn variant_hints(
@@ -91,7 +93,6 @@ fn variant_hints(
 
     Some(())
 }
-
 #[cfg(test)]
 mod tests {
     use crate::inlay_hints::{
@@ -123,30 +124,30 @@ mod tests {
         check_discriminants(
             r#"
 enum Enum {
-  Variant,
-//^^^^^^^ = 0$
-  Variant1,
-//^^^^^^^^ = 1$
-  Variant2,
-//^^^^^^^^ = 2$
-  Variant5 = 5,
-  Variant6,
-//^^^^^^^^ = 6$
+    Variant,
+//  ^^^^^^^ = 0$
+    Variant1,
+//  ^^^^^^^^ = 1$
+    Variant2,
+//  ^^^^^^^^ = 2$
+    Variant5 = 5,
+    Variant6,
+//  ^^^^^^^^ = 6$
 }
 "#,
         );
         check_discriminants_fieldless(
             r#"
 enum Enum {
-  Variant,
-//^^^^^^^ = 0
-  Variant1,
-//^^^^^^^^ = 1
-  Variant2,
-//^^^^^^^^ = 2
-  Variant5 = 5,
-  Variant6,
-//^^^^^^^^ = 6
+    Variant,
+//  ^^^^^^^ = 0
+    Variant1,
+//  ^^^^^^^^ = 1
+    Variant2,
+//  ^^^^^^^^ = 2
+    Variant5 = 5,
+    Variant6,
+//  ^^^^^^^^ = 6
 }
 "#,
         );
@@ -156,26 +157,23 @@ enum Enum {
     fn datacarrying_mixed() {
         check_discriminants(
             r#"
+#[repr(u8)]
 enum Enum {
     Variant(),
-  //^^^^^^^^^ = 0
+//  ^^^^^^^^^ = 0
     Variant1,
-  //^^^^^^^^ = 1
+//  ^^^^^^^^ = 1
     Variant2 {},
-  //^^^^^^^^^^^ = 2
+//  ^^^^^^^^^^^ = 2
     Variant3,
-  //^^^^^^^^ = 3
+//  ^^^^^^^^ = 3
     Variant5 = 5,
     Variant6,
-  //^^^^^^^^ = 6
+//  ^^^^^^^^ = 6
 }
 "#,
         );
-    }
-
-    #[test]
-    fn datacarrying_mixed_fieldless_set() {
-        check_discriminants_fieldless(
+        check_discriminants(
             r#"
 enum Enum {
     Variant(),
@@ -187,20 +185,20 @@ enum Enum {
 }
 "#,
         );
+    }
+
+    #[test]
+    fn datacarrying_mixed_fieldless_set() {
         check_discriminants_fieldless(
             r#"
+#[repr(u8)]
 enum Enum {
     Variant(),
-  //^^^^^^^^^ = 0
     Variant1,
-  //^^^^^^^^ = 1
     Variant2 {},
-  //^^^^^^^^^^^ = 2
     Variant3,
-  //^^^^^^^^ = 3
-    Variant5 = 5,
+    Variant5,
     Variant6,
-  //^^^^^^^^ = 6
 }
 "#,
         );
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 1e0cb2ec2fb..9c198eefc75 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -102,7 +102,7 @@ pub(crate) fn handle_analyzer_status(
                 .collect::<Vec<&AbsPath>>()
         );
     }
-    format_to!(buf, "\nVfs memory usage: {}\n", snap.vfs_memory_usage());
+    format_to!(buf, "\nVfs memory usage: {}\n", profile::Bytes::new(snap.vfs_memory_usage() as _));
     buf.push_str("\nAnalysis:\n");
     buf.push_str(
         &snap