diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index be1a9d11773..2dc7714bbb5 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -28,8 +28,8 @@ nameres::DefMap, path::{ModPath, Path}, src::{HasChildSource, HasSource}, - AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId, - ModuleId, UnresolvedMacro, + AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId, ModuleId, + UnresolvedMacro, }; pub use lower::LowerCtx; @@ -328,7 +328,6 @@ pub(crate) fn body_with_source_map_query( let e = v.parent.lookup(db); let src = v.parent.child_source(db); let variant = &src.value[v.local_id]; - // TODO(ole): Handle missing exprs (+1 to the prev) (src.file_id, e.container, variant.expr()) } }; diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index efb17c4780a..141652db73a 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -203,7 +203,7 @@ pub fn eval_const( Ok(ComputedExpr::Enum( get_name(variant, ctx), variant, - Literal::Int(value + 1, Some(BuiltinInt::I128)), + Literal::Int(value, Some(BuiltinInt::I128)), )) } _ => Err(ConstEvalError::IncompleteExpr), diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index 4a052851afd..357d43d2253 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -87,6 +87,35 @@ fn consts() { ); } +#[test] +fn enums() { + check_number( + r#" + enum E { + F1 = 1, + F2 = 2 * E::F1 as u8, + F3 = 3 * E::F2 as u8, + } + const GOAL: i32 = E::F3 as u8; + "#, + 6, + ); + let r = eval_goal( + r#" + enum E { A = 1, } + const GOAL: E = E::A; + "#, + ) + .unwrap(); + match r { + ComputedExpr::Enum(name, _, Literal::Uint(val, _)) => { + assert_eq!(name, "E::A"); + assert_eq!(val, 1); + } + x => panic!("Expected enum but found {:?}", x), + } +} + #[test] fn const_loop() { check_fail( diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 1b06dbd9085..b656eaa74ca 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -952,6 +952,10 @@ pub fn variants(self, db: &dyn HirDatabase) -> Vec { pub fn ty(self, db: &dyn HirDatabase) -> Type { Type::from_def(db, self.id) } + + pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool { + self.variants(db).iter().all(|v| matches!(v.kind(db), StructKind::Unit)) + } } impl HasVisibility for Enum { @@ -996,7 +1000,6 @@ pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc { } pub fn value(self, db: &dyn HirDatabase) -> Option { - // TODO(ole): Handle missing exprs (+1 to the prev) self.source(db)?.value.expr() } diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index 44291a1a88b..486739628f2 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -348,12 +348,15 @@ pub(super) fn definition( Definition::Module(it) => label_and_docs(db, it), Definition::Function(it) => label_and_docs(db, it), Definition::Adt(it) => label_and_docs(db, it), - Definition::Variant(it) => label_value_and_docs(db, it, |&it| match it.kind(db) { - StructKind::Unit => match it.eval(db) { - Ok(x) => Some(format!("{}", x.enum_value().unwrap_or(x))), - Err(_) => it.value(db).map(|x| format!("{:?}", x)), - }, - _ => None, + Definition::Variant(it) => label_value_and_docs(db, it, |&it| { + if it.parent.is_data_carrying(db) { + match it.eval(db) { + Ok(x) => Some(format!("{}", x.enum_value().unwrap_or(x))), + Err(_) => it.value(db).map(|x| format!("{:?}", x)), + } + } else { + None + } }), Definition::Const(it) => label_value_and_docs(db, it, |it| { let body = it.eval(db); diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index b877e6e5c9f..362b9fa815d 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -698,6 +698,7 @@ fn hover_enum_variant() { check( r#" enum Option { + Some(T) /// The None variant Non$0e }