Added consteval tests

This commit is contained in:
OleStrohm 2022-08-07 18:22:18 +02:00
parent 2f84b6e2e5
commit ad0a6bf1a3
6 changed files with 46 additions and 11 deletions

View File

@ -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())
}
};

View File

@ -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),

View File

@ -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(

View File

@ -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()
}

View File

@ -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);

View File

@ -698,6 +698,7 @@ fn hover_enum_variant() {
check(
r#"
enum Option<T> {
Some(T)
/// The None variant
Non$0e
}