impl membership type assertion error handling

This commit is contained in:
collin 2020-10-23 17:31:41 -07:00
parent dbade1f4fe
commit f2a808cbe7
4 changed files with 70 additions and 45 deletions

View File

@ -17,6 +17,7 @@
use crate::{
assert_satisfied,
expect_compiler_error,
expect_dynamic_check_error,
get_output,
parse_program,
parse_program_with_input,
@ -38,15 +39,6 @@ pub fn output_false(program: EdwardsTestCompiler) {
assert_eq!(expected, actual.bytes().as_slice());
}
fn fail_boolean_statement(program: EdwardsTestCompiler) {
match expect_compiler_error(program) {
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
ExpressionError::BooleanError(BooleanError::Error(_)),
))) => {}
_ => panic!("Expected boolean error, got {}"),
}
}
#[test]
fn test_input_pass() {
let program_bytes = include_bytes!("assert_eq_input.leo");
@ -139,9 +131,9 @@ fn test_false_or_false() {
#[test]
fn test_true_or_u32() {
let bytes = include_bytes!("true_or_u32.leo");
let program = parse_program(bytes).unwrap();
let error = parse_program(bytes).err().unwrap();
fail_boolean_statement(program);
expect_dynamic_check_error(error);
}
// Boolean and &&
@ -173,9 +165,9 @@ fn test_false_and_false() {
#[test]
fn test_true_and_u32() {
let bytes = include_bytes!("true_and_u32.leo");
let program = parse_program(bytes).unwrap();
let error = parse_program(bytes).err().unwrap();
fail_boolean_statement(program);
expect_dynamic_check_error(error);
}
// All

View File

@ -178,6 +178,15 @@ pub(crate) fn expect_compiler_error(program: EdwardsTestCompiler) -> CompilerErr
program.generate_constraints_helper(&mut cs).unwrap_err()
}
pub(crate) fn expect_dynamic_check_error(error: CompilerError) {
let is_dynamic_check = match error {
CompilerError::DynamicCheckError(_) => true,
_ => false,
};
assert!(is_dynamic_check)
}
// pub(crate) fn expect_synthesis_error(program: EdwardsTestCompiler) {
// let mut cs = TestConstraintSystem::<Fq>::new();
// let _output = program.generate_constraints_helper(&mut cs).unwrap();

View File

@ -341,8 +341,8 @@ impl Frame {
///
/// Creates a new membership type assertion between a given and set of types.
///
fn assert_membership(&mut self, given: Type, set: Vec<Type>) {
let type_assertion = TypeAssertion::new_membership(given, set);
fn assert_membership(&mut self, given: Type, set: Vec<Type>, span: &Span) {
let type_assertion = TypeAssertion::new_membership(given, set, span);
self.type_assertions.push(type_assertion);
}
@ -350,28 +350,28 @@ impl Frame {
///
/// Creates a new membership type assertion between a given and the set of negative integer types.
///
fn assert_negative_integer(&mut self, given: &Type) {
fn assert_negative_integer(&mut self, given: &Type, span: &Span) {
let negative_integer_types = Type::negative_integer_types();
self.assert_membership(given.clone(), negative_integer_types)
self.assert_membership(given.clone(), negative_integer_types, span)
}
///
/// Creates a new membership type assertion between a given and the set of all integer types.
///
fn assert_integer(&mut self, given: &Type) {
fn assert_integer(&mut self, given: &Type, span: &Span) {
let integer_types = Type::integer_types();
self.assert_membership(given.clone(), integer_types)
self.assert_membership(given.clone(), integer_types, span)
}
///
/// Creates a new membership type assertion between a given and the set of index types.
///
fn assert_index(&mut self, given: &Type) {
fn assert_index(&mut self, given: &Type, span: &Span) {
let index_types = Type::index_types();
self.assert_membership(given.clone(), index_types)
self.assert_membership(given.clone(), index_types, span)
}
///
@ -751,12 +751,12 @@ impl Frame {
&mut self,
left: &Expression,
right: &Expression,
_span: &Span,
span: &Span,
) -> Result<Type, FrameError> {
let type_ = self.parse_binary_expression(left, right, _span)?;
let type_ = self.parse_binary_expression(left, right, span)?;
// Assert that the type is an integer.
self.assert_integer(&type_);
self.assert_integer(&type_, span);
Ok(type_)
}
@ -780,12 +780,12 @@ impl Frame {
///
/// Returns the `Type` of the expression being negated. Must be a negative integer type.
///
fn parse_negate_expression(&mut self, expression: &Expression, _span: &Span) -> Result<Type, FrameError> {
fn parse_negate_expression(&mut self, expression: &Expression, span: &Span) -> Result<Type, FrameError> {
// Parse the expression type.
let type_ = self.parse_expression(expression)?;
// Assert that this integer can be negated.
self.assert_negative_integer(&type_);
self.assert_negative_integer(&type_, span);
Ok(type_)
}
@ -958,12 +958,7 @@ impl Frame {
///
/// Returns the type of the accessed array element.
///
fn parse_array_access(
&mut self,
type_: Type,
r_or_e: &RangeOrExpression,
_span: &Span,
) -> Result<Type, FrameError> {
fn parse_array_access(&mut self, type_: Type, r_or_e: &RangeOrExpression, span: &Span) -> Result<Type, FrameError> {
// Check the type is an array.
let (element_type, _dimensions) = match type_ {
Type::Array(type_, dimensions) => (type_, dimensions),
@ -980,14 +975,14 @@ impl Frame {
// Parse the expression type.
let type_ = self.parse_expression(expression)?;
self.assert_index(&type_);
self.assert_index(&type_, span);
}
if let Some(expression) = to {
// Parse the expression type.
let type_ = self.parse_expression(expression)?;
self.assert_index(&type_);
self.assert_index(&type_, span);
}
}
RangeOrExpression::Expression(expression) => {
@ -995,7 +990,7 @@ impl Frame {
let type_ = self.parse_expression(expression)?;
// Assert the type is an index.
self.assert_index(&type_);
self.assert_index(&type_, span);
}
}
@ -1423,8 +1418,8 @@ impl TypeAssertion {
///
/// Returns a `TypeAssertion::Membership` predicate from given and set `Type`s.
///
pub fn new_membership(given: Type, set: Vec<Type>) -> Self {
Self::Membership(TypeMembership::new(given, set))
pub fn new_membership(given: Type, set: Vec<Type>, span: &Span) -> Self {
Self::Membership(TypeMembership::new(given, set, span))
}
///
@ -1445,7 +1440,11 @@ impl TypeAssertion {
pub fn solve(&self) -> Result<Option<TypeVariablePair>, TypeAssertionError> {
match self {
TypeAssertion::Equality(equality) => equality.solve(),
TypeAssertion::Membership(_) => unimplemented!(),
TypeAssertion::Membership(membership) => {
membership.solve()?;
Ok(None)
}
}
}
}
@ -1455,14 +1454,19 @@ impl TypeAssertion {
pub struct TypeMembership {
given: Type,
set: Vec<Type>,
span: Span,
}
impl TypeMembership {
///
/// Returns a `TypeMembership` predicate from given and set `Type`s.
///
pub fn new(given: Type, set: Vec<Type>) -> Self {
Self { given, set }
pub fn new(given: Type, set: Vec<Type>, span: &Span) -> Self {
Self {
given,
set,
span: span.to_owned(),
}
}
///
@ -1476,8 +1480,16 @@ impl TypeMembership {
///
/// Returns true if the given type is equal to a member of the set.
///
pub fn evaluate(&self) -> bool {
self.set.contains(&self.given)
pub fn solve(&self) -> Result<(), TypeAssertionError> {
if self.set.contains(&self.given) {
Ok(())
} else {
Err(TypeAssertionError::membership_failed(
&self.given,
&self.set,
&self.span,
))
}
}
///
@ -1534,7 +1546,7 @@ impl TypeEquality {
// Return None if the two types are equal (the equality is satisfied).
None
} else {
return Err(TypeAssertionError::assertion_failed(type1, type2, &self.span));
return Err(TypeAssertionError::equality_failed(type1, type2, &self.span));
}
}
})

View File

@ -46,8 +46,20 @@ impl TypeAssertionError {
///
/// Found mismatched types during program parsing.
///
pub fn assertion_failed(left: &Type, right: &Type, span: &Span) -> Self {
let message = format!("Mismatched types expected type `{}`, found type `{}`", left, right);
pub fn equality_failed(left: &Type, right: &Type, span: &Span) -> Self {
let message = format!("Mismatched types. Expected type `{}`, found type `{}`.", left, right);
Self::new_from_span(message, span.to_owned())
}
///
/// Given type is not a member of the set of expected types.
///
pub fn membership_failed(given: &Type, set: &Vec<Type>, span: &Span) -> Self {
let message = format!(
"Mismatched types. Given type `{}` is not in the expected type set `{:?}`.",
given, set
);
Self::new_from_span(message, span.to_owned())
}