Added consteval tests
This commit is contained in:
parent
2f84b6e2e5
commit
ad0a6bf1a3
@ -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())
|
||||
}
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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(
|
||||
|
@ -952,6 +952,10 @@ pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
|
||||
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<VariantData> {
|
||||
}
|
||||
|
||||
pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
|
||||
// TODO(ole): Handle missing exprs (+1 to the prev)
|
||||
self.source(db)?.value.expr()
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -698,6 +698,7 @@ fn hover_enum_variant() {
|
||||
check(
|
||||
r#"
|
||||
enum Option<T> {
|
||||
Some(T)
|
||||
/// The None variant
|
||||
Non$0e
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user