1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

add tests, fail gracefully on generic inference attempt and eq generic mismatch

This commit is contained in:
schaeff 2021-07-28 12:38:58 +02:00
parent d0622d849c
commit f92df0fa1a
7 changed files with 73 additions and 25 deletions

View file

@ -0,0 +1,7 @@
struct A<N> {
field[N] a
}
def main():
A<_> a = A { a: [1] }
return

View file

@ -0,0 +1,6 @@
struct A<N> {
field[N] a
}
def main(A<1> a, A<2> b) -> bool:
return a == b

View file

@ -0,0 +1,4 @@
struct A<N> {}
def main():
return

View file

@ -1216,18 +1216,26 @@ impl<'ast, T: Field> Checker<'ast, T> {
let assignment = GGenericsAssignment(generics
.into_iter()
.zip(generic_identifiers)
.filter_map(|(e, g)| e.map(|e| {
self
.check_expression(e, module_id, types)
.and_then(|e| {
UExpression::try_from_typed(e, &UBitwidth::B32)
.map(|e| (g, e))
.map_err(|e| ErrorInner {
pos: Some(pos),
message: format!("Expected u32 expression, but got expression of type {}", e.get_type()),
})
})
}))
.map(|(e, g)| match e {
Some(e) => {
self
.check_expression(e, module_id, types)
.and_then(|e| {
UExpression::try_from_typed(e, &UBitwidth::B32)
.map(|e| (g, e))
.map_err(|e| ErrorInner {
pos: Some(pos),
message: format!("Expected u32 expression, but got expression of type {}", e.get_type()),
})
})
},
None => Err(ErrorInner {
pos: Some(pos),
message:
"Expected u32 constant or identifier, but found `_`. Generic inference is not supported yet."
.into(),
})
})
.collect::<Result<_, _>>()?);
// specialize the declared type using the generic assignment

View file

@ -1279,6 +1279,24 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
Ok(BooleanExpression::ArrayEq(box e1, box e2))
}
BooleanExpression::StructEq(box e1, box e2) => {
let e1 = self.fold_struct_expression(e1)?;
let e2 = self.fold_struct_expression(e2)?;
if let (Ok(t1), Ok(t2)) = (
ConcreteType::try_from(e1.get_type()),
ConcreteType::try_from(e2.get_type()),
) {
if t1 != t2 {
return Err(Error::Type(format!(
"Cannot compare {} of type {} to {} of type {}",
e1, t1, e2, t2
)));
}
};
Ok(BooleanExpression::StructEq(box e1, box e2))
}
BooleanExpression::FieldLt(box e1, box e2) => {
let e1 = self.fold_field_expression(e1)?;
let e2 = self.fold_field_expression(e2)?;

View file

@ -230,12 +230,15 @@ mod tests {
public: true,
ty: ConcreteType::Struct(ConcreteStructType::new(
"".into(),
"Foo".into(),
vec![],
vec![
ConcreteStructMember::new(String::from("a"), ConcreteType::FieldElement),
ConcreteStructMember::new(String::from("b"), ConcreteType::Boolean),
],
"Bar".into(),
vec![Some(1usize)],
vec![ConcreteStructMember::new(
String::from("a"),
ConcreteType::Array(ConcreteArrayType::new(
ConcreteType::FieldElement,
1usize,
)),
)],
)),
}],
outputs: vec![ConcreteType::Struct(ConcreteStructType::new(
@ -259,16 +262,18 @@ mod tests {
"public": true,
"type": "struct",
"components": {
"name": "Foo",
"generics": [],
"name": "Bar",
"generics": [
1
],
"members": [
{
"name": "a",
"type": "field"
},
{
"name": "b",
"type": "bool"
"type": "array",
"components": {
"size": 1,
"type": "field"
}
}
]
}