diff --git a/compiler/noirc_evaluator/src/acir/mod.rs b/compiler/noirc_evaluator/src/acir/mod.rs index 7ecc4d28032..e57f5d18830 100644 --- a/compiler/noirc_evaluator/src/acir/mod.rs +++ b/compiler/noirc_evaluator/src/acir/mod.rs @@ -2169,7 +2169,7 @@ impl<'a> Context<'a> { let Type::Array(result_type, array_length) = dfg.type_of_value(result_ids[0]) else { - unreachable!("ICE: ToRadix result must be an array"); + unreachable!("ICE: ToBits result must be an array"); }; self.acir_context diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 0e26d0b5bd8..98b08266f67 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -1526,7 +1526,7 @@ impl<'context> Elaborator<'context> { ) -> Option { let func_id = match self.current_item { Some(DependencyId::Function(id)) => id, - _ => panic!("unexpected method outside a function"), + _ => panic!("unexpected method outside a function: {method_name}"), }; let func_meta = self.interner.function_meta(&func_id); diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 8a9fcf12e16..730bcd1be6c 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -192,6 +192,8 @@ impl<'local, 'context> Interpreter<'local, 'context> { "struct_def_set_fields" => struct_def_set_fields(interner, arguments, location), "to_be_radix" => to_be_radix(arguments, return_type, location), "to_le_radix" => to_le_radix(arguments, return_type, location), + "to_be_bits" => to_be_bits(arguments, return_type, location), + "to_le_bits" => to_le_bits(arguments, return_type, location), "trait_constraint_eq" => trait_constraint_eq(arguments, location), "trait_constraint_hash" => trait_constraint_hash(arguments, location), "trait_def_as_trait_constraint" => { @@ -776,6 +778,26 @@ fn quoted_tokens(arguments: Vec<(Value, Location)>, location: Location) -> IResu )) } +fn to_be_bits( + arguments: Vec<(Value, Location)>, + return_type: Type, + location: Location, +) -> IResult { + let value = check_one_argument(arguments, location)?; + let radix = (Value::U32(2), value.1); + to_be_radix(vec![value, radix], return_type, location) +} + +fn to_le_bits( + arguments: Vec<(Value, Location)>, + return_type: Type, + location: Location, +) -> IResult { + let value = check_one_argument(arguments, location)?; + let radix = (Value::U32(2), value.1); + to_le_radix(vec![value, radix], return_type, location) +} + fn to_be_radix( arguments: Vec<(Value, Location)>, return_type: Type, diff --git a/compiler/noirc_frontend/src/hir/comptime/tests.rs b/compiler/noirc_frontend/src/hir/comptime/tests.rs index ce8d43e56d5..9f77bb03b6e 100644 --- a/compiler/noirc_frontend/src/hir/comptime/tests.rs +++ b/compiler/noirc_frontend/src/hir/comptime/tests.rs @@ -19,6 +19,8 @@ use crate::node_interner::FuncId; use crate::parse_program; /// Create an interpreter for a code snippet and pass it to a test function. +/// +/// The `stdlib` is not made available as a dependency. pub(crate) fn with_interpreter( src: &str, f: impl FnOnce(&mut Interpreter, FuncId, &[(CompilationError, FileId)]) -> T, diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index c657a839a33..4b854f2a55d 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -65,6 +65,9 @@ pub(crate) fn get_program(src: &str) -> (ParsedModule, Context, Vec<(Compilation ) } +/// Compile a program. +/// +/// The `stdlib` is not available for these snippets. pub(crate) fn get_program_with_maybe_parser_errors( src: &str, allow_parser_errors: bool, @@ -3894,10 +3897,10 @@ fn errors_on_cyclic_globals() { #[test] fn warns_on_unneeded_unsafe() { let src = r#" - fn main() { + fn main() { /// Safety: test unsafe { - foo() + foo() } } @@ -3914,12 +3917,12 @@ fn warns_on_unneeded_unsafe() { #[test] fn warns_on_nested_unsafe() { let src = r#" - fn main() { + fn main() { /// Safety: test - unsafe { + unsafe { /// Safety: test unsafe { - foo() + foo() } } } diff --git a/test_programs/noir_test_success/global_eval/Nargo.toml b/test_programs/noir_test_success/global_eval/Nargo.toml new file mode 100644 index 00000000000..1dfe3a9660a --- /dev/null +++ b/test_programs/noir_test_success/global_eval/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "global_eval" +type = "bin" +authors = [""] +compiler_version = ">=0.27.0" + +[dependencies] diff --git a/test_programs/noir_test_success/global_eval/src/main.nr b/test_programs/noir_test_success/global_eval/src/main.nr new file mode 100644 index 00000000000..2896a1694fb --- /dev/null +++ b/test_programs/noir_test_success/global_eval/src/main.nr @@ -0,0 +1,10 @@ +use std::uint128::U128; + +// These definitions require `to_be_bits` and `to_le_bits` to be supported at comptime. +global POW64_A: Field = 2.pow_32(64); +global POW64_B: Field = (U128::one() << 64).to_integer(); + +#[test] +fn test_pow64_equal() { + assert_eq(POW64_A, POW64_B); +}