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 { + 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::>() ); } - 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