From 2abd98ce811438aabcee95e07b13de04aca16380 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 9 Jan 2025 10:54:19 -0300 Subject: [PATCH] chore: require safety doc comment for unsafe instead of `//@safety` (#6992) --- compiler/noirc_frontend/src/debug/mod.rs | 12 +- .../src/elaborator/expressions.rs | 4 +- compiler/noirc_frontend/src/lexer/lexer.rs | 22 +- compiler/noirc_frontend/src/lexer/token.rs | 3 - compiler/noirc_frontend/src/parser/errors.rs | 16 +- compiler/noirc_frontend/src/parser/parser.rs | 22 ++ .../src/parser/parser/expression.rs | 83 +++++-- .../src/parser/parser/statement.rs | 65 ++++- compiler/noirc_frontend/src/tests.rs | 6 +- .../noirc_frontend/src/tests/references.rs | 2 +- docs/docs/noir/concepts/unconstrained.md | 8 +- noir_stdlib/src/array/check_shuffle.nr | 5 +- noir_stdlib/src/array/mod.nr | 7 +- noir_stdlib/src/collections/umap.nr | 12 +- noir_stdlib/src/field/bn254.nr | 19 +- noir_stdlib/src/field/mod.nr | 2 +- noir_stdlib/src/hash/mod.nr | 6 +- noir_stdlib/src/hash/sha256.nr | 39 ++- noir_stdlib/src/lib.nr | 4 +- noir_stdlib/src/meta/expr.nr | 8 +- noir_stdlib/src/uint128.nr | 30 +-- .../brillig_mut_ref_from_acir/src/main.nr | 6 +- .../regression_5008/src/main.nr | 8 +- .../unconstrained_ref/src/main.nr | 6 +- .../acir_inside_brillig_recursion/src/main.nr | 2 +- .../brillig_cast/src/main.nr | 2 +- .../src/main.nr | 2 +- .../src/main.nr | 2 +- .../brillig_modulo/src/main.nr | 2 +- .../brillig_slice_input/src/main.nr | 4 +- .../is_unconstrained/src/main.nr | 2 +- .../macros_in_comptime/src/main.nr | 5 +- .../src/main.nr | 20 +- .../src/main.nr | 2 +- .../brillig_assert_fail/src/main.nr | 10 +- .../brillig_assert_msg_runtime/src/main.nr | 8 +- .../src/main.nr | 4 +- .../regression_5202/src/main.nr | 21 +- .../aes128_encrypt/src/main.nr | 12 +- .../src/main.nr | 2 +- .../execution_success/bigint/src/main.nr | 2 +- .../brillig_acir_as_brillig/src/main.nr | 2 +- .../brillig_arrays/src/main.nr | 2 +- .../brillig_blake2s/src/main.nr | 2 +- .../brillig_calls_array/src/main.nr | 2 +- .../brillig_calls_conditionals/src/main.nr | 2 +- .../brillig_conditional/src/main.nr | 2 +- .../brillig_fns_as_values/src/main.nr | 2 +- .../brillig_identity_function/src/main.nr | 2 +- .../brillig_nested_arrays/src/main.nr | 2 +- .../execution_success/brillig_not/src/main.nr | 2 +- .../brillig_oracle/src/main.nr | 2 +- .../brillig_recursion/src/main.nr | 2 +- .../brillig_uninitialized_arrays/src/main.nr | 2 +- .../global_consts/src/main.nr | 5 +- .../hint_black_box/src/main.nr | 6 +- .../nested_arrays_from_brillig/src/main.nr | 6 +- .../reference_only_used_as_alias/src/main.nr | 2 +- .../regression_5435/src/main.nr | 6 +- .../regression_6451/src/main.nr | 6 +- .../regression_6674_3/src/main.nr | 5 +- .../src/main.nr | 6 +- .../execution_success/u16_support/src/main.nr | 2 +- .../execution_success/uhashmap/src/main.nr | 13 +- .../comptime_expr/src/main.nr | 223 +++++++----------- .../noir_test_success/mock_oracle/src/main.nr | 19 +- .../out_of_bounds_alignment/src/main.nr | 7 +- .../src/formatter/comments_and_whitespace.rs | 8 +- tooling/nargo_fmt/src/formatter/expression.rs | 28 ++- tooling/nargo_fmt/src/formatter/statement.rs | 20 +- tooling/nargo_fmt/src/lib.rs | 1 + tooling/nargo_fmt/tests/expected/unsafe.nr | 6 +- tooling/nargo_fmt/tests/input/unsafe.nr | 6 +- 73 files changed, 463 insertions(+), 435 deletions(-) diff --git a/compiler/noirc_frontend/src/debug/mod.rs b/compiler/noirc_frontend/src/debug/mod.rs index c9c2cdcfea1..808bbda677c 100644 --- a/compiler/noirc_frontend/src/debug/mod.rs +++ b/compiler/noirc_frontend/src/debug/mod.rs @@ -523,8 +523,8 @@ pub fn build_debug_crate_file() -> String { __debug_var_assign_oracle(var_id, value); } pub fn __debug_var_assign(var_id: u32, value: T) { + /// Safety: debug context unsafe { - //@safety: debug context { __debug_var_assign_inner(var_id, value); }} @@ -536,8 +536,8 @@ pub fn build_debug_crate_file() -> String { __debug_var_drop_oracle(var_id); } pub fn __debug_var_drop(var_id: u32) { + /// Safety: debug context unsafe { - //@safety: debug context { __debug_var_drop_inner(var_id); }} @@ -549,8 +549,8 @@ pub fn build_debug_crate_file() -> String { __debug_fn_enter_oracle(fn_id); } pub fn __debug_fn_enter(fn_id: u32) { + /// Safety: debug context unsafe { - //@safety: debug context { __debug_fn_enter_inner(fn_id); }} @@ -562,8 +562,8 @@ pub fn build_debug_crate_file() -> String { __debug_fn_exit_oracle(fn_id); } pub fn __debug_fn_exit(fn_id: u32) { + /// Safety: debug context unsafe { - //@safety: debug context { __debug_fn_exit_inner(fn_id); }} @@ -575,8 +575,8 @@ pub fn build_debug_crate_file() -> String { __debug_dereference_assign_oracle(var_id, value); } pub fn __debug_dereference_assign(var_id: u32, value: T) { + /// Safety: debug context unsafe { - //@safety: debug context { __debug_dereference_assign_inner(var_id, value); }} @@ -603,8 +603,8 @@ pub fn build_debug_crate_file() -> String { __debug_oracle_member_assign_{n}(var_id, value, {vars}); }} pub fn __debug_member_assign_{n}(var_id: u32, value: T, {var_sig}) {{ + /// Safety: debug context unsafe {{ - //@safety: debug context __debug_inner_member_assign_{n}(var_id, value, {vars}); }} }} diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 73b8ef6a6bd..1b3bc645cbc 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -58,8 +58,8 @@ impl<'context> Elaborator<'context> { ExpressionKind::Comptime(comptime, _) => { return self.elaborate_comptime_block(comptime, expr.span) } - ExpressionKind::Unsafe(block_expression, _) => { - self.elaborate_unsafe_block(block_expression, expr.span) + ExpressionKind::Unsafe(block_expression, span) => { + self.elaborate_unsafe_block(block_expression, span) } ExpressionKind::Resolved(id) => return (id, self.interner.id_type(id)), ExpressionKind::Interned(id) => { diff --git a/compiler/noirc_frontend/src/lexer/lexer.rs b/compiler/noirc_frontend/src/lexer/lexer.rs index 99799b9a1c0..0b7bd0991d9 100644 --- a/compiler/noirc_frontend/src/lexer/lexer.rs +++ b/compiler/noirc_frontend/src/lexer/lexer.rs @@ -726,7 +726,7 @@ impl<'a> Lexer<'a> { } fn parse_comment(&mut self, start: u32) -> SpannedTokenResult { - let mut doc_style = match self.peek_char() { + let doc_style = match self.peek_char() { Some('!') => { self.next_char(); Some(DocStyle::Inner) @@ -735,17 +735,9 @@ impl<'a> Lexer<'a> { self.next_char(); Some(DocStyle::Outer) } - Some('@') => Some(DocStyle::Safety), _ => None, }; - let mut comment = self.eat_while(None, |ch| ch != '\n'); - if doc_style == Some(DocStyle::Safety) { - if comment.starts_with("@safety") { - comment = comment["@safety".len()..].to_string(); - } else { - doc_style = None; - } - } + let comment = self.eat_while(None, |ch| ch != '\n'); if !comment.is_ascii() { let span = Span::from(start..self.position); @@ -760,7 +752,7 @@ impl<'a> Lexer<'a> { } fn parse_block_comment(&mut self, start: u32) -> SpannedTokenResult { - let mut doc_style = match self.peek_char() { + let doc_style = match self.peek_char() { Some('!') => { self.next_char(); Some(DocStyle::Inner) @@ -769,7 +761,6 @@ impl<'a> Lexer<'a> { self.next_char(); Some(DocStyle::Outer) } - Some('@') => Some(DocStyle::Safety), _ => None, }; @@ -796,13 +787,6 @@ impl<'a> Lexer<'a> { ch => content.push(ch), } } - if doc_style == Some(DocStyle::Safety) { - if content.starts_with("@safety") { - content = content["@safety".len()..].to_string(); - } else { - doc_style = None; - } - } if depth == 0 { if !content.is_ascii() { let span = Span::from(start..self.position); diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index 7f0c87d0794..8df831bbaab 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -345,7 +345,6 @@ impl Display for FmtStrFragment { pub enum DocStyle { Outer, Inner, - Safety, } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -425,13 +424,11 @@ impl fmt::Display for Token { Token::LineComment(ref s, style) => match style { Some(DocStyle::Inner) => write!(f, "//!{s}"), Some(DocStyle::Outer) => write!(f, "///{s}"), - Some(DocStyle::Safety) => write!(f, "//@safety{s}"), None => write!(f, "//{s}"), }, Token::BlockComment(ref s, style) => match style { Some(DocStyle::Inner) => write!(f, "/*!{s}*/"), Some(DocStyle::Outer) => write!(f, "/**{s}*/"), - Some(DocStyle::Safety) => write!(f, "/*@safety{s}*/"), None => write!(f, "/*{s}*/"), }, Token::Quote(ref stream) => { diff --git a/compiler/noirc_frontend/src/parser/errors.rs b/compiler/noirc_frontend/src/parser/errors.rs index 1b16b911b18..f44f109e1ce 100644 --- a/compiler/noirc_frontend/src/parser/errors.rs +++ b/compiler/noirc_frontend/src/parser/errors.rs @@ -110,8 +110,10 @@ pub enum ParserErrorReason { WrongNumberOfAttributeArguments { name: String, min: usize, max: usize, found: usize }, #[error("The `deprecated` attribute expects a string argument")] DeprecatedAttributeExpectsAStringArgument, - #[error("Unsafe block must start with a safety comment")] + #[error("Unsafe block must have a safety doc comment above it")] MissingSafetyComment, + #[error("Unsafe block must start with a safety comment")] + UnsafeDocCommentDoesNotStartWithSafety, #[error("Missing parameters for function definition")] MissingParametersForFunctionDefinition, } @@ -283,10 +285,18 @@ impl<'a> From<&'a ParserError> for Diagnostic { error.span, ), ParserErrorReason::MissingSafetyComment => Diagnostic::simple_warning( - "Missing Safety Comment".into(), - "Unsafe block must start with a safety comment: //@safety".into(), + "Unsafe block must have a safety doc comment above it".into(), + "The doc comment must start with the \"Safety: \" word".into(), error.span, ), + ParserErrorReason::UnsafeDocCommentDoesNotStartWithSafety => { + Diagnostic::simple_warning( + "Unsafe block must start with a safety comment".into(), + "The doc comment above this unsafe block must start with the \"Safety: \" word" + .into(), + error.span, + ) + } ParserErrorReason::MissingParametersForFunctionDefinition => { Diagnostic::simple_error( "Missing parameters for function definition".into(), diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 33c7a8aad51..05f8ae3c2bb 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -83,6 +83,27 @@ pub struct Parser<'a> { next_token: SpannedToken, current_token_span: Span, previous_token_span: Span, + + /// The current statement's doc comments. + /// This is used to eventually know if an `unsafe { ... }` expression is documented + /// in its containing statement. For example: + /// + /// ```noir + /// /// Safety: test + /// let x = unsafe { call() }; + /// ``` + statement_doc_comments: Option, +} + +#[derive(Debug)] +pub(crate) struct StatementDocComments { + pub(crate) doc_comments: Vec, + pub(crate) start_span: Span, + pub(crate) end_span: Span, + + /// Were these doc comments "read" by an unsafe statement? + /// If not, these doc comments aren't documenting anything and they produce an error. + pub(crate) read: bool, } impl<'a> Parser<'a> { @@ -107,6 +128,7 @@ impl<'a> Parser<'a> { next_token: eof_spanned_token(), current_token_span: Default::default(), previous_token_span: Default::default(), + statement_doc_comments: None, }; parser.read_two_first_tokens(); parser diff --git a/compiler/noirc_frontend/src/parser/parser/expression.rs b/compiler/noirc_frontend/src/parser/parser/expression.rs index 6b059bb0c8c..15be2155a15 100644 --- a/compiler/noirc_frontend/src/parser/parser/expression.rs +++ b/compiler/noirc_frontend/src/parser/parser/expression.rs @@ -8,7 +8,7 @@ use crate::{ MemberAccessExpression, MethodCallExpression, Statement, TypePath, UnaryOp, UnresolvedType, }, parser::{labels::ParsingRuleLabel, parser::parse_many::separated_by_comma, ParserErrorReason}, - token::{DocStyle, Keyword, SpannedToken, Token, TokenKind}, + token::{Keyword, Token, TokenKind}, }; use super::{ @@ -267,6 +267,21 @@ impl<'a> Parser<'a> { } fn parse_atom_kind(&mut self, allow_constructors: bool) -> Option { + let span_before_doc_comments = self.current_token_span; + let doc_comments = self.parse_outer_doc_comments(); + let has_doc_comments = !doc_comments.is_empty(); + + if let Some(kind) = self.parse_unsafe_expr(&doc_comments, span_before_doc_comments) { + return Some(kind); + } + + if has_doc_comments { + self.push_error( + ParserErrorReason::DocCommentDoesNotDocumentAnything, + self.span_since(span_before_doc_comments), + ); + } + if let Some(literal) = self.parse_literal() { return Some(literal); } @@ -275,10 +290,6 @@ impl<'a> Parser<'a> { return Some(kind); } - if let Some(kind) = self.parse_unsafe_expr() { - return Some(kind); - } - if let Some(kind) = self.parse_path_expr(allow_constructors) { return Some(kind); } @@ -370,26 +381,43 @@ impl<'a> Parser<'a> { } /// UnsafeExpression = 'unsafe' Block - fn parse_unsafe_expr(&mut self) -> Option { + fn parse_unsafe_expr( + &mut self, + doc_comments: &[String], + span_before_doc_comments: Span, + ) -> Option { + let start_span = self.current_token_span; + if !self.eat_keyword(Keyword::Unsafe) { return None; } - let next_token = self.next_token.token(); - if matches!( - next_token, - Token::LineComment(_, Some(DocStyle::Safety)) - | Token::BlockComment(_, Some(DocStyle::Safety)) - ) { - //Checks the safety comment is there, and skip it - let span = self.current_token_span; - self.eat_left_brace(); - self.token = SpannedToken::new(Token::LeftBrace, span); - } else { - self.push_error(ParserErrorReason::MissingSafetyComment, self.current_token_span); + if doc_comments.is_empty() { + if let Some(statement_doc_comments) = &mut self.statement_doc_comments { + statement_doc_comments.read = true; + + let doc_comments = &statement_doc_comments.doc_comments; + let span_before_doc_comments = statement_doc_comments.start_span; + let span_after_doc_comments = statement_doc_comments.end_span; + + if !doc_comments[0].trim().to_lowercase().starts_with("safety:") { + self.push_error( + ParserErrorReason::UnsafeDocCommentDoesNotStartWithSafety, + Span::from( + span_before_doc_comments.start()..span_after_doc_comments.start(), + ), + ); + } + } else { + self.push_error(ParserErrorReason::MissingSafetyComment, start_span); + } + } else if !doc_comments[0].trim().to_lowercase().starts_with("safety:") { + self.push_error( + ParserErrorReason::UnsafeDocCommentDoesNotStartWithSafety, + self.span_since(span_before_doc_comments), + ); } - let start_span = self.current_token_span; if let Some(block) = self.parse_block() { Some(ExpressionKind::Unsafe(block, self.span_since(start_span))) } else { @@ -971,8 +999,21 @@ mod tests { #[test] fn parses_unsafe_expression() { - let src = "unsafe { //@safety: test - 1 }"; + let src = " + /// Safety: test + unsafe { 1 }"; + let expr = parse_expression_no_errors(src); + let ExpressionKind::Unsafe(block, _) = expr.kind else { + panic!("Expected unsafe expression"); + }; + assert_eq!(block.statements.len(), 1); + } + + #[test] + fn parses_unsafe_expression_with_doc_comment() { + let src = " + /// Safety: test + unsafe { 1 }"; let expr = parse_expression_no_errors(src); let ExpressionKind::Unsafe(block, _) = expr.kind else { panic!("Expected unsafe expression"); diff --git a/compiler/noirc_frontend/src/parser/parser/statement.rs b/compiler/noirc_frontend/src/parser/parser/statement.rs index 14c8a415a38..315f3b9f958 100644 --- a/compiler/noirc_frontend/src/parser/parser/statement.rs +++ b/compiler/noirc_frontend/src/parser/parser/statement.rs @@ -10,7 +10,7 @@ use crate::{ token::{Attribute, Keyword, Token, TokenKind}, }; -use super::Parser; +use super::{Parser, StatementDocComments}; impl<'a> Parser<'a> { pub(crate) fn parse_statement_or_error(&mut self) -> Statement { @@ -25,10 +25,38 @@ impl<'a> Parser<'a> { /// Statement = Attributes StatementKind ';'? pub(crate) fn parse_statement(&mut self) -> Option<(Statement, (Option, Span))> { loop { + let span_before_doc_comments = self.current_token_span; + let doc_comments = self.parse_outer_doc_comments(); + let span_after_doc_comments = self.current_token_span; + if doc_comments.is_empty() { + self.statement_doc_comments = None; + } else { + self.statement_doc_comments = Some(StatementDocComments { + doc_comments, + start_span: span_before_doc_comments, + end_span: span_after_doc_comments, + read: false, + }); + } + let attributes = self.parse_attributes(); let start_span = self.current_token_span; let kind = self.parse_statement_kind(attributes); + if let Some(statement_doc_comments) = &self.statement_doc_comments { + if !statement_doc_comments.read { + self.push_error( + ParserErrorReason::DocCommentDoesNotDocumentAnything, + Span::from( + statement_doc_comments.start_span.start() + ..statement_doc_comments.end_span.start(), + ), + ); + } + } + + self.statement_doc_comments = None; + let (semicolon_token, semicolon_span) = if self.at(Token::Semicolon) { let token = self.token.clone(); self.bump(); @@ -481,6 +509,17 @@ mod tests { assert!(!let_statement.comptime); } + #[test] + fn parses_let_statement_with_unsafe() { + let src = "/// Safety: doc comment + let x = unsafe { 1 };"; + let statement = parse_statement_no_errors(src); + let StatementKind::Let(let_statement) = statement.kind else { + panic!("Expected let statement"); + }; + assert_eq!(let_statement.pattern.to_string(), "x"); + } + #[test] fn parses_assert() { let src = "assert(true, \"good\")"; @@ -633,6 +672,20 @@ mod tests { }; } + #[test] + fn parses_assignment_with_unsafe() { + let src = "/// Safety: test + x = unsafe { 1 }"; + let statement = parse_statement_no_errors(src); + let StatementKind::Assign(assign) = statement.kind else { + panic!("Expected assign"); + }; + let LValue::Ident(ident) = assign.lvalue else { + panic!("Expected ident"); + }; + assert_eq!(ident.to_string(), "x"); + } + #[test] fn parses_op_assignment() { let src = "x += 1"; @@ -653,6 +706,16 @@ mod tests { assert_eq!(assign.to_string(), "x = (x >> 1)"); } + #[test] + fn parses_op_assignment_with_unsafe() { + let src = "/// Safety: comment + x += unsafe { 1 }"; + let statement = parse_statement_no_errors(src); + let StatementKind::Assign(_) = statement.kind else { + panic!("Expected assign"); + }; + } + #[test] fn parses_if_statement_followed_by_tuple() { // This shouldn't be parsed as a call diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index f1db0df9540..c657a839a33 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -3895,8 +3895,8 @@ fn errors_on_cyclic_globals() { fn warns_on_unneeded_unsafe() { let src = r#" fn main() { + /// Safety: test unsafe { - //@safety: test foo() } } @@ -3915,10 +3915,10 @@ fn warns_on_unneeded_unsafe() { fn warns_on_nested_unsafe() { let src = r#" fn main() { + /// Safety: test unsafe { - //@safety: test + /// Safety: test unsafe { - //@safety: test foo() } } diff --git a/compiler/noirc_frontend/src/tests/references.rs b/compiler/noirc_frontend/src/tests/references.rs index 7ae3974a125..956b2c5f05e 100644 --- a/compiler/noirc_frontend/src/tests/references.rs +++ b/compiler/noirc_frontend/src/tests/references.rs @@ -87,8 +87,8 @@ fn constrained_reference_to_unconstrained() { fn main(mut x: u32, y: pub u32) { let x_ref = &mut x; if x == 5 { + /// Safety: test context unsafe { - //@safety: test context mut_ref_input(x_ref, y); } } diff --git a/docs/docs/noir/concepts/unconstrained.md b/docs/docs/noir/concepts/unconstrained.md index 8e07d719f4b..26a5df0be3e 100644 --- a/docs/docs/noir/concepts/unconstrained.md +++ b/docs/docs/noir/concepts/unconstrained.md @@ -66,10 +66,8 @@ We can then run `u72_to_u8` as unconstrained brillig code in order to calculate ```rust fn main(num: u72) -> pub [u8; 8] { - let out = unsafe { - //@safety: 'out' is properly constrained below in 'assert(num == reconstructed_num);' - u72_to_u8(num) - }; + /// Safety: 'out' is properly constrained below in 'assert(num == reconstructed_num);' + let out = unsafe { u72_to_u8(num) }; let mut reconstructed_num: u72 = 0; for i in 0..8 { @@ -97,7 +95,7 @@ This ends up taking off another ~250 gates from our circuit! We've ended up with Note that in order to invoke unconstrained functions we need to wrap them in an `unsafe` block, to make it clear that the call is unconstrained. -Furthermore, a warning is emitted unless the `unsafe` block starts with a `//@safety: ...` comment explaining why it is fine to call the unconstrained function. +Furthermore, a warning is emitted unless the `unsafe` block is documented with a `/// Safety: ...` doc comment explaining why it is fine to call the unconstrained function. Note that either the `unsafe` block can be documented this way or the statement it exists in (like in the `let` example above). Generally we want to use brillig whenever there's something that's easy to verify but hard to compute within the circuit. For example, if you wanted to calculate a square root of a number it'll be a much better idea to calculate this in brillig and then assert that if you square the result you get back your number. diff --git a/noir_stdlib/src/array/check_shuffle.nr b/noir_stdlib/src/array/check_shuffle.nr index 828ac733290..327f0559810 100644 --- a/noir_stdlib/src/array/check_shuffle.nr +++ b/noir_stdlib/src/array/check_shuffle.nr @@ -42,10 +42,9 @@ pub(crate) fn check_shuffle(lhs: [T; N], rhs: [T; N]) where T: Eq, { + /// Safety: shuffle_indices is ensured to be a permutation of 0..N, and then + /// shuffle_indices is ensured to map lhs to rhs: assert(lhs[i] == rhs[shuffle_indices[i]]), for all i in 0..N unsafe { - /*@safety : shuffle_indices is ensured to be a permutation of 0..N, and then - shuffle_indices is ensured to map lhs to rhs: assert(lhs[i] == rhs[shuffle_indices[i]]), for all i in 0..N - */ let shuffle_indices = __get_shuffle_indices(lhs, rhs); for i in 0..N { diff --git a/noir_stdlib/src/array/mod.nr b/noir_stdlib/src/array/mod.nr index 1309a15d571..47dc3ca7bb9 100644 --- a/noir_stdlib/src/array/mod.nr +++ b/noir_stdlib/src/array/mod.nr @@ -184,11 +184,10 @@ where /// } /// ``` pub fn sort_via(self, ordering: fn[Env](T, T) -> bool) -> Self { + /// Safety: `sorted` array is checked to be: + /// a. a permutation of `input`'s elements + /// b. satisfying the predicate `ordering` unsafe { - /*@safety: `sorted` array is checked to be: - a. a permutation of `input`'s elements - b. satisfying the predicate `ordering` - */ let sorted = quicksort::quicksort(self, ordering); if !is_unconstrained() { diff --git a/noir_stdlib/src/collections/umap.nr b/noir_stdlib/src/collections/umap.nr index 27af14caa24..fb15d532bc5 100644 --- a/noir_stdlib/src/collections/umap.nr +++ b/noir_stdlib/src/collections/umap.nr @@ -113,10 +113,8 @@ impl UHashMap { H: Hasher, { // docs:end:contains_key - unsafe { - //@safety : unconstrained context - self.get(key) - } + /// Safety: unconstrained context + unsafe { self.get(key) } .is_some() } @@ -436,10 +434,8 @@ where // Not marked as deleted and has key-value. if equal & slot.is_valid() { let (key, value) = slot.key_value_unchecked(); - let other_value = unsafe { - //@safety : unconstrained context - other.get(key) - }; + /// Safety: unconstrained context + let other_value = unsafe { other.get(key) }; if other_value.is_none() { equal = false; diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index f3cbdca2762..a298a5d1e38 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -38,11 +38,10 @@ unconstrained fn lte_hint(x: Field, y: Field) -> bool { fn assert_gt_limbs(a: (Field, Field), b: (Field, Field)) { let (alo, ahi) = a; let (blo, bhi) = b; + /// Safety: borrow is enforced to be boolean due to its type. + /// if borrow is 0, it asserts that (alo > blo && ahi >= bhi) + /// if borrow is 1, it asserts that (alo <= blo && ahi > bhi) unsafe { - /*@safety: borrow is enforced to be boolean due to its type. - if borrow is 0, it asserts that (alo > blo && ahi >= bhi) - if borrow is 1, it asserts that (alo <= blo && ahi > bhi) - */ let borrow = lte_hint(alo, blo); let rlo = alo - blo - 1 + (borrow as Field) * TWO_POW_128; @@ -58,8 +57,8 @@ pub fn decompose(x: Field) -> (Field, Field) { if is_unconstrained() { compute_decomposition(x) } else { + /// Safety: decomposition is properly checked below unsafe { - /*@safety: decomposition is properly checked below*/ // Take hints of the decomposition let (xlo, xhi) = decompose_hint(x); @@ -80,10 +79,8 @@ pub fn decompose(x: Field) -> (Field, Field) { pub fn assert_gt(a: Field, b: Field) { if is_unconstrained() { assert( - unsafe { - //@safety: already unconstrained - field_less_than(b, a) - }, + /// Safety: already unconstrained + unsafe { field_less_than(b, a) }, ); } else { // Decompose a and b @@ -101,15 +98,15 @@ pub fn assert_lt(a: Field, b: Field) { pub fn gt(a: Field, b: Field) -> bool { if is_unconstrained() { + /// Safety: unsafe in unconstrained unsafe { - //@safety: unsafe in unconstrained field_less_than(b, a) } } else if a == b { false } else { + /// Safety: Take a hint of the comparison and verify it unsafe { - //@safety: Take a hint of the comparison and verify it if field_less_than(a, b) { assert_gt(b, a); false diff --git a/noir_stdlib/src/field/mod.nr b/noir_stdlib/src/field/mod.nr index 7e5ad97d64f..d0760447ff1 100644 --- a/noir_stdlib/src/field/mod.nr +++ b/noir_stdlib/src/field/mod.nr @@ -237,8 +237,8 @@ pub fn bytes32_to_field(bytes32: [u8; 32]) -> Field { fn lt_fallback(x: Field, y: Field) -> bool { if is_unconstrained() { + /// Safety: unconstrained context unsafe { - //@safety : unconstrained context field_less_than(x, y) } } else { diff --git a/noir_stdlib/src/hash/mod.nr b/noir_stdlib/src/hash/mod.nr index 89f6d2a1363..104368b50fa 100644 --- a/noir_stdlib/src/hash/mod.nr +++ b/noir_stdlib/src/hash/mod.nr @@ -96,10 +96,8 @@ fn __derive_generators( // does not assert the limbs are 128 bits // does not assert the decomposition does not overflow the EmbeddedCurveScalar fn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar { - let (xlo, xhi) = unsafe { - //@safety : xlo and xhi decomposition is checked below - crate::field::bn254::decompose_hint(scalar) - }; + /// Safety: xlo and xhi decomposition is checked below + let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) }; // Check that the decomposition is correct assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi); EmbeddedCurveScalar { lo: xlo, hi: xhi } diff --git a/noir_stdlib/src/hash/sha256.nr b/noir_stdlib/src/hash/sha256.nr index a4e21304912..fce263ce25d 100644 --- a/noir_stdlib/src/hash/sha256.nr +++ b/noir_stdlib/src/hash/sha256.nr @@ -74,10 +74,9 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { let mut msg_byte_ptr = 0; for i in 0..num_blocks { let msg_start = BLOCK_SIZE * i; - let (new_msg_block, new_msg_byte_ptr) = unsafe { - /*@safety : the msg_block is checked below in verify_msg_block*/ - build_msg_block(msg, message_size, msg_start) - }; + /// Safety: the msg_block is checked below in verify_msg_block + let (new_msg_block, new_msg_byte_ptr) = + unsafe { build_msg_block(msg, message_size, msg_start) }; if msg_start < message_size { msg_block = new_msg_block; @@ -106,10 +105,9 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { // or our message cannot be evenly split into blocks. if modulo != 0 { let msg_start = BLOCK_SIZE * num_blocks; - let (new_msg_block, new_msg_byte_ptr) = unsafe { - //@safety : the msg_block is checked below in verify_msg_block - build_msg_block(msg, message_size, msg_start) - }; + /// Safety: the msg_block is checked below in verify_msg_block + let (new_msg_block, new_msg_byte_ptr) = + unsafe { build_msg_block(msg, message_size, msg_start) }; if msg_start < message_size { msg_block = new_msg_block; @@ -150,10 +148,8 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> HASH { msg_byte_ptr = 0; } - msg_block = unsafe { - //@safety : the msg_len is checked below in verify_msg_len - attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) - }; + /// Safety: the msg_len is checked below in verify_msg_len + msg_block = unsafe { attach_len_to_msg_block(msg_block, msg_byte_ptr, message_size) }; if !is_unconstrained() { verify_msg_len(msg_block, last_block, msg_byte_ptr, message_size); @@ -805,10 +801,9 @@ mod tests { 101, 115, 46, 48, ]; assert_eq(input.len(), 22); - let (msg_block, msg_byte_ptr) = unsafe { - //@safety : testing context - build_msg_block(input, input.len(), 0) - }; + + /// Safety: testing context + let (msg_block, msg_byte_ptr) = unsafe { build_msg_block(input, input.len(), 0) }; assert_eq(msg_byte_ptr, input.len()); assert_eq(msg_block[0], make_item(input[0], input[1], input[2], input[3])); assert_eq(msg_block[1], make_item(input[4], input[5], input[6], input[7])); @@ -825,10 +820,8 @@ mod tests { 108, 97, 105, 110, 59, 32, 99, 104, 97, 114, 115, 101, 116, ]; assert_eq(input.len(), 68); - let (msg_block, msg_byte_ptr) = unsafe { - //@safety : testing context - build_msg_block(input, input.len(), 64) - }; + /// Safety: test context + let (msg_block, msg_byte_ptr) = unsafe { build_msg_block(input, input.len(), 64) }; assert_eq(msg_byte_ptr, 4); assert_eq(msg_block[0], make_item(input[64], input[65], input[66], input[67])); assert_eq(msg_block[1], 0); @@ -841,10 +834,8 @@ mod tests { 1919905082, 1131376244, 1701737517, 1417244773, 978151789, 1697470053, 1920166255, 1849316213, 1651139939, ]; - let msg_block = unsafe { - //@safety : testing context - attach_len_to_msg_block(input, 1, 448) - }; + /// Safety: testing context + let msg_block = unsafe { attach_len_to_msg_block(input, 1, 448) }; assert_eq(msg_block[0], ((1 << 7) as u32) * 256 * 256 * 256); assert_eq(msg_block[1], 0); assert_eq(msg_block[15], 3584); diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index cdc82b20509..2e743822ffb 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -40,15 +40,15 @@ unconstrained fn print_unconstrained(with_newline: bool, input: T) { } pub fn println(input: T) { + /// Safety: a print statement cannot be constrained unsafe { - //@safety: a print statement cannot be constrained print_unconstrained(true, input); } } pub fn print(input: T) { + /// Safety: a print statement cannot be constrained unsafe { - //@safety: a print statement cannot be constrained print_unconstrained(false, input); } } diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index a6bb4630e81..7538b26dc44 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -669,10 +669,10 @@ comptime fn new_unary_op(op: UnaryOp, rhs: Expr) -> Expr { comptime fn new_unsafe(exprs: [Expr]) -> Expr { let exprs = join_expressions(exprs, quote { ; }); - quote { unsafe { - //@safety: generated by macro - $exprs - }} + quote { + /// Safety: generated by macro + unsafe { $exprs } + } .as_expr() .unwrap() } diff --git a/noir_stdlib/src/uint128.nr b/noir_stdlib/src/uint128.nr index ffd6d60b6ca..9aa01e1ea52 100644 --- a/noir_stdlib/src/uint128.nr +++ b/noir_stdlib/src/uint128.nr @@ -104,16 +104,9 @@ impl U128 { if ascii < 58 { ascii - 48 } else { - let ascii = ascii - + 32 - * ( - unsafe { - /*@safety : optionally adds 32 and then check (below) the result is in 'a..f' range - This enforces that the input is in either 'A..F' or 'a..f' range - */ - U128::uconstrained_check_is_upper_ascii(ascii) as u8 - } - ); + /// Safety: optionally adds 32 and then check (below) the result is in 'a..f' range + let ascii = + ascii + 32 * (unsafe { U128::uconstrained_check_is_upper_ascii(ascii) as u8 }); assert(ascii >= 97); // enforce >= 'a' assert(ascii <= 102); // enforce <= 'f' ascii - 87 @@ -220,10 +213,9 @@ impl Mul for U128 { impl Div for U128 { fn div(self: Self, b: U128) -> U128 { + /// Safety: euclidian division is asserted to be correct: assert(a == b * q + r); and assert(r < b); + /// Furthermore, U128 addition and multiplication ensures that b * q + r does not overflow unsafe { - /*@safety : euclidian division is asserted to be correct: assert(a == b * q + r); and assert(r < b); - Furthermore, U128 addition and multiplication ensures that b * q + r does not overflow - */ let (q, r) = self.unconstrained_div(b); let a = b * q + r; assert_eq(self, a); @@ -235,8 +227,8 @@ impl Div for U128 { impl Rem for U128 { fn rem(self: Self, b: U128) -> U128 { + /// Safety: cf div() above unsafe { - //@safety : cf div() above let (q, r) = self.unconstrained_div(b); let a = b * q + r; assert_eq(self, a); @@ -463,8 +455,8 @@ mod tests { let b = U128::from_u64s_le(0x0, 0xfffffffffffffffe); let c = U128::one(); let d = U128::from_u64s_le(0x0, 0x1); + /// Safety: testing context unsafe { - //@safety: testing context let (q, r) = a.unconstrained_div(b); assert_eq(q, c); assert_eq(r, d); @@ -473,15 +465,15 @@ mod tests { let a = U128::from_u64s_le(2, 0); let b = U128::one(); // Check the case where a is a multiple of b + /// Safety: testing context unsafe { - //@safety: testing context let (c, d) = a.unconstrained_div(b); assert_eq((c, d), (a, U128::zero())); } // Check where b is a multiple of a + /// Safety: testing context unsafe { - //@safety: testing context let (c, d) = b.unconstrained_div(a); assert_eq((c, d), (U128::zero(), b)); } @@ -489,16 +481,16 @@ mod tests { // Dividing by zero returns 0,0 let a = U128::from_u64s_le(0x1, 0x0); let b = U128::zero(); + /// Safety: testing context unsafe { - //@safety: testing context let (c, d) = a.unconstrained_div(b); assert_eq((c, d), (U128::zero(), U128::zero())); } // Dividing 1<<127 by 1<<127 (special case) let a = U128::from_u64s_le(0x0, pow63 as u64); let b = U128::from_u64s_le(0x0, pow63 as u64); + /// Safety: testing context unsafe { - //@safety: testing context let (c, d) = a.unconstrained_div(b); assert_eq((c, d), (U128::one(), U128::zero())); } diff --git a/test_programs/compile_failure/brillig_mut_ref_from_acir/src/main.nr b/test_programs/compile_failure/brillig_mut_ref_from_acir/src/main.nr index 29431005c29..d4450ec62b1 100644 --- a/test_programs/compile_failure/brillig_mut_ref_from_acir/src/main.nr +++ b/test_programs/compile_failure/brillig_mut_ref_from_acir/src/main.nr @@ -3,9 +3,7 @@ unconstrained fn mut_ref_identity(value: &mut Field) -> Field { } fn main(mut x: Field, y: pub Field) { - let returned_x = unsafe { - //@safety: testing context - mut_ref_identity(&mut x) - }; + /// Safety: testing context + let returned_x = unsafe { mut_ref_identity(&mut x) }; assert(returned_x == x); } diff --git a/test_programs/compile_failure/regression_5008/src/main.nr b/test_programs/compile_failure/regression_5008/src/main.nr index be1adb119aa..5155900734c 100644 --- a/test_programs/compile_failure/regression_5008/src/main.nr +++ b/test_programs/compile_failure/regression_5008/src/main.nr @@ -2,7 +2,7 @@ struct Bar { value: Field, } -struct Foo{ +struct Foo { bar: &mut Bar, } @@ -13,8 +13,6 @@ impl Foo { fn main() { let foo = Foo { bar: &mut Bar { value: 0 } }; - unsafe { - //@safety: testing context - foo.crash_fn() - }; + /// Safety: testing context + unsafe { foo.crash_fn() }; } diff --git a/test_programs/compile_failure/unconstrained_ref/src/main.nr b/test_programs/compile_failure/unconstrained_ref/src/main.nr index 282d598b484..23dc1d66673 100644 --- a/test_programs/compile_failure/unconstrained_ref/src/main.nr +++ b/test_programs/compile_failure/unconstrained_ref/src/main.nr @@ -4,8 +4,6 @@ unconstrained fn uncon_ref() -> &mut Field { } fn main() { - let e = unsafe { - //@safety: testing context - uncon_ref() - }; + /// Safety: testing context + let e = unsafe { uncon_ref() }; } diff --git a/test_programs/compile_success_empty/acir_inside_brillig_recursion/src/main.nr b/test_programs/compile_success_empty/acir_inside_brillig_recursion/src/main.nr index b4cc69bb00a..12c663b2705 100644 --- a/test_programs/compile_success_empty/acir_inside_brillig_recursion/src/main.nr +++ b/test_programs/compile_success_empty/acir_inside_brillig_recursion/src/main.nr @@ -1,6 +1,6 @@ fn main() { + /// Safety: testing context unsafe { - //@safety: testing context assert_eq(fibonacci(3), fibonacci_hint(3)); } } diff --git a/test_programs/compile_success_empty/brillig_cast/src/main.nr b/test_programs/compile_success_empty/brillig_cast/src/main.nr index 581ca8dc16a..d7d0b1b8fa5 100644 --- a/test_programs/compile_success_empty/brillig_cast/src/main.nr +++ b/test_programs/compile_success_empty/brillig_cast/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested are cast operations on brillig fn main() { + /// Safety: testing context unsafe { - //@safety: testing context bool_casts(); field_casts(); uint_casts(); diff --git a/test_programs/compile_success_empty/brillig_field_binary_operations/src/main.nr b/test_programs/compile_success_empty/brillig_field_binary_operations/src/main.nr index 15f1b23853d..f55beb6d1a8 100644 --- a/test_programs/compile_success_empty/brillig_field_binary_operations/src/main.nr +++ b/test_programs/compile_success_empty/brillig_field_binary_operations/src/main.nr @@ -1,7 +1,7 @@ // Tests arithmetic operations on fields fn main() { + /// Safety: testing context unsafe { - //@safety: testing context let x = 4; let y = 2; assert((x + y) == add(x, y)); diff --git a/test_programs/compile_success_empty/brillig_integer_binary_operations/src/main.nr b/test_programs/compile_success_empty/brillig_integer_binary_operations/src/main.nr index 4ee04807355..0e00f25e5bb 100644 --- a/test_programs/compile_success_empty/brillig_integer_binary_operations/src/main.nr +++ b/test_programs/compile_success_empty/brillig_integer_binary_operations/src/main.nr @@ -3,8 +3,8 @@ fn main() { let x: u32 = 6; let y: u32 = 2; + /// Safety: testing context unsafe { - //@safety: testing context assert((x + y) == add(x, y)); assert((x - y) == sub(x, y)); diff --git a/test_programs/compile_success_empty/brillig_modulo/src/main.nr b/test_programs/compile_success_empty/brillig_modulo/src/main.nr index 47f2466f453..841d7d2dfca 100644 --- a/test_programs/compile_success_empty/brillig_modulo/src/main.nr +++ b/test_programs/compile_success_empty/brillig_modulo/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested is modulo operations on brillig fn main() { + /// Safety: testing context unsafe { - //@safety: testing context assert(modulo(47, 3) == 2); assert(modulo(2, 3) == 2); assert(signed_modulo(5, 3) == 2); diff --git a/test_programs/compile_success_empty/brillig_slice_input/src/main.nr b/test_programs/compile_success_empty/brillig_slice_input/src/main.nr index 41bd2d8c3ef..c43c5fae162 100644 --- a/test_programs/compile_success_empty/brillig_slice_input/src/main.nr +++ b/test_programs/compile_success_empty/brillig_slice_input/src/main.nr @@ -16,15 +16,15 @@ unconstrained fn sum_slice(slice: [[Point; 2]]) -> Field { fn main() { let mut slice = &[]; slice = slice.push_back([Point { x: 13, y: 14 }, Point { x: 20, y: 8 }]); + /// Safety: testing context unsafe { - //@safety: testing context let brillig_sum = sum_slice(slice); assert_eq(brillig_sum, 55); } slice = slice.push_back([Point { x: 15, y: 5 }, Point { x: 12, y: 13 }]); + /// Safety: testing context unsafe { - //@safety: testing context let brillig_sum = sum_slice(slice); assert_eq(brillig_sum, 100); } diff --git a/test_programs/compile_success_empty/is_unconstrained/src/main.nr b/test_programs/compile_success_empty/is_unconstrained/src/main.nr index dddf2dfec2e..856040b2274 100644 --- a/test_programs/compile_success_empty/is_unconstrained/src/main.nr +++ b/test_programs/compile_success_empty/is_unconstrained/src/main.nr @@ -9,8 +9,8 @@ unconstrained fn unconstrained_intermediate() { } fn main() { + /// Safety: testing context unsafe { - //@safety: testing context unconstrained_intermediate(); } check(false); diff --git a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr index 9e4439e67cd..0572192225c 100644 --- a/test_programs/compile_success_empty/macros_in_comptime/src/main.nr +++ b/test_programs/compile_success_empty/macros_in_comptime/src/main.nr @@ -6,10 +6,7 @@ global three_field: Field = 3; fn main() { comptime { - unsafe { - //@safety: testing context - foo::(5) - }; + foo::(5); submodule::bar(); } } diff --git a/test_programs/compile_success_no_bug/check_unconstrained_regression/src/main.nr b/test_programs/compile_success_no_bug/check_unconstrained_regression/src/main.nr index b8c4137aa74..174b68fd162 100644 --- a/test_programs/compile_success_no_bug/check_unconstrained_regression/src/main.nr +++ b/test_programs/compile_success_no_bug/check_unconstrained_regression/src/main.nr @@ -1,24 +1,26 @@ -struct Trigger{ +struct Trigger { x: u32, y: Field, - z: [Field;3], + z: [Field; 3], } -struct ResultType{ +struct ResultType { a: u32, b: Field, - c: [Field;3], + c: [Field; 3], } unconstrained fn convert(trigger: Trigger) -> ResultType { - let result= ResultType { a: trigger.x + 1, b: trigger.y - 1 + trigger.z[2], c: [trigger.z[0], 0, trigger.z[1]] }; + let result = ResultType { + a: trigger.x + 1, + b: trigger.y - 1 + trigger.z[2], + c: [trigger.z[0], 0, trigger.z[1]], + }; result } impl Trigger { fn execute(self) -> ResultType { - let result = unsafe { - //@safety: testing context - convert(self) - }; + /// Safety: testing context + let result = unsafe { convert(self) }; assert(result.a == self.x + 1); assert(result.b == self.y - 1 + self.z[2]); assert(result.c[1] == 0); diff --git a/test_programs/compile_success_with_bug/underconstrained_value_detector_5425/src/main.nr b/test_programs/compile_success_with_bug/underconstrained_value_detector_5425/src/main.nr index 7047be3a577..22e2bc0b49d 100644 --- a/test_programs/compile_success_with_bug/underconstrained_value_detector_5425/src/main.nr +++ b/test_programs/compile_success_with_bug/underconstrained_value_detector_5425/src/main.nr @@ -9,8 +9,8 @@ unconstrained fn maximum_price(options: [u32; 3]) -> u32 { } fn main(sandwiches: pub [u32; 3], drinks: pub [u32; 3], snacks: pub [u32; 3], best_value: u32) { + /// Safety: testing context unsafe { - //@safety: testing context let meal_deal_cost: u32 = 390; let most_expensive_sandwich = maximum_price(sandwiches); let mut sandwich_exists = false; diff --git a/test_programs/execution_failure/brillig_assert_fail/src/main.nr b/test_programs/execution_failure/brillig_assert_fail/src/main.nr index 4ca70baae2e..18e6422361c 100644 --- a/test_programs/execution_failure/brillig_assert_fail/src/main.nr +++ b/test_programs/execution_failure/brillig_assert_fail/src/main.nr @@ -1,13 +1,9 @@ // Tests a very simple program. -// +// // The features being tested is using assert on brillig fn main(x: Field) { - assert( - 1 == unsafe { - //@safety: testing context - conditional(x as bool) - } - ); + /// Safety: testing context + assert(1 == unsafe { conditional(x as bool) }); } unconstrained fn conditional(x: bool) -> Field { diff --git a/test_programs/execution_failure/brillig_assert_msg_runtime/src/main.nr b/test_programs/execution_failure/brillig_assert_msg_runtime/src/main.nr index d726e699bab..9c07660217b 100644 --- a/test_programs/execution_failure/brillig_assert_msg_runtime/src/main.nr +++ b/test_programs/execution_failure/brillig_assert_msg_runtime/src/main.nr @@ -1,10 +1,6 @@ fn main(x: Field) { - assert( - 1 == unsafe { - //@safety: testing context - conditional(x) - } - ); + /// Safety: testing context + assert(1 == unsafe { conditional(x) }); } unconstrained fn conditional(x: Field) -> Field { diff --git a/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr b/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr index b87744399c6..bbb6f8ff422 100644 --- a/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr +++ b/test_programs/execution_failure/fold_nested_brillig_assert_fail/src/main.nr @@ -1,5 +1,5 @@ // Tests a very simple program. -// +// // The features being tested is using assert on brillig that is triggered through nested ACIR calls. // We want to make sure we get a call stack from the original call in main to the failed assert. fn main(x: Field) { @@ -14,8 +14,8 @@ fn fold_conditional_wrapper(x: bool) -> Field { #[fold] fn fold_conditional(x: bool) -> Field { + /// Safety: testing context unsafe { - //@safety: testing context conditional_wrapper(x) } } diff --git a/test_programs/execution_failure/regression_5202/src/main.nr b/test_programs/execution_failure/regression_5202/src/main.nr index a270a9fccad..0c3a9693958 100644 --- a/test_programs/execution_failure/regression_5202/src/main.nr +++ b/test_programs/execution_failure/regression_5202/src/main.nr @@ -2,7 +2,11 @@ trait ToField { fn to_field(self) -> Field; } -impl ToField for bool { fn to_field(self) -> Field { self as Field } } +impl ToField for bool { + fn to_field(self) -> Field { + self as Field + } +} unconstrained fn get_unconstrained_option() -> Option { Option::some(13) @@ -13,22 +17,17 @@ unconstrained fn should_i_assert() -> bool { } fn get_magical_boolean() -> bool { - let option = unsafe { - //@safety: testing context - get_unconstrained_option() - }; + /// Safety: testing context + let option = unsafe { get_unconstrained_option() }; let pre_assert = option.is_some().to_field(); - if unsafe { - //@safety: testing context - should_i_assert() - } { + /// Safety: testing context + if unsafe { should_i_assert() } { // Note that `should_i_assert` is unconstrained, so Noir should not be able to infer // any behavior from the contents of this block. In this case it is actually false, so the // assertion below is not even executed (if it did it'd fail since the values are not equal). - - assert_eq(option, Option::some(42)); /// <- this seems to be the trigger for the bug + assert_eq(option, Option::some(42)); // <- this seems to be the trigger for the bug } // In my testing, the `option` value exhibits weird behavior from this point on, as if it had been mutated diff --git a/test_programs/execution_success/aes128_encrypt/src/main.nr b/test_programs/execution_success/aes128_encrypt/src/main.nr index 243984a8300..11f9512444e 100644 --- a/test_programs/execution_success/aes128_encrypt/src/main.nr +++ b/test_programs/execution_success/aes128_encrypt/src/main.nr @@ -29,15 +29,11 @@ fn main(inputs: str<12>, iv: str<16>, key: str<16>, output: str<32>) { let result: [u8; 16] = std::aes128::aes128_encrypt(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()); - let output_bytes: [u8; 16] = unsafe { - //@safety: testing context - decode_hex(output) - }; + /// Safety: testing context + let output_bytes: [u8; 16] = unsafe { decode_hex(output) }; assert(result == output_bytes); - let unconstrained_result = unsafe { - //@safety: testing context - cipher(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()) - }; + /// Safety: testing context + let unconstrained_result = unsafe { cipher(inputs.as_bytes(), iv.as_bytes(), key.as_bytes()) }; assert(unconstrained_result == output_bytes); } diff --git a/test_programs/execution_success/array_to_slice_constant_length/src/main.nr b/test_programs/execution_success/array_to_slice_constant_length/src/main.nr index 425c48c21f1..1d29db4973a 100644 --- a/test_programs/execution_success/array_to_slice_constant_length/src/main.nr +++ b/test_programs/execution_success/array_to_slice_constant_length/src/main.nr @@ -4,8 +4,8 @@ unconstrained fn return_array(val: Field) -> [Field; 1] { } fn main(val: Field) { + /// Safety: testing context unsafe { - //@safety: testing context let array = return_array(val); assert_constant(array.as_slice().len()); } diff --git a/test_programs/execution_success/bigint/src/main.nr b/test_programs/execution_success/bigint/src/main.nr index 65cf990dcaf..2095c92349a 100644 --- a/test_programs/execution_success/bigint/src/main.nr +++ b/test_programs/execution_success/bigint/src/main.nr @@ -17,8 +17,8 @@ fn main(mut x: [u8; 5], y: [u8; 5]) { let c = if x[0] != 0 { test_unconstrained1(a, b) } else { + /// Safety: testing context unsafe { - //@safety: testing context test_unconstrained2(a, b) } }; diff --git a/test_programs/execution_success/brillig_acir_as_brillig/src/main.nr b/test_programs/execution_success/brillig_acir_as_brillig/src/main.nr index bcb995591c7..a327dfd7533 100644 --- a/test_programs/execution_success/brillig_acir_as_brillig/src/main.nr +++ b/test_programs/execution_success/brillig_acir_as_brillig/src/main.nr @@ -1,6 +1,6 @@ fn main(x: u32) { + /// Safety: testing context unsafe { - //@safety: testing context assert(entry_point(x) == 2); swap_entry_point(x, x + 1); assert(deep_entry_point(x) == 4); diff --git a/test_programs/execution_success/brillig_arrays/src/main.nr b/test_programs/execution_success/brillig_arrays/src/main.nr index b4cd13e1091..f0524842ac6 100644 --- a/test_programs/execution_success/brillig_arrays/src/main.nr +++ b/test_programs/execution_success/brillig_arrays/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested are array reads and writes fn main(x: [Field; 3]) { + /// Safety: testing context unsafe { - //@safety: testing context read_array(x); read_write_array(x); } diff --git a/test_programs/execution_success/brillig_blake2s/src/main.nr b/test_programs/execution_success/brillig_blake2s/src/main.nr index 58f45e8d667..7e567b84139 100644 --- a/test_programs/execution_success/brillig_blake2s/src/main.nr +++ b/test_programs/execution_success/brillig_blake2s/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested is blake2s in brillig fn main(x: [u8; 5], result: [u8; 32]) { + /// Safety: testing context unsafe { - //@safety: testing context assert(blake2s(x) == result); } } diff --git a/test_programs/execution_success/brillig_calls_array/src/main.nr b/test_programs/execution_success/brillig_calls_array/src/main.nr index 8d5e01dd7c4..b27eb30da17 100644 --- a/test_programs/execution_success/brillig_calls_array/src/main.nr +++ b/test_programs/execution_success/brillig_calls_array/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested is brillig calls passing arrays around fn main(x: [u32; 3]) { + /// Safety: testing context unsafe { - //@safety: testing context assert(entry_point(x) == 9); another_entry_point(x); } diff --git a/test_programs/execution_success/brillig_calls_conditionals/src/main.nr b/test_programs/execution_success/brillig_calls_conditionals/src/main.nr index e03f04a0cbc..31b70cb12cf 100644 --- a/test_programs/execution_success/brillig_calls_conditionals/src/main.nr +++ b/test_programs/execution_success/brillig_calls_conditionals/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested is brillig calls with conditionals fn main(x: [u32; 3]) { + /// Safety: testing context unsafe { - //@safety: testing context assert(entry_point(x[0]) == 7); assert(entry_point(x[1]) == 8); assert(entry_point(x[2]) == 9); diff --git a/test_programs/execution_success/brillig_conditional/src/main.nr b/test_programs/execution_success/brillig_conditional/src/main.nr index 5934f982f88..024ee52d5af 100644 --- a/test_programs/execution_success/brillig_conditional/src/main.nr +++ b/test_programs/execution_success/brillig_conditional/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested is basic conditonal on brillig fn main(x: Field) { + /// Safety: testing context unsafe { - //@safety: testing context assert(4 == conditional(x == 1)); } } diff --git a/test_programs/execution_success/brillig_fns_as_values/src/main.nr b/test_programs/execution_success/brillig_fns_as_values/src/main.nr index b56542fd0ae..ff1c36c9ddf 100644 --- a/test_programs/execution_success/brillig_fns_as_values/src/main.nr +++ b/test_programs/execution_success/brillig_fns_as_values/src/main.nr @@ -3,8 +3,8 @@ struct MyStruct { } fn main(x: u32) { + /// Safety: testing context unsafe { - //@safety: testing context assert(wrapper(increment, x) == x + 1); assert(wrapper(increment_acir, x) == x + 1); assert(wrapper(decrement, x) == x - 1); diff --git a/test_programs/execution_success/brillig_identity_function/src/main.nr b/test_programs/execution_success/brillig_identity_function/src/main.nr index 7bf584579d3..b676c46120e 100644 --- a/test_programs/execution_success/brillig_identity_function/src/main.nr +++ b/test_programs/execution_success/brillig_identity_function/src/main.nr @@ -6,8 +6,8 @@ struct myStruct { // // The features being tested is the identity function in Brillig fn main(x: Field) { + /// Safety: testing context unsafe { - //@safety: testing context assert(x == identity(x)); // TODO: add support for array comparison let arr = identity_array([x, x]); diff --git a/test_programs/execution_success/brillig_nested_arrays/src/main.nr b/test_programs/execution_success/brillig_nested_arrays/src/main.nr index e97db35f800..feb5433738f 100644 --- a/test_programs/execution_success/brillig_nested_arrays/src/main.nr +++ b/test_programs/execution_success/brillig_nested_arrays/src/main.nr @@ -28,8 +28,8 @@ unconstrained fn create_and_assert_inside_brillig(x: Field, y: Field) { } fn main(x: Field, y: Field) { + /// Safety: testing context unsafe { - //@safety: testing context let header = Header { params: [1, 2, 3] }; let note0 = MyNote { array: [1, 2], plain: 3, header }; let note1 = MyNote { array: [4, 5], plain: 6, header }; diff --git a/test_programs/execution_success/brillig_not/src/main.nr b/test_programs/execution_success/brillig_not/src/main.nr index 38641f5ee5f..6dc91f86127 100644 --- a/test_programs/execution_success/brillig_not/src/main.nr +++ b/test_programs/execution_success/brillig_not/src/main.nr @@ -2,8 +2,8 @@ // // The features being tested is not instruction on brillig fn main(x: Field, y: Field) { + /// Safety: testing context unsafe { - //@safety: testing context assert(false == not_operator(x as bool)); assert(true == not_operator(y as bool)); } diff --git a/test_programs/execution_success/brillig_oracle/src/main.nr b/test_programs/execution_success/brillig_oracle/src/main.nr index e59c908fd6f..cae174edb99 100644 --- a/test_programs/execution_success/brillig_oracle/src/main.nr +++ b/test_programs/execution_success/brillig_oracle/src/main.nr @@ -3,8 +3,8 @@ use std::test::OracleMock; // Tests oracle usage in brillig/unconstrained functions fn main(_x: Field) { + /// Safety: testing context unsafe { - //@safety: testing context let size = 20; // TODO: Add a method along the lines of `(0..size).to_array()`. let mut mock_oracle_response = [0; 20]; diff --git a/test_programs/execution_success/brillig_recursion/src/main.nr b/test_programs/execution_success/brillig_recursion/src/main.nr index fa048c30abe..e7140ffa06c 100644 --- a/test_programs/execution_success/brillig_recursion/src/main.nr +++ b/test_programs/execution_success/brillig_recursion/src/main.nr @@ -2,8 +2,8 @@ // // The feature being tested is brillig recursion fn main(x: u32) { + /// Safety: testing context unsafe { - //@safety: testing context assert(fibonacci(x) == 55); } } diff --git a/test_programs/execution_success/brillig_uninitialized_arrays/src/main.nr b/test_programs/execution_success/brillig_uninitialized_arrays/src/main.nr index 839ac489f2d..39a13440ca9 100644 --- a/test_programs/execution_success/brillig_uninitialized_arrays/src/main.nr +++ b/test_programs/execution_success/brillig_uninitialized_arrays/src/main.nr @@ -1,6 +1,6 @@ fn main(x: Field, y: Field) -> pub Field { + /// Safety: testing context unsafe { - //@safety: testing context let notes = create_notes(x, y); sum_x(notes, x, y) } diff --git a/test_programs/execution_success/global_consts/src/main.nr b/test_programs/execution_success/global_consts/src/main.nr index 70423810327..9f84af35cba 100644 --- a/test_programs/execution_success/global_consts/src/main.nr +++ b/test_programs/execution_success/global_consts/src/main.nr @@ -25,10 +25,7 @@ unconstrained fn calculate_global_value() -> Field { } // Regression test for https://github.com/noir-lang/noir/issues/4318 -global CALCULATED_GLOBAL: Field = unsafe { - //@safety: testing context - calculate_global_value() -}; +global CALCULATED_GLOBAL: Field = calculate_global_value(); fn main( a: [Field; M + N - N], diff --git a/test_programs/execution_success/hint_black_box/src/main.nr b/test_programs/execution_success/hint_black_box/src/main.nr index d53cf335878..abceadb07ff 100644 --- a/test_programs/execution_success/hint_black_box/src/main.nr +++ b/test_programs/execution_success/hint_black_box/src/main.nr @@ -23,10 +23,8 @@ fn main(a: u32, b: u32) { //assert_eq(slice_sum(black_box(arr.as_slice())), b); // But we can pass a blackboxed slice to Brillig. - let s = unsafe { - //@safety: testing context - brillig_slice_sum(black_box(arr.as_slice())) - }; + /// Safety: testing context + let s = unsafe { brillig_slice_sum(black_box(arr.as_slice())) }; assert_eq(s, b); let mut d = b; diff --git a/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr b/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr index aec0ba3be33..f724d0cdedd 100644 --- a/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr +++ b/test_programs/execution_success/nested_arrays_from_brillig/src/main.nr @@ -20,10 +20,8 @@ unconstrained fn create_inside_brillig(values: [Field; 6]) -> [MyNote; 2] { } fn main(values: [Field; 6]) { - let notes = unsafe { - //@safety: testing context - create_inside_brillig(values) - }; + /// Safety: testing context + let notes = unsafe { create_inside_brillig(values) }; assert(access_nested(notes) == (2 + 4 + 3 + 1)); } diff --git a/test_programs/execution_success/reference_only_used_as_alias/src/main.nr b/test_programs/execution_success/reference_only_used_as_alias/src/main.nr index c310f052fce..3bbf1cf9ccb 100644 --- a/test_programs/execution_success/reference_only_used_as_alias/src/main.nr +++ b/test_programs/execution_success/reference_only_used_as_alias/src/main.nr @@ -61,8 +61,8 @@ where Event: EventInterface, { |e: Event| { + /// Safety: testing context unsafe { - //@safety: testing context func(context.a); } emit_with_keys(context, randomness, e, compute); diff --git a/test_programs/execution_success/regression_5435/src/main.nr b/test_programs/execution_success/regression_5435/src/main.nr index 4e90002e2a2..a83ca055aab 100644 --- a/test_programs/execution_success/regression_5435/src/main.nr +++ b/test_programs/execution_success/regression_5435/src/main.nr @@ -3,10 +3,8 @@ fn main(input: Field, enable: bool) { let hash = no_predicate_function(input); // `EnableSideEffects` instruction from above instruction leaks out and removes the predicate from this call, // resulting in execution failure. - unsafe { - //@safety: testing context - fail(hash) - }; + /// Safety: testing context + unsafe { fail(hash) }; } } diff --git a/test_programs/execution_success/regression_6451/src/main.nr b/test_programs/execution_success/regression_6451/src/main.nr index 192e09fe3f5..edef71020e4 100644 --- a/test_programs/execution_success/regression_6451/src/main.nr +++ b/test_programs/execution_success/regression_6451/src/main.nr @@ -10,10 +10,8 @@ fn main(x: Field) { value.assert_max_bit_size::<1>(); // Regression test for #6447 (Aztec Packages issue #9488) - let y = unsafe { - //@safety: testing context - empty(x + 1) - }; + /// Safety: testing context + let y = unsafe { empty(x + 1) }; let z = y + x + 1; let z1 = z + y; assert(z + z1 != 3); diff --git a/test_programs/execution_success/regression_6674_3/src/main.nr b/test_programs/execution_success/regression_6674_3/src/main.nr index a0f2d0668d5..57a3df5fcac 100644 --- a/test_programs/execution_success/regression_6674_3/src/main.nr +++ b/test_programs/execution_success/regression_6674_3/src/main.nr @@ -166,10 +166,7 @@ pub unconstrained fn sort_by_counter_desc(array: [T; N]) -> [T; N pub unconstrained fn sort_by(array: [T; N]) -> [T; N] { let mut result = array; - unsafe { - //@safety: testing context - get_sorting_index(array) - }; + get_sorting_index(array); result } diff --git a/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr b/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr index c0d8b336a04..b4dd6a57e80 100644 --- a/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr +++ b/test_programs/execution_success/regression_unsafe_no_predicates/src/main.nr @@ -7,10 +7,8 @@ fn main(x: u8, nest: bool) { #[no_predicates] pub fn unsafe_assert(msg: [u8; N]) -> u8 { - let block = unsafe { - //@safety: testing context - get_block(msg) - }; + /// Safety: testing context + let block = unsafe { get_block(msg) }; verify_block(msg, block); block[0] } diff --git a/test_programs/execution_success/u16_support/src/main.nr b/test_programs/execution_success/u16_support/src/main.nr index c6a212f908e..d86ad348708 100644 --- a/test_programs/execution_success/u16_support/src/main.nr +++ b/test_programs/execution_success/u16_support/src/main.nr @@ -1,7 +1,7 @@ fn main(x: u16) { test_u16(x); + /// Safety: testing context unsafe { - //@safety: testing context test_u16_unconstrained(x); } } diff --git a/test_programs/execution_success/uhashmap/src/main.nr b/test_programs/execution_success/uhashmap/src/main.nr index d1ba1c6175d..6163d5b954b 100644 --- a/test_programs/execution_success/uhashmap/src/main.nr +++ b/test_programs/execution_success/uhashmap/src/main.nr @@ -293,10 +293,8 @@ unconstrained fn doc_tests() { // docs:start:get_example fn get_example(map: UHashMap>) { - let x = unsafe { - //@safety: testing context - map.get(12) - }; + /// Safety: testing context + let x = unsafe { map.get(12) }; if x.is_some() { assert(x.unwrap() == 42); @@ -321,11 +319,8 @@ fn entries_examples(map: UHashMap {value}"); } // docs:end:keys_example diff --git a/test_programs/noir_test_success/comptime_expr/src/main.nr b/test_programs/noir_test_success/comptime_expr/src/main.nr index 39167242a7b..25910685e87 100644 --- a/test_programs/noir_test_success/comptime_expr/src/main.nr +++ b/test_programs/noir_test_success/comptime_expr/src/main.nr @@ -1,11 +1,10 @@ mod tests { - use std::meta::op::UnaryOp; use std::meta::op::BinaryOp; + use std::meta::op::UnaryOp; #[test] fn test_expr_as_array() { - comptime - { + comptime { let expr = quote { [1, 2, 4] }.as_expr().unwrap(); let elems = expr.as_array().unwrap(); assert_eq(elems.len(), 3); @@ -17,8 +16,7 @@ mod tests { #[test] fn test_expr_modify_for_array() { - comptime - { + comptime { let expr = quote { [1, 2, 4] }.as_expr().unwrap(); let expr = expr.modify(times_two); let elems = expr.as_array().unwrap(); @@ -31,8 +29,7 @@ mod tests { #[test] fn test_expr_as_assert() { - comptime - { + comptime { let expr = quote { assert(true) }.as_expr().unwrap(); let (predicate, msg) = expr.as_assert().unwrap(); assert_eq(predicate.as_bool().unwrap(), true); @@ -47,8 +44,7 @@ mod tests { #[test] fn test_expr_modify_for_assert() { - comptime - { + comptime { let expr = quote { assert(1) }.as_expr().unwrap(); let expr = expr.modify(times_two); let (predicate, msg) = expr.as_assert().unwrap(); @@ -65,8 +61,7 @@ mod tests { #[test] fn test_expr_as_assert_eq() { - comptime - { + comptime { let expr = quote { assert_eq(true, false) }.as_expr().unwrap(); let (lhs, rhs, msg) = expr.as_assert_eq().unwrap(); assert_eq(lhs.as_bool().unwrap(), true); @@ -83,8 +78,7 @@ mod tests { #[test] fn test_expr_modify_for_assert_eq() { - comptime - { + comptime { let expr = quote { assert_eq(1, 2) }.as_expr().unwrap(); let expr = expr.modify(times_two); let (lhs, rhs, msg) = expr.as_assert_eq().unwrap(); @@ -103,8 +97,7 @@ mod tests { #[test] fn test_expr_as_assign() { - comptime - { + comptime { let expr = quote { { a = 1; } }.as_expr().unwrap(); let exprs = expr.as_block().unwrap(); let (_lhs, rhs) = exprs[0].as_assign().unwrap(); @@ -114,8 +107,7 @@ mod tests { #[test] fn test_expr_modify_for_assign() { - comptime - { + comptime { let expr = quote { { a = 1; } }.as_expr().unwrap(); let expr = expr.modify(times_two); let exprs = expr.as_block().unwrap(); @@ -126,8 +118,7 @@ mod tests { #[test] fn test_expr_as_block() { - comptime - { + comptime { let expr = quote { { 1; 4; 23 } }.as_expr().unwrap(); let exprs = expr.as_block().unwrap(); assert_eq(exprs.len(), 3); @@ -143,8 +134,7 @@ mod tests { #[test] fn test_expr_modify_for_block() { - comptime - { + comptime { let expr = quote { { 1; 4; 23 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let exprs = expr.as_block().unwrap(); @@ -161,8 +151,7 @@ mod tests { #[test] fn test_expr_as_method_call() { - comptime - { + comptime { let expr = quote { foo.bar::(3, 4) }.as_expr().unwrap(); let (_object, name, generics, arguments) = expr.as_method_call().unwrap(); @@ -179,8 +168,7 @@ mod tests { #[test] fn test_expr_modify_for_method_call() { - comptime - { + comptime { let expr = quote { foo.bar(3, 4) }.as_expr().unwrap(); let expr = expr.modify(times_two); @@ -198,8 +186,7 @@ mod tests { #[test] fn test_expr_as_integer() { - comptime - { + comptime { let expr = quote { 1 }.as_expr().unwrap(); assert_eq((1, false), expr.as_integer().unwrap()); @@ -210,8 +197,7 @@ mod tests { #[test] fn test_expr_modify_for_integer() { - comptime - { + comptime { let expr = quote { 1 }.as_expr().unwrap(); let expr = expr.modify(times_two); @@ -221,8 +207,7 @@ mod tests { #[test] fn test_expr_as_binary_op() { - comptime - { + comptime { assert(get_binary_op(quote { x + y }).is_add()); assert(get_binary_op(quote { x - y }).is_subtract()); assert(get_binary_op(quote { x * y }).is_multiply()); @@ -244,8 +229,7 @@ mod tests { #[test] fn test_expr_modify_for_binary_op() { - comptime - { + comptime { let expr = quote { 3 + 4 }.as_expr().unwrap(); let expr = expr.modify(times_two); @@ -258,8 +242,7 @@ mod tests { #[test] fn test_expr_as_bool() { - comptime - { + comptime { let expr = quote { false }.as_expr().unwrap(); assert(expr.as_bool().unwrap() == false); @@ -270,8 +253,7 @@ mod tests { #[test] fn test_expr_as_cast() { - comptime - { + comptime { let expr = quote { 1 as Field }.as_expr().unwrap(); let (expr, typ) = expr.as_cast().unwrap(); assert_eq(expr.as_integer().unwrap(), (1, false)); @@ -281,8 +263,7 @@ mod tests { #[test] fn test_expr_modify_for_cast() { - comptime - { + comptime { let expr = quote { 1 as Field }.as_expr().unwrap(); let expr = expr.modify(times_two); let (expr, typ) = expr.as_cast().unwrap(); @@ -293,8 +274,7 @@ mod tests { #[test] fn test_expr_as_comptime() { - comptime - { + comptime { let expr = quote { comptime { 1; 4; 23 } }.as_expr().unwrap(); let exprs = expr.as_comptime().unwrap(); assert_eq(exprs.len(), 3); @@ -303,8 +283,7 @@ mod tests { #[test] fn test_expr_modify_for_comptime() { - comptime - { + comptime { let expr = quote { comptime { 1; 4; 23 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let exprs = expr.as_comptime().unwrap(); @@ -315,8 +294,7 @@ mod tests { #[test] fn test_expr_as_comptime_as_statement() { - comptime - { + comptime { let expr = quote { { comptime { 1; 4; 23 } } }.as_expr().unwrap(); let exprs = expr.as_block().unwrap(); assert_eq(exprs.len(), 1); @@ -328,8 +306,7 @@ mod tests { #[test] fn test_expr_as_constructor() { - comptime - { + comptime { let expr = quote { Foo { a: 1, b: 2 } }.as_expr().unwrap(); let (_typ, fields) = expr.as_constructor().unwrap(); assert_eq(fields.len(), 2); @@ -342,8 +319,7 @@ mod tests { #[test] fn test_expr_modify_for_constructor() { - comptime - { + comptime { let expr = quote { foo::bar::Baz:: { a: 1, b: 2 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let (_typ, fields) = expr.as_constructor().unwrap(); @@ -360,8 +336,7 @@ mod tests { // docs:start:as_expr_example #[test] fn test_expr_as_function_call() { - comptime - { + comptime { let expr = quote { foo(42) }.as_expr().unwrap(); let (_function, args) = expr.as_function_call().unwrap(); assert_eq(args.len(), 1); @@ -372,8 +347,7 @@ mod tests { #[test] fn test_expr_modify_for_function_call() { - comptime - { + comptime { let expr = quote { foo(42) }.as_expr().unwrap(); let expr = expr.modify(times_two); let (_function, args) = expr.as_function_call().unwrap(); @@ -384,8 +358,7 @@ mod tests { #[test] fn test_expr_as_if() { - comptime - { + comptime { let expr = quote { if 1 { 2 } }.as_expr().unwrap(); let (_condition, _consequence, alternative) = expr.as_if().unwrap(); assert(alternative.is_none()); @@ -398,8 +371,7 @@ mod tests { #[test] fn test_expr_modify_for_if() { - comptime - { + comptime { let expr = quote { if 1 { 2 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let (condition, consequence, alternative) = expr.as_if().unwrap(); @@ -421,8 +393,7 @@ mod tests { #[test] fn test_expr_as_index() { - comptime - { + comptime { let expr = quote { foo[bar] }.as_expr().unwrap(); assert(expr.as_index().is_some()); } @@ -430,8 +401,7 @@ mod tests { #[test] fn test_expr_modify_for_index() { - comptime - { + comptime { let expr = quote { 1[2] }.as_expr().unwrap(); let expr = expr.modify(times_two); let (object, index) = expr.as_index().unwrap(); @@ -442,8 +412,7 @@ mod tests { #[test] fn test_expr_as_member_access() { - comptime - { + comptime { let expr = quote { foo.bar }.as_expr().unwrap(); let (_, name) = expr.as_member_access().unwrap(); assert_eq(name, quote { bar }); @@ -452,8 +421,7 @@ mod tests { #[test] fn test_expr_modify_for_member_access() { - comptime - { + comptime { let expr = quote { 1.bar }.as_expr().unwrap(); let expr = expr.modify(times_two); let (expr, name) = expr.as_member_access().unwrap(); @@ -464,8 +432,7 @@ mod tests { #[test] fn test_expr_as_member_access_with_an_lvalue() { - comptime - { + comptime { let expr = quote { { foo.bar = 1; } }.as_expr().unwrap(); let exprs = expr.as_block().unwrap(); let (lhs, _rhs) = exprs[0].as_assign().unwrap(); @@ -476,8 +443,7 @@ mod tests { #[test] fn test_expr_as_repeated_element_array() { - comptime - { + comptime { let expr = quote { [1; 3] }.as_expr().unwrap(); let (expr, length) = expr.as_repeated_element_array().unwrap(); assert_eq(expr.as_integer().unwrap(), (1, false)); @@ -487,8 +453,7 @@ mod tests { #[test] fn test_expr_modify_for_repeated_element_array() { - comptime - { + comptime { let expr = quote { [1; 3] }.as_expr().unwrap(); let expr = expr.modify(times_two); let (expr, length) = expr.as_repeated_element_array().unwrap(); @@ -499,8 +464,7 @@ mod tests { #[test] fn test_expr_as_repeated_element_slice() { - comptime - { + comptime { let expr = quote { &[1; 3] }.as_expr().unwrap(); let (expr, length) = expr.as_repeated_element_slice().unwrap(); assert_eq(expr.as_integer().unwrap(), (1, false)); @@ -510,8 +474,7 @@ mod tests { #[test] fn test_expr_modify_for_repeated_element_slice() { - comptime - { + comptime { let expr = quote { &[1; 3] }.as_expr().unwrap(); let expr = expr.modify(times_two); let (expr, length) = expr.as_repeated_element_slice().unwrap(); @@ -522,8 +485,7 @@ mod tests { #[test] fn test_expr_as_slice() { - comptime - { + comptime { let expr = quote { &[1, 3, 5] }.as_expr().unwrap(); let elems = expr.as_slice().unwrap(); assert_eq(elems.len(), 3); @@ -535,8 +497,7 @@ mod tests { #[test] fn test_expr_modify_for_slice() { - comptime - { + comptime { let expr = quote { &[1, 3, 5] }.as_expr().unwrap(); let expr = expr.modify(times_two); let elems = expr.as_slice().unwrap(); @@ -549,8 +510,7 @@ mod tests { #[test] fn test_expr_as_tuple() { - comptime - { + comptime { let expr = quote { (1, 2) }.as_expr().unwrap(); let tuple_exprs = expr.as_tuple().unwrap(); assert_eq(tuple_exprs.len(), 2); @@ -559,8 +519,7 @@ mod tests { #[test] fn test_expr_modify_for_tuple() { - comptime - { + comptime { let expr = quote { (1, 2) }.as_expr().unwrap(); let expr = expr.modify(times_two); let tuple_exprs = expr.as_tuple().unwrap(); @@ -572,8 +531,7 @@ mod tests { #[test] fn test_expr_as_unary_op() { - comptime - { + comptime { assert(get_unary_op(quote { -x }).is_minus()); assert(get_unary_op(quote { !x }).is_not()); assert(get_unary_op(quote { &mut x }).is_mutable_reference()); @@ -583,8 +541,7 @@ mod tests { #[test] fn test_expr_modify_for_unary_op() { - comptime - { + comptime { let expr = quote { -(1) }.as_expr().unwrap(); let expr = expr.modify(times_two); let (op, expr) = expr.as_unary_op().unwrap(); @@ -595,14 +552,13 @@ mod tests { #[test] fn test_expr_as_unsafe() { - comptime - { + comptime { let expr = quote { - unsafe - { - //@safety" test - 1; 4; 23 } - }.as_expr().unwrap(); + /// Safety: test + unsafe { 1; 4; 23 } + } + .as_expr() + .unwrap(); let exprs = expr.as_unsafe().unwrap(); assert_eq(exprs.len(), 3); } @@ -610,11 +566,13 @@ mod tests { #[test] fn test_expr_modify_for_unsafe() { - comptime - { - let expr = quote { unsafe { - //@safety: test - 1; 4; 23 } }.as_expr().unwrap(); + comptime { + let expr = quote { + /// Safety: test + unsafe { 1; 4; 23 } + } + .as_expr() + .unwrap(); let expr = expr.modify(times_two); let exprs = expr.as_unsafe().unwrap(); assert_eq(exprs.len(), 3); @@ -624,8 +582,7 @@ mod tests { #[test] fn test_expr_is_break() { - comptime - { + comptime { let expr = quote { { break; } }.as_expr().unwrap(); let exprs = expr.as_block().unwrap(); assert(exprs[0].is_break()); @@ -634,8 +591,7 @@ mod tests { #[test] fn test_expr_is_continue() { - comptime - { + comptime { let expr = quote { { continue; } }.as_expr().unwrap(); let exprs = expr.as_block().unwrap(); assert(exprs[0].is_continue()); @@ -644,8 +600,7 @@ mod tests { #[test] fn test_expr_as_lambda() { - comptime - { + comptime { let expr = quote { |x: Field| -> Field { 1 } }.as_expr().unwrap(); let (params, return_type, body) = expr.as_lambda().unwrap(); assert_eq(params.len(), 1); @@ -664,15 +619,17 @@ mod tests { #[test] fn test_expr_modify_lambda() { - comptime - { + comptime { let expr = quote { |x: Field| -> Field { 1 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let (params, return_type, body) = expr.as_lambda().unwrap(); assert_eq(params.len(), 1); assert(params[0].1.unwrap().is_field()); assert(return_type.unwrap().is_field()); - assert_eq(body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), (2, false)); + assert_eq( + body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), + (2, false), + ); let expr = quote { |x| { 1 } }.as_expr().unwrap(); let expr = expr.modify(times_two); @@ -680,14 +637,16 @@ mod tests { assert_eq(params.len(), 1); assert(params[0].1.is_none()); assert(return_type.is_none()); - assert_eq(body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), (2, false)); + assert_eq( + body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), + (2, false), + ); } } #[test] fn test_expr_as_let() { - comptime - { + comptime { let expr = quote { let x: Field = 1; }.as_expr().unwrap(); let (_pattern, typ, expr) = expr.as_let().unwrap(); assert(typ.unwrap().is_field()); @@ -697,8 +656,7 @@ mod tests { #[test] fn test_expr_modify_for_let() { - comptime - { + comptime { let expr = quote { let x : Field = 1; }.as_expr().unwrap(); let expr = expr.modify(times_two); let (_pattern, typ, expr) = expr.as_let().unwrap(); @@ -709,8 +667,7 @@ mod tests { #[test] fn test_expr_modify_for_let_without_type() { - comptime - { + comptime { let expr = quote { let x = 1; }.as_expr().unwrap(); let expr = expr.modify(times_two); let (_pattern, typ, expr) = expr.as_let().unwrap(); @@ -721,8 +678,7 @@ mod tests { #[test] fn test_expr_as_for_statement() { - comptime - { + comptime { let expr = quote { for x in 2 { 3 } }.as_expr().unwrap(); let (index, array, body) = expr.as_for().unwrap(); assert_eq(index, quote { x }); @@ -733,21 +689,22 @@ mod tests { #[test] fn test_expr_modify_for_statement() { - comptime - { + comptime { let expr = quote { for x in 2 { 3 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let (index, array, body) = expr.as_for().unwrap(); assert_eq(index, quote { x }); assert_eq(array.as_integer().unwrap(), (4, false)); - assert_eq(body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), (6, false)); + assert_eq( + body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), + (6, false), + ); } } #[test] fn test_expr_as_for_range_statement() { - comptime - { + comptime { let expr = quote { for x in 2..3 { 4 } }.as_expr().unwrap(); let (index, from, to, body) = expr.as_for_range().unwrap(); assert_eq(index, quote { x }); @@ -759,22 +716,23 @@ mod tests { #[test] fn test_expr_modify_for_range_statement() { - comptime - { + comptime { let expr = quote { for x in 2..3 { 4 } }.as_expr().unwrap(); let expr = expr.modify(times_two); let (index, from, to, body) = expr.as_for_range().unwrap(); assert_eq(index, quote { x }); assert_eq(from.as_integer().unwrap(), (4, false)); assert_eq(to.as_integer().unwrap(), (6, false)); - assert_eq(body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), (8, false)); + assert_eq( + body.as_block().unwrap()[0].as_block().unwrap()[0].as_integer().unwrap(), + (8, false), + ); } } #[test] fn test_automatically_unwraps_parenthesized_expression() { - comptime - { + comptime { let expr = quote { ((if 1 { 2 })) }.as_expr().unwrap(); assert(expr.as_if().is_some()); } @@ -782,8 +740,7 @@ mod tests { #[test] fn test_resolve_to_function_definition() { - comptime - { + comptime { let expr = quote { times_two }.as_expr().unwrap(); let func = expr.resolve(Option::none()).as_function_definition().unwrap(); assert_eq(func.name(), quote { times_two }); @@ -804,13 +761,11 @@ mod tests { } comptime fn times_two(expr: Expr) -> Option { - expr.as_integer().and_then( - |integer: (Field, bool)| { - let (value, _) = integer; + expr.as_integer().and_then(|integer: (Field, bool)| { + let (value, _) = integer; let value = value * 2; quote { $value }.as_expr() - } - ) + }) } } diff --git a/test_programs/noir_test_success/mock_oracle/src/main.nr b/test_programs/noir_test_success/mock_oracle/src/main.nr index b026f510418..aaf2c87ddb0 100644 --- a/test_programs/noir_test_success/mock_oracle/src/main.nr +++ b/test_programs/noir_test_success/mock_oracle/src/main.nr @@ -34,8 +34,8 @@ unconstrained fn struct_field(point: Point, array: [Field; 4]) -> Field { #[test(should_fail)] fn test_mock_no_returns() { + /// Safety: testing context unsafe { - //@safety: testing context OracleMock::mock("void_field"); void_field(); // Some return value must be set } @@ -43,8 +43,8 @@ fn test_mock_no_returns() { #[test] fn test_mock() { + /// Safety: testing context unsafe { - //@safety: testing context OracleMock::mock("void_field").returns(10); assert_eq(void_field(), 10); } @@ -52,8 +52,8 @@ fn test_mock() { #[test] fn test_multiple_mock() { + /// Safety: testing context unsafe { - //@safety: testing context let first_mock = OracleMock::mock("void_field").returns(10); OracleMock::mock("void_field").returns(42); @@ -67,8 +67,8 @@ fn test_multiple_mock() { #[test] fn test_multiple_mock_times() { + /// Safety: testing context unsafe { - //@safety: testing context OracleMock::mock("void_field").returns(10).times(2); OracleMock::mock("void_field").returns(42); @@ -80,8 +80,8 @@ fn test_multiple_mock_times() { #[test] fn test_mock_with_params() { + /// Safety: testing context unsafe { - //@safety: testing context OracleMock::mock("field_field").with_params((5,)).returns(10); assert_eq(field_field(5), 10); } @@ -89,8 +89,8 @@ fn test_mock_with_params() { #[test] fn test_multiple_mock_with_params() { + /// Safety: testing context unsafe { - //@safety: testing context OracleMock::mock("field_field").with_params((5,)).returns(10); OracleMock::mock("field_field").with_params((7,)).returns(14); @@ -101,8 +101,8 @@ fn test_multiple_mock_with_params() { #[test] fn test_mock_last_params() { + /// Safety: testing context unsafe { - //@safety: testing context let mock = OracleMock::mock("field_field").returns(10); assert_eq(field_field(5), 10); @@ -112,8 +112,8 @@ fn test_mock_last_params() { #[test] fn test_mock_last_params_many_calls() { + /// Safety: testing context unsafe { - //@safety: testing context let mock = OracleMock::mock("field_field").returns(10); assert_eq(field_field(5), 10); assert_eq(field_field(7), 10); @@ -125,13 +125,12 @@ fn test_mock_last_params_many_calls() { #[test] fn test_mock_struct_field() { // Combination of simpler test cases - let array = [1, 2, 3, 4]; let another_array = [4, 3, 2, 1]; let point = Point { x: 14, y: 27 }; + /// Safety: testing context unsafe { - //@safety: testing context OracleMock::mock("struct_field").returns(42).times(2); let timeless_mock = OracleMock::mock("struct_field").returns(0); assert_eq(42, struct_field(point, array)); diff --git a/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr b/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr index 99277b62939..05bc2a5ce13 100644 --- a/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr +++ b/test_programs/noir_test_success/out_of_bounds_alignment/src/main.nr @@ -2,7 +2,10 @@ fn out_of_bounds(arr_1: [Field; 50]) -> Field { arr_1[50 + 1] } -unconstrained fn out_of_bounds_unconstrained_wrapper(arr_1: [Field; 50], arr_2: [Field; 50]) -> Field { +unconstrained fn out_of_bounds_unconstrained_wrapper( + arr_1: [Field; 50], + arr_2: [Field; 50], +) -> Field { out_of_bounds(arr_1) } @@ -13,8 +16,8 @@ fn test_acir() { #[test(should_fail)] fn test_brillig() { + /// Safety: testing context unsafe { - //@safety: testing context assert_eq(out_of_bounds_unconstrained_wrapper([0; 50], [0; 50]), 0); } } diff --git a/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs b/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs index 57512d049df..e20eb4291d1 100644 --- a/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs +++ b/tooling/nargo_fmt/src/formatter/comments_and_whitespace.rs @@ -1,4 +1,4 @@ -use noirc_frontend::token::{DocStyle, Token}; +use noirc_frontend::token::Token; use super::Formatter; @@ -113,8 +113,7 @@ impl<'a> Formatter<'a> { last_was_block_comment = false; } - Token::LineComment(comment, None) - | Token::LineComment(comment, Some(DocStyle::Safety)) => { + Token::LineComment(comment, None) => { if comment.trim() == "noir-fmt:ignore" { ignore_next = true; } @@ -143,8 +142,7 @@ impl<'a> Formatter<'a> { last_was_block_comment = false; self.written_comments_count += 1; } - Token::BlockComment(comment, None) - | Token::BlockComment(comment, Some(DocStyle::Safety)) => { + Token::BlockComment(comment, None) => { if comment.trim() == "noir-fmt:ignore" { ignore_next = true; } diff --git a/tooling/nargo_fmt/src/formatter/expression.rs b/tooling/nargo_fmt/src/formatter/expression.rs index 2f71d3209a7..ef04276a605 100644 --- a/tooling/nargo_fmt/src/formatter/expression.rs +++ b/tooling/nargo_fmt/src/formatter/expression.rs @@ -370,6 +370,7 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { ) -> ChunkGroup { let mut group = ChunkGroup::new(); group.text(self.chunk(|formatter| { + formatter.format_outer_doc_comments(); formatter.write_keyword(Keyword::Unsafe); formatter.write_space(); })); @@ -1910,21 +1911,17 @@ global y = 1; #[test] fn format_unsafe_one_expression() { - let src = "global x = unsafe { //@safety: testing + let src = "global x = unsafe { 1 } ;"; - let expected = "global x = unsafe { - //@safety: testing - 1 -};\n"; + let expected = "global x = unsafe { 1 };\n"; assert_format(src, expected); } #[test] fn format_unsafe_two_expressions() { - let src = "global x = unsafe { //@safety: testing + let src = "global x = unsafe { 1; 2 } ;"; let expected = "global x = unsafe { - //@safety: testing 1; 2 }; @@ -1932,6 +1929,21 @@ global y = 1; assert_format(src, expected); } + #[test] + fn format_unsafe_with_doc_comment() { + let src = "fn foo() { + /// Comment + unsafe { 1 } }"; + let expected = "fn foo() { + /// Comment + unsafe { + 1 + } +} +"; + assert_format(src, expected); + } + #[test] fn format_comptime_one_expression() { let src = "global x = comptime { 1 } ;"; @@ -2204,7 +2216,6 @@ global y = 1; let src = "mod moo { fn foo() { let mut sorted_write_tuples = unsafe { - //@safety: testing get_sorted_tuple( final_public_data_writes.storage, |(_, leaf_a): (u32, PublicDataTreeLeaf), (_, leaf_b): (u32, PublicDataTreeLeaf)| full_field_less_than( @@ -2218,7 +2229,6 @@ global y = 1; let expected = "mod moo { fn foo() { let mut sorted_write_tuples = unsafe { - //@safety: testing get_sorted_tuple( final_public_data_writes.storage, |(_, leaf_a): (u32, PublicDataTreeLeaf), (_, leaf_b): (u32, PublicDataTreeLeaf)| { diff --git a/tooling/nargo_fmt/src/formatter/statement.rs b/tooling/nargo_fmt/src/formatter/statement.rs index 116d68e308f..1736197403c 100644 --- a/tooling/nargo_fmt/src/formatter/statement.rs +++ b/tooling/nargo_fmt/src/formatter/statement.rs @@ -4,7 +4,7 @@ use noirc_frontend::{ ForLoopStatement, ForRange, LetStatement, Pattern, Statement, StatementKind, UnresolvedType, UnresolvedTypeData, }, - token::{Keyword, SecondaryAttribute, Token}, + token::{Keyword, SecondaryAttribute, Token, TokenKind}, }; use crate::chunks::{ChunkFormatter, ChunkGroup, GroupKind}; @@ -23,6 +23,9 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { // Now write any leading comment respecting multiple newlines after them group.leading_comment(self.chunk(|formatter| { + if formatter.token.kind() == TokenKind::OuterDocComment { + formatter.format_outer_doc_comments(); + } formatter.skip_comments_and_whitespace_writing_multiple_lines_if_found(); })); @@ -374,6 +377,19 @@ mod tests { assert_format(src, expected); } + #[test] + fn format_let_statement_with_unsafe() { + let src = " fn foo() { + /// Safety: some doc + let x = unsafe { 1 } ; } "; + let expected = "fn foo() { + /// Safety: some doc + let x = unsafe { 1 }; +} +"; + assert_format(src, expected); + } + #[test] fn format_assign() { let src = " fn foo() { x = 2 ; } "; @@ -490,11 +506,9 @@ mod tests { #[test] fn format_unsafe_statement() { let src = " fn foo() { unsafe { - //@safety: testing context 1 } } "; let expected = "fn foo() { unsafe { - //@safety: testing context 1 } } diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 2b55b86e975..05bfb0e7d57 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -79,6 +79,7 @@ pub(crate) fn assert_format_with_config(src: &str, expected: &str, config: Confi let src = &result; let (parsed_module, errors) = parser::parse_program(src); + let errors: Vec<_> = errors.into_iter().filter(|error| !error.is_warning()).collect(); if !errors.is_empty() { panic!("Expected no errors in idempotent check, got: {:?}", errors); } diff --git a/tooling/nargo_fmt/tests/expected/unsafe.nr b/tooling/nargo_fmt/tests/expected/unsafe.nr index ec99d90c662..0cf587ea549 100644 --- a/tooling/nargo_fmt/tests/expected/unsafe.nr +++ b/tooling/nargo_fmt/tests/expected/unsafe.nr @@ -1,9 +1,9 @@ fn main(x: pub u8, y: u8) { - unsafe { //@safety: testing - } + /// Safety: testing + unsafe {} + /// Safety: testing unsafe { - //@safety: testing assert_eq(x, y); } } diff --git a/tooling/nargo_fmt/tests/input/unsafe.nr b/tooling/nargo_fmt/tests/input/unsafe.nr index 65ed061835f..0aeffd0b983 100644 --- a/tooling/nargo_fmt/tests/input/unsafe.nr +++ b/tooling/nargo_fmt/tests/input/unsafe.nr @@ -1,8 +1,10 @@ fn main(x: pub u8, y: u8) { - unsafe {//@safety: testing + /// Safety: testing + unsafe { } - unsafe {//@safety: testing + /// Safety: testing + unsafe { assert_eq(x, y); } }