Skip to content

Commit

Permalink
Fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
d0cd committed Mar 27, 2023
1 parent dcf2b6f commit ee3e225
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 23 deletions.
41 changes: 21 additions & 20 deletions compiler/ast/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use leo_errors::{type_name, FlattenError, LeoError, Result};
use leo_span::{Span, Symbol};

use indexmap::IndexMap;
use std::num::ParseIntError;
use std::{
fmt::Display,
ops::{BitAnd, BitOr, BitXor, Not},
Expand Down Expand Up @@ -864,29 +865,29 @@ impl From<&Value> for Type {
}
}

// TODO: Consider making this `Option<Value>` instead of `Value`.
impl From<&Literal> for Value {
impl TryFrom<&Literal> for Value {
type Error = ParseIntError;

/// Converts a literal to a value.
/// This should only be invoked on literals that are known to be valid.
fn from(literal: &Literal) -> Self {
fn try_from(literal: &Literal) -> Result<Self, Self::Error> {
match literal {
Literal::Address(string, span) => Self::Address(string.clone(), *span),
Literal::Boolean(bool, span) => Self::Boolean(*bool, *span),
Literal::Field(string, span) => Self::Field(string.clone(), *span),
Literal::Group(group_literal) => Self::Group(group_literal.clone()),
Literal::Scalar(string, span) => Self::Scalar(string.clone(), *span),
Literal::String(string, span) => Self::String(string.clone(), *span),
Literal::Address(string, span) => Ok(Self::Address(string.clone(), *span)),
Literal::Boolean(bool, span) => Ok(Self::Boolean(*bool, *span)),
Literal::Field(string, span) => Ok(Self::Field(string.clone(), *span)),
Literal::Group(group_literal) => Ok(Self::Group(group_literal.clone())),
Literal::Scalar(string, span) => Ok(Self::Scalar(string.clone(), *span)),
Literal::String(string, span) => Ok(Self::String(string.clone(), *span)),
Literal::Integer(integer_type, string, span) => match integer_type {
IntegerType::U8 => Self::U8(string.parse().unwrap(), *span),
IntegerType::U16 => Self::U16(string.parse().unwrap(), *span),
IntegerType::U32 => Self::U32(string.parse().unwrap(), *span),
IntegerType::U64 => Self::U64(string.parse().unwrap(), *span),
IntegerType::U128 => Self::U128(string.parse().unwrap(), *span),
IntegerType::I8 => Self::I8(string.parse().unwrap(), *span),
IntegerType::I16 => Self::I16(string.parse().unwrap(), *span),
IntegerType::I32 => Self::I32(string.parse().unwrap(), *span),
IntegerType::I64 => Self::I64(string.parse().unwrap(), *span),
IntegerType::I128 => Self::I128(string.parse().unwrap(), *span),
IntegerType::U8 => Ok(Self::U8(string.parse()?, *span)),
IntegerType::U16 => Ok(Self::U16(string.parse()?, *span)),
IntegerType::U32 => Ok(Self::U32(string.parse()?, *span)),
IntegerType::U64 => Ok(Self::U64(string.parse()?, *span)),
IntegerType::U128 => Ok(Self::U128(string.parse()?, *span)),
IntegerType::I8 => Ok(Self::I8(string.parse()?, *span)),
IntegerType::I16 => Ok(Self::I16(string.parse()?, *span)),
IntegerType::I32 => Ok(Self::I32(string.parse()?, *span)),
IntegerType::I64 => Ok(Self::I64(string.parse()?, *span)),
IntegerType::I128 => Ok(Self::I128(string.parse()?, *span)),
},
}
}
Expand Down
13 changes: 10 additions & 3 deletions compiler/passes/src/type_checking/check_statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,15 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
// Exit the scope.
self.exit_scope(scope_index);

// Check that the literal is valid.
self.visit_expression(&input.start, iter_type);

// If `input.start` is a literal, instantiate it as a value.
// If `input.start` is a valid literal, instantiate it as a value.
if let Expression::Literal(literal) = &input.start {
input.start_value.replace(Some(Value::from(literal)));
// Note that this check is needed because the pass attempts to make progress, even though the literal may be invalid.
if let Ok(value) = Value::try_from(literal) {
input.start_value.replace(Some(value));
}
} else {
self.emit_err(TypeCheckerError::loop_bound_must_be_a_literal(input.start.span()));
}
Expand All @@ -362,7 +366,10 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {

// If `input.stop` is a literal, instantiate it as a value.
if let Expression::Literal(literal) = &input.stop {
input.stop_value.replace(Some(Value::from(literal)));
// Note that this check is needed because the pass attempts to make progress, even though the literal may be invalid.
if let Ok(value) = Value::try_from(literal) {
input.stop_value.replace(Some(value));
}
} else {
self.emit_err(TypeCheckerError::loop_bound_must_be_a_literal(input.stop.span()));
}
Expand Down

0 comments on commit ee3e225

Please sign in to comment.