fix: Discriminant hints only render for datacarrying enums with primitive repr

This commit is contained in:
Lukas Wirth 2023-05-16 22:15:39 +02:00
parent 2f8cd66fb4
commit c12ede8c34
3 changed files with 49 additions and 46 deletions

View File

@ -1075,6 +1075,10 @@ impl Enum {
db.enum_data(self.id).variants.iter().map(|(id, _)| Variant { parent: self, id }).collect() 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 { pub fn ty(self, db: &dyn HirDatabase) -> Type {
Type::from_def(db, self.id) 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 { pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool {
self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit)) self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
} }

View File

@ -20,21 +20,23 @@ pub(super) fn enum_hints(
_: FileId, _: FileId,
enum_: ast::Enum, enum_: ast::Enum,
) -> Option<()> { ) -> Option<()> {
let enabled = match config.discriminant_hints { if let DiscriminantHints::Never = config.discriminant_hints {
DiscriminantHints::Always => true, return None;
DiscriminantHints::Fieldless => { }
!sema.to_def(&enum_)?.is_data_carrying(sema.db)
|| enum_.variant_list()?.variants().any(|v| v.expr().is_some()) let def = sema.to_def(&enum_)?;
} let data_carrying = def.is_data_carrying(sema.db);
DiscriminantHints::Never => false, if matches!(config.discriminant_hints, DiscriminantHints::Fieldless) && data_carrying {
}; return None;
if !enabled { }
// 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; return None;
} }
for variant in enum_.variant_list()?.variants() { for variant in enum_.variant_list()?.variants() {
variant_hints(acc, sema, &variant); variant_hints(acc, sema, &variant);
} }
None Some(())
} }
fn variant_hints( fn variant_hints(
@ -91,7 +93,6 @@ fn variant_hints(
Some(()) Some(())
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::inlay_hints::{ use crate::inlay_hints::{
@ -123,30 +124,30 @@ mod tests {
check_discriminants( check_discriminants(
r#" r#"
enum Enum { enum Enum {
Variant, Variant,
//^^^^^^^ = 0$ // ^^^^^^^ = 0$
Variant1, Variant1,
//^^^^^^^^ = 1$ // ^^^^^^^^ = 1$
Variant2, Variant2,
//^^^^^^^^ = 2$ // ^^^^^^^^ = 2$
Variant5 = 5, Variant5 = 5,
Variant6, Variant6,
//^^^^^^^^ = 6$ // ^^^^^^^^ = 6$
} }
"#, "#,
); );
check_discriminants_fieldless( check_discriminants_fieldless(
r#" r#"
enum Enum { enum Enum {
Variant, Variant,
//^^^^^^^ = 0 // ^^^^^^^ = 0
Variant1, Variant1,
//^^^^^^^^ = 1 // ^^^^^^^^ = 1
Variant2, Variant2,
//^^^^^^^^ = 2 // ^^^^^^^^ = 2
Variant5 = 5, Variant5 = 5,
Variant6, Variant6,
//^^^^^^^^ = 6 // ^^^^^^^^ = 6
} }
"#, "#,
); );
@ -156,26 +157,23 @@ enum Enum {
fn datacarrying_mixed() { fn datacarrying_mixed() {
check_discriminants( check_discriminants(
r#" r#"
#[repr(u8)]
enum Enum { enum Enum {
Variant(), Variant(),
//^^^^^^^^^ = 0 // ^^^^^^^^^ = 0
Variant1, Variant1,
//^^^^^^^^ = 1 // ^^^^^^^^ = 1
Variant2 {}, Variant2 {},
//^^^^^^^^^^^ = 2 // ^^^^^^^^^^^ = 2
Variant3, Variant3,
//^^^^^^^^ = 3 // ^^^^^^^^ = 3
Variant5 = 5, Variant5 = 5,
Variant6, Variant6,
//^^^^^^^^ = 6 // ^^^^^^^^ = 6
} }
"#, "#,
); );
} check_discriminants(
#[test]
fn datacarrying_mixed_fieldless_set() {
check_discriminants_fieldless(
r#" r#"
enum Enum { enum Enum {
Variant(), Variant(),
@ -187,20 +185,20 @@ enum Enum {
} }
"#, "#,
); );
}
#[test]
fn datacarrying_mixed_fieldless_set() {
check_discriminants_fieldless( check_discriminants_fieldless(
r#" r#"
#[repr(u8)]
enum Enum { enum Enum {
Variant(), Variant(),
//^^^^^^^^^ = 0
Variant1, Variant1,
//^^^^^^^^ = 1
Variant2 {}, Variant2 {},
//^^^^^^^^^^^ = 2
Variant3, Variant3,
//^^^^^^^^ = 3 Variant5,
Variant5 = 5,
Variant6, Variant6,
//^^^^^^^^ = 6
} }
"#, "#,
); );

View File

@ -102,7 +102,7 @@ pub(crate) fn handle_analyzer_status(
.collect::<Vec<&AbsPath>>() .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("\nAnalysis:\n");
buf.push_str( buf.push_str(
&snap &snap