Added consteval tests
This commit is contained in:
parent
2f84b6e2e5
commit
ad0a6bf1a3
@ -28,8 +28,8 @@ use crate::{
|
|||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
path::{ModPath, Path},
|
path::{ModPath, Path},
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId,
|
AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId, ModuleId,
|
||||||
ModuleId, UnresolvedMacro,
|
UnresolvedMacro,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use lower::LowerCtx;
|
pub use lower::LowerCtx;
|
||||||
@ -328,7 +328,6 @@ impl Body {
|
|||||||
let e = v.parent.lookup(db);
|
let e = v.parent.lookup(db);
|
||||||
let src = v.parent.child_source(db);
|
let src = v.parent.child_source(db);
|
||||||
let variant = &src.value[v.local_id];
|
let variant = &src.value[v.local_id];
|
||||||
// TODO(ole): Handle missing exprs (+1 to the prev)
|
|
||||||
(src.file_id, e.container, variant.expr())
|
(src.file_id, e.container, variant.expr())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -203,7 +203,7 @@ pub fn eval_const(
|
|||||||
Ok(ComputedExpr::Enum(
|
Ok(ComputedExpr::Enum(
|
||||||
get_name(variant, ctx),
|
get_name(variant, ctx),
|
||||||
variant,
|
variant,
|
||||||
Literal::Int(value + 1, Some(BuiltinInt::I128)),
|
Literal::Int(value, Some(BuiltinInt::I128)),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => Err(ConstEvalError::IncompleteExpr),
|
_ => 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]
|
#[test]
|
||||||
fn const_loop() {
|
fn const_loop() {
|
||||||
check_fail(
|
check_fail(
|
||||||
|
@ -952,6 +952,10 @@ impl Enum {
|
|||||||
pub fn ty(self, db: &dyn HirDatabase) -> Type {
|
pub fn ty(self, db: &dyn HirDatabase) -> Type {
|
||||||
Type::from_def(db, self.id)
|
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 {
|
impl HasVisibility for Enum {
|
||||||
@ -996,7 +1000,6 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
|
pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
|
||||||
// TODO(ole): Handle missing exprs (+1 to the prev)
|
|
||||||
self.source(db)?.value.expr()
|
self.source(db)?.value.expr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,12 +348,15 @@ pub(super) fn definition(
|
|||||||
Definition::Module(it) => label_and_docs(db, it),
|
Definition::Module(it) => label_and_docs(db, it),
|
||||||
Definition::Function(it) => label_and_docs(db, it),
|
Definition::Function(it) => label_and_docs(db, it),
|
||||||
Definition::Adt(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) {
|
Definition::Variant(it) => label_value_and_docs(db, it, |&it| {
|
||||||
StructKind::Unit => match it.eval(db) {
|
if it.parent.is_data_carrying(db) {
|
||||||
Ok(x) => Some(format!("{}", x.enum_value().unwrap_or(x))),
|
match it.eval(db) {
|
||||||
Err(_) => it.value(db).map(|x| format!("{:?}", x)),
|
Ok(x) => Some(format!("{}", x.enum_value().unwrap_or(x))),
|
||||||
},
|
Err(_) => it.value(db).map(|x| format!("{:?}", x)),
|
||||||
_ => None,
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
Definition::Const(it) => label_value_and_docs(db, it, |it| {
|
Definition::Const(it) => label_value_and_docs(db, it, |it| {
|
||||||
let body = it.eval(db);
|
let body = it.eval(db);
|
||||||
|
@ -698,6 +698,7 @@ fn hover_enum_variant() {
|
|||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
enum Option<T> {
|
enum Option<T> {
|
||||||
|
Some(T)
|
||||||
/// The None variant
|
/// The None variant
|
||||||
Non$0e
|
Non$0e
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user