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;
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())
}
};
Ok(ComputedExpr::Enum(
get_name(variant, ctx),
variant,
- Literal::Int(value + 1, Some(BuiltinInt::I128)),
+ Literal::Int(value, Some(BuiltinInt::I128)),
))
}
_ => Err(ConstEvalError::IncompleteExpr),
);
}
+#[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(
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 {
}
pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
- // TODO(ole): Handle missing exprs (+1 to the prev)
self.source(db)?.value.expr()
}
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);
check(
r#"
enum Option<T> {
+ Some(T)
/// The None variant
Non$0e
}