diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 9fabc6bc4f9..9ec3f7f29ab 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -24,12 +24,14 @@ mod chaining;
 mod param_name;
 mod binding_mode;
 mod bind_pat;
+mod discrimant;
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct InlayHintsConfig {
     pub location_links: bool,
     pub render_colons: bool,
     pub type_hints: bool,
+    pub discriminant_hints: DiscriminantHints,
     pub parameter_hints: bool,
     pub chaining_hints: bool,
     pub adjustment_hints: AdjustmentHints,
@@ -51,6 +53,13 @@ pub enum ClosureReturnTypeHints {
     Never,
 }
 
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum DiscriminantHints {
+    Always,
+    Never,
+    Fieldless,
+}
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum LifetimeElisionHints {
     Always,
@@ -76,6 +85,7 @@ pub enum InlayKind {
     LifetimeHint,
     ParameterHint,
     TypeHint,
+    DiscriminantHint,
     OpeningParenthesis,
     ClosingParenthesis,
 }
@@ -365,6 +375,9 @@ fn hints(
                 ast::Item::Const(it) => implicit_static::hints(hints, config, Either::Right(it)),
                 _ => None,
             },
+            ast::Variant(v) => {
+                discrimant::hints(hints, famous_defs, config, file_id, &v)
+            },
             // FIXME: fn-ptr type, dyn fn type, and trait object type elisions
             ast::Type(_) => None,
             _ => None,
@@ -418,12 +431,14 @@ mod tests {
     use test_utils::extract_annotations;
 
     use crate::inlay_hints::AdjustmentHints;
+    use crate::DiscriminantHints;
     use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
 
     use super::ClosureReturnTypeHints;
 
     pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
         location_links: false,
+        discriminant_hints: DiscriminantHints::Never,
         render_colons: false,
         type_hints: false,
         parameter_hints: false,
diff --git a/crates/ide/src/inlay_hints/discrimant.rs b/crates/ide/src/inlay_hints/discrimant.rs
new file mode 100644
index 00000000000..f32c4bdf288
--- /dev/null
+++ b/crates/ide/src/inlay_hints/discrimant.rs
@@ -0,0 +1,142 @@
+//! Implementation of "enum variant discriminant" inlay hints:
+//! ```no_run
+//! enum Foo {
+//!    Bar/* = 0*/,
+//! }
+//! ```
+use ide_db::{base_db::FileId, famous_defs::FamousDefs};
+use syntax::ast::{self, AstNode, HasName};
+
+use crate::{DiscriminantHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
+
+pub(super) fn hints(
+    acc: &mut Vec<InlayHint>,
+    FamousDefs(sema, _): &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    _: FileId,
+    variant: &ast::Variant,
+) -> Option<()> {
+    let field_list = match config.discriminant_hints {
+        DiscriminantHints::Always => variant.field_list(),
+        DiscriminantHints::Fieldless => match variant.field_list() {
+            Some(_) => return None,
+            None => None,
+        },
+        DiscriminantHints::Never => return None,
+    };
+
+    if variant.eq_token().is_some() {
+        return None;
+    }
+
+    let name = variant.name()?;
+
+    let descended = sema.descend_node_into_attributes(variant.clone()).pop();
+    let desc_pat = descended.as_ref().unwrap_or(variant);
+    let v = sema.to_def(desc_pat)?;
+    let d = v.eval(sema.db);
+
+    acc.push(InlayHint {
+        range: match field_list {
+            Some(field_list) => name.syntax().text_range().cover(field_list.syntax().text_range()),
+            None => name.syntax().text_range(),
+        },
+        kind: InlayKind::DiscriminantHint,
+        label: match &d {
+            Ok(v) => format!("{}", v).into(),
+            Err(_) => "?".into(),
+        },
+        tooltip: Some(InlayTooltip::String(match &d {
+            Ok(_) => "enum variant discriminant".into(),
+            Err(e) => format!("{e:?}").into(),
+        })),
+    });
+
+    Some(())
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::inlay_hints::{
+        tests::{check_with_config, DISABLED_CONFIG},
+        DiscriminantHints, InlayHintsConfig,
+    };
+
+    #[track_caller]
+    fn check_discriminants(ra_fixture: &str) {
+        check_with_config(
+            InlayHintsConfig { discriminant_hints: DiscriminantHints::Always, ..DISABLED_CONFIG },
+            ra_fixture,
+        );
+    }
+
+    #[track_caller]
+    fn check_discriminants_fieldless(ra_fixture: &str) {
+        check_with_config(
+            InlayHintsConfig {
+                discriminant_hints: DiscriminantHints::Fieldless,
+                ..DISABLED_CONFIG
+            },
+            ra_fixture,
+        );
+    }
+
+    #[test]
+    fn fieldless() {
+        check_discriminants(
+            r#"
+enum Enum {
+    Variant,
+  //^^^^^^^0
+    Variant1,
+  //^^^^^^^^1
+    Variant2,
+  //^^^^^^^^2
+    Variant5 = 5,
+    Variant6,
+  //^^^^^^^^6
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn datacarrying_mixed() {
+        check_discriminants(
+            r#"
+enum Enum {
+    Variant(),
+  //^^^^^^^^^0
+    Variant1,
+  //^^^^^^^^1
+    Variant2 {},
+  //^^^^^^^^^^^2
+    Variant3,
+  //^^^^^^^^3
+    Variant5 = 5,
+    Variant6,
+  //^^^^^^^^6
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn datacarrying_mixed_fieldless_set() {
+        check_discriminants_fieldless(
+            r#"
+enum Enum {
+    Variant(),
+    Variant1,
+  //^^^^^^^^1
+    Variant2 {},
+    Variant3,
+  //^^^^^^^^3
+    Variant5 = 5,
+    Variant6,
+  //^^^^^^^^6
+}
+"#,
+        );
+    }
+}
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 6698bf766a0..200958a4330 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -81,8 +81,8 @@ pub use crate::{
     highlight_related::{HighlightRelatedConfig, HighlightedRange},
     hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
     inlay_hints::{
-        AdjustmentHints, ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig,
-        InlayKind, InlayTooltip, LifetimeElisionHints,
+        AdjustmentHints, ClosureReturnTypeHints, DiscriminantHints, InlayHint, InlayHintLabel,
+        InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
     },
     join_lines::JoinLinesConfig,
     markup::Markup,
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index b6a58f5ef59..6e31a1420ea 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -108,6 +108,7 @@ impl StaticIndex<'_> {
                 &InlayHintsConfig {
                     location_links: true,
                     render_colons: true,
+                    discriminant_hints: crate::DiscriminantHints::Fieldless,
                     type_hints: true,
                     parameter_hints: true,
                     chaining_hints: true,
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index ac496a7a9f9..dc876720de4 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -327,6 +327,8 @@ config_data! {
         inlayHints_closingBraceHints_minLines: usize               = "25",
         /// Whether to show inlay type hints for return types of closures.
         inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef  = "\"never\"",
+        /// Whether to show enum variant discriminant hints.
+        inlayHints_discriminantHints_enable: DiscriminantHintsDef            = "\"never\"",
         /// Whether to show inlay hints for type adjustments.
         inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = "\"never\"",
         /// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
@@ -1218,6 +1220,11 @@ impl Config {
             type_hints: self.data.inlayHints_typeHints_enable,
             parameter_hints: self.data.inlayHints_parameterHints_enable,
             chaining_hints: self.data.inlayHints_chainingHints_enable,
+            discriminant_hints: match self.data.inlayHints_discriminantHints_enable {
+                DiscriminantHintsDef::Always => ide::DiscriminantHints::Always,
+                DiscriminantHintsDef::Never => ide::DiscriminantHints::Never,
+                DiscriminantHintsDef::Fieldless => ide::DiscriminantHints::Fieldless,
+            },
             closure_return_type_hints: match self.data.inlayHints_closureReturnTypeHints_enable {
                 ClosureReturnTypeHintsDef::Always => ide::ClosureReturnTypeHints::Always,
                 ClosureReturnTypeHintsDef::Never => ide::ClosureReturnTypeHints::Never,
@@ -1579,6 +1586,7 @@ mod de_unit_v {
     named_unit_variant!(skip_trivial);
     named_unit_variant!(mutable);
     named_unit_variant!(reborrow);
+    named_unit_variant!(fieldless);
     named_unit_variant!(with_block);
 }
 
@@ -1742,6 +1750,17 @@ enum AdjustmentHintsDef {
     Reborrow,
 }
 
+#[derive(Deserialize, Debug, Clone)]
+#[serde(untagged)]
+enum DiscriminantHintsDef {
+    #[serde(deserialize_with = "true_or_always")]
+    Always,
+    #[serde(deserialize_with = "false_or_never")]
+    Never,
+    #[serde(deserialize_with = "de_unit_v::fieldless")]
+    Fieldless,
+}
+
 #[derive(Deserialize, Debug, Clone)]
 #[serde(rename_all = "snake_case")]
 enum FilesWatcherDef {
@@ -2064,6 +2083,19 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
                 "Only show auto borrow and dereference adjustment hints."
             ]
         },
+        "DiscriminantHintsDef" => set! {
+            "type": "string",
+            "enum": [
+                "always",
+                "never",
+                "fieldless"
+            ],
+            "enumDescriptions": [
+                "Always show all discriminant hints.",
+                "Never show discriminant hints.",
+                "Only show discriminant hints on fieldless enum variants."
+            ]
+        },
         "CargoFeaturesDef" => set! {
             "anyOf": [
                 {
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 35ced15de54..6773fc40e16 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -434,6 +434,7 @@ pub(crate) fn inlay_hint(
         InlayKind::ParameterHint if render_colons => inlay_hint.label.append_str(":"),
         InlayKind::TypeHint if render_colons => inlay_hint.label.prepend_str(": "),
         InlayKind::ClosureReturnTypeHint => inlay_hint.label.prepend_str(" -> "),
+        InlayKind::DiscriminantHint => inlay_hint.label.prepend_str(" = "),
         _ => {}
     }
 
@@ -447,6 +448,7 @@ pub(crate) fn inlay_hint(
             // after annotated thing
             InlayKind::ClosureReturnTypeHint
             | InlayKind::TypeHint
+            | InlayKind::DiscriminantHint
             | InlayKind::ChainingHint
             | InlayKind::GenericParamListHint
             | InlayKind::ClosingParenthesis
@@ -457,6 +459,7 @@ pub(crate) fn inlay_hint(
             InlayKind::TypeHint => !render_colons,
             InlayKind::ChainingHint | InlayKind::ClosingBraceHint => true,
             InlayKind::ClosingParenthesis
+            | InlayKind::DiscriminantHint
             | InlayKind::OpeningParenthesis
             | InlayKind::BindingModeHint
             | InlayKind::ClosureReturnTypeHint
@@ -473,6 +476,7 @@ pub(crate) fn inlay_hint(
             | InlayKind::GenericParamListHint
             | InlayKind::AdjustmentHint
             | InlayKind::TypeHint
+            | InlayKind::DiscriminantHint
             | InlayKind::ClosingBraceHint => false,
             InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"),
             InlayKind::ParameterHint | InlayKind::LifetimeHint => true,
@@ -483,6 +487,7 @@ pub(crate) fn inlay_hint(
                 Some(lsp_types::InlayHintKind::TYPE)
             }
             InlayKind::ClosingParenthesis
+            | InlayKind::DiscriminantHint
             | InlayKind::OpeningParenthesis
             | InlayKind::BindingModeHint
             | InlayKind::GenericParamListHint
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 867fd5620fd..91f8e98449e 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -454,6 +454,11 @@ to always show them).
 --
 Whether to show inlay type hints for return types of closures.
 --
+[[rust-analyzer.inlayHints.discriminantHints.enable]]rust-analyzer.inlayHints.discriminantHints.enable (default: `"never"`)::
++
+--
+Whether to show enum variant discriminant hints.
+--
 [[rust-analyzer.inlayHints.expressionAdjustmentHints.enable]]rust-analyzer.inlayHints.expressionAdjustmentHints.enable (default: `"never"`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index fad67ce8031..b45058a6cf3 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -960,6 +960,21 @@
                         "Only show type hints for return types of closures with blocks."
                     ]
                 },
+                "rust-analyzer.inlayHints.discriminantHints.enable": {
+                    "markdownDescription": "Whether to show enum variant discriminant hints.",
+                    "default": "never",
+                    "type": "string",
+                    "enum": [
+                        "always",
+                        "never",
+                        "fieldless"
+                    ],
+                    "enumDescriptions": [
+                        "Always show all discriminant hints.",
+                        "Never show discriminant hints.",
+                        "Only show discriminant hints on fieldless enum variants."
+                    ]
+                },
                 "rust-analyzer.inlayHints.expressionAdjustmentHints.enable": {
                     "markdownDescription": "Whether to show inlay hints for type adjustments.",
                     "default": "never",