From 506838d9e4992848bea0378058e9acacec2cc709 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Thu, 21 Sep 2023 18:44:23 +0000 Subject: [PATCH 1/2] error on unsupported integer annotation --- .../noirc_frontend/src/hir/type_check/errors.rs | 5 ++++- compiler/noirc_frontend/src/hir/type_check/stmt.rs | 14 ++++++++++++-- compiler/noirc_frontend/src/hir_def/types.rs | 8 ++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index ece3a4c61ef..2ccf4381aa8 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -108,6 +108,8 @@ pub enum TypeCheckError { parameter_span: Span, parameter_index: usize, }, + #[error("Integer annotation specifies {num_bits:?} bits which is over the max supported size of {max_num_bits:?}")] + UnsupportedIntegerSize { num_bits: u32, max_num_bits: u32, span: Span }, } impl TypeCheckError { @@ -194,7 +196,8 @@ impl From for Diagnostic { | TypeCheckError::FieldComparison { span, .. } | TypeCheckError::AmbiguousBitWidth { span, .. } | TypeCheckError::IntegerAndFieldBinaryOperation { span } - | TypeCheckError::OverflowingAssignment { span, .. } => { + | TypeCheckError::OverflowingAssignment { span, .. } + | TypeCheckError::UnsupportedIntegerSize { span, .. } => { Diagnostic::simple_error(error.to_string(), String::new(), span) } TypeCheckError::PublicReturnType { typ, span } => Diagnostic::simple_error( diff --git a/compiler/noirc_frontend/src/hir/type_check/stmt.rs b/compiler/noirc_frontend/src/hir/type_check/stmt.rs index 5db23c3f4f2..bf5f91f7b2b 100644 --- a/compiler/noirc_frontend/src/hir/type_check/stmt.rs +++ b/compiler/noirc_frontend/src/hir/type_check/stmt.rs @@ -1,3 +1,4 @@ +use acvm::FieldElement; use iter_extended::vecmap; use noirc_errors::{Location, Span}; @@ -265,8 +266,17 @@ impl<'interner> TypeChecker<'interner> { expr_span, } }); - if annotated_type.is_unsigned() { - self.lint_overflowing_uint(&rhs_expr, &annotated_type); + if let Some(bit_size) = annotated_type.bit_size() { + let max_integer_bit_size = FieldElement::max_num_bits() / 2; + if bit_size > max_integer_bit_size { + self.errors.push(TypeCheckError::UnsupportedIntegerSize { + num_bits: bit_size, + max_num_bits: max_integer_bit_size, + span: expr_span, + }); + } else if annotated_type.is_unsigned() { + self.lint_overflowing_uint(&rhs_expr, &annotated_type); + } } annotated_type } else { diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index eb837ec5f55..2febf8e7328 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -446,6 +446,14 @@ impl Type { matches!(self.follow_bindings(), Type::FieldElement) } + // Return the bit size of an integer type, otherwise return `None` + pub fn bit_size(&self) -> Option { + match self.follow_bindings() { + Type::Integer(_, bit_size) => Some(bit_size), + _ => None, + } + } + pub fn is_signed(&self) -> bool { matches!(self.follow_bindings(), Type::Integer(Signedness::Signed, _)) } From 5f61a232073ff2a69f1436e4b63233b308ceb8dd Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 22 Sep 2023 02:51:47 +0000 Subject: [PATCH 2/2] move unsupported integer size to lexer --- .../noirc_frontend/src/hir/type_check/errors.rs | 5 +---- compiler/noirc_frontend/src/hir/type_check/stmt.rs | 14 ++------------ compiler/noirc_frontend/src/hir_def/types.rs | 8 -------- compiler/noirc_frontend/src/lexer/token.rs | 2 +- 4 files changed, 4 insertions(+), 25 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index 2ccf4381aa8..ece3a4c61ef 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -108,8 +108,6 @@ pub enum TypeCheckError { parameter_span: Span, parameter_index: usize, }, - #[error("Integer annotation specifies {num_bits:?} bits which is over the max supported size of {max_num_bits:?}")] - UnsupportedIntegerSize { num_bits: u32, max_num_bits: u32, span: Span }, } impl TypeCheckError { @@ -196,8 +194,7 @@ impl From for Diagnostic { | TypeCheckError::FieldComparison { span, .. } | TypeCheckError::AmbiguousBitWidth { span, .. } | TypeCheckError::IntegerAndFieldBinaryOperation { span } - | TypeCheckError::OverflowingAssignment { span, .. } - | TypeCheckError::UnsupportedIntegerSize { span, .. } => { + | TypeCheckError::OverflowingAssignment { span, .. } => { Diagnostic::simple_error(error.to_string(), String::new(), span) } TypeCheckError::PublicReturnType { typ, span } => Diagnostic::simple_error( diff --git a/compiler/noirc_frontend/src/hir/type_check/stmt.rs b/compiler/noirc_frontend/src/hir/type_check/stmt.rs index bf5f91f7b2b..5db23c3f4f2 100644 --- a/compiler/noirc_frontend/src/hir/type_check/stmt.rs +++ b/compiler/noirc_frontend/src/hir/type_check/stmt.rs @@ -1,4 +1,3 @@ -use acvm::FieldElement; use iter_extended::vecmap; use noirc_errors::{Location, Span}; @@ -266,17 +265,8 @@ impl<'interner> TypeChecker<'interner> { expr_span, } }); - if let Some(bit_size) = annotated_type.bit_size() { - let max_integer_bit_size = FieldElement::max_num_bits() / 2; - if bit_size > max_integer_bit_size { - self.errors.push(TypeCheckError::UnsupportedIntegerSize { - num_bits: bit_size, - max_num_bits: max_integer_bit_size, - span: expr_span, - }); - } else if annotated_type.is_unsigned() { - self.lint_overflowing_uint(&rhs_expr, &annotated_type); - } + if annotated_type.is_unsigned() { + self.lint_overflowing_uint(&rhs_expr, &annotated_type); } annotated_type } else { diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index 2febf8e7328..eb837ec5f55 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -446,14 +446,6 @@ impl Type { matches!(self.follow_bindings(), Type::FieldElement) } - // Return the bit size of an integer type, otherwise return `None` - pub fn bit_size(&self) -> Option { - match self.follow_bindings() { - Type::Integer(_, bit_size) => Some(bit_size), - _ => None, - } - } - pub fn is_signed(&self) -> bool { matches!(self.follow_bindings(), Type::Integer(Signedness::Signed, _)) } diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index fb5ab220b2c..9eaa4fa75e5 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -302,7 +302,7 @@ impl IntType { Err(_) => return Ok(None), }; - let max_bits = FieldElement::max_num_bits(); + let max_bits = FieldElement::max_num_bits() / 2; if str_as_u32 > max_bits { return Err(LexerErrorKind::TooManyBits { span, max: max_bits, got: str_as_u32 });