Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 0 additions & 37 deletions compiler/noirc_evaluator/src/ssa/ssa_gen/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,40 +107,3 @@ fn basic_loop() {

assert_normalized_ssa_equals(ssa, expected);
}

#[named]
#[test]
fn databus_no_dead_param_on_empty_array() {
let src = "
fn main(a: (i8, u32, i8), b: call_data(0) [(i8, i8, bool, bool, str<0>); 2]) -> pub [(bool, str<3>, str<0>, u32); 0] {
[]
}
";

let ssa = get_initial_ssa(src, function_path!()).unwrap();

// We expect that there to be no `array_get` attempting to fetch from v3
// the empty nested array `[u8; 0]`.
// The databus is only going to be initialized with actual numeric values so keeping
// an empty array in the databus is pointless.
// The databus is not mutated after initialization as well. So if we have instructions
// on the data bus (such as an `array_get` on an empty array) that go unused, it becomes
// more difficult to eliminate those unused instructions. Thus, we just do not generate them.
let expected = "
acir(inline) fn main f0 {
b0(v0: i8, v1: u32, v2: i8, v3: [(i8, i8, u1, u1, [u8; 0]); 2]):
v5 = array_get v3, index u32 0 -> i8
v7 = array_get v3, index u32 1 -> i8
v9 = array_get v3, index u32 2 -> u1
v11 = array_get v3, index u32 3 -> u1
v13 = array_get v3, index u32 4 -> i8
v15 = array_get v3, index u32 5 -> i8
v17 = array_get v3, index u32 6 -> u1
v19 = array_get v3, index u32 7 -> u1
v20 = make_array [v5, v7, v9, v11, v13, v15, v17, v19] : [Field; 8]
v21 = make_array [] : [(u1, [u8; 3], [u8; 0], u32); 0]
return v21
}
";
assert_normalized_ssa_equals(ssa, expected);
}
24 changes: 22 additions & 2 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1295,9 +1295,13 @@
}

Type::Array(length, element) => {
length.is_valid_for_program_input() && element.is_valid_for_program_input()
self.array_or_string_len_is_not_zero()
&& length.is_valid_for_program_input()
&& element.is_valid_for_program_input()
}
Type::String(length) => {
self.array_or_string_len_is_not_zero() && length.is_valid_for_program_input()
}
Type::String(length) => length.is_valid_for_program_input(),
Type::Tuple(elements) => elements.iter().all(|elem| elem.is_valid_for_program_input()),
Type::DataType(definition, generics) => {
if let Some(fields) = definition.borrow().get_fields(generics) {
Expand All @@ -1314,6 +1318,22 @@
}
}

/// Empty arrays and strings (which are arrays under the hood) are disallowed
/// as input to program entry points.
///
/// The point of inputs to entry points is to process input data.
/// Thus, passing empty arrays is pointless and adds extra complexity to the compiler
/// for handling them.
fn array_or_string_len_is_not_zero(&self) -> bool {
match self {
Type::Array(length, _) | Type::String(length) => {
let length = length.evaluate_to_u32(Location::dummy()).unwrap_or(0);
length != 0
}
_ => panic!("ICE: Expected an array or string type"),
}
}

/// True if this type can be used as a parameter to an ACIR function that is not `main` or a contract function.
/// This encapsulates functions for which we may not want to inline during compilation.
///
Expand Down Expand Up @@ -2399,7 +2419,7 @@
}

let recur_on_binding = |id, replacement: &Type| {
// Prevent recuring forever if there's a `T := T` binding

Check warning on line 2422 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (recuring)
if replacement.type_variable_id() == Some(id) {
replacement.clone()
} else {
Expand Down Expand Up @@ -2485,7 +2505,7 @@
Type::Tuple(fields)
}
Type::Forall(typevars, typ) => {
// Trying to substitute_helper a variable de, substitute_bound_typevarsfined within a nested Forall

Check warning on line 2508 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevarsfined)
// is usually impossible and indicative of an error in the type checker somewhere.
for var in typevars {
assert!(!type_bindings.contains_key(&var.id()));
Expand Down Expand Up @@ -2652,7 +2672,7 @@
}
}

/// Follow bindings if this is a type variable or generic to the first non-typevariable

Check warning on line 2675 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (typevariable)
/// type. Unlike `follow_bindings`, this won't recursively follow any bindings on any
/// fields or arguments of this type.
pub fn follow_bindings_shallow(&self) -> Cow<Type> {
Expand All @@ -2677,7 +2697,7 @@

/// Replace any `Type::NamedGeneric` in this type with a `Type::TypeVariable`
/// using to the same inner `TypeVariable`. This is used during monomorphization
/// to bind to named generics since they are unbindable during type checking.

Check warning on line 2700 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (unbindable)
pub fn replace_named_generics_with_type_variables(&mut self) {
match self {
Type::FieldElement
Expand Down Expand Up @@ -3223,7 +3243,7 @@
len.hash(state);
env.hash(state);
}
Type::Tuple(elems) => elems.hash(state),

Check warning on line 3246 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)

Check warning on line 3246 in compiler/noirc_frontend/src/hir_def/types.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)
Type::DataType(def, args) => {
def.hash(state);
args.hash(state);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: Only sized types may be used in the entry point to a program
┌─ src/main.nr:1:12
1 │ fn main(a: [[u32; 0]; 1], b: bool) -> pub [u32; 0] {
│ ------------- Slices, references, or any type containing them may not be used in main, contract functions, or foldable functions

Aborting due to 1 previous error
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
global DEPTH: Field = 40000;
global DEPTH: u32 = 40000;

fn main(x: [u32; DEPTH], y: u32) {
let mut new_x = [];
Expand Down
16 changes: 1 addition & 15 deletions test_programs/compile_failure/brillig_slice_to_acir/stderr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,6 @@ warning: unused variable x
│ - unused variable

error: The numeric generic is not of type `u32`
┌─ src/main.nr:3:12
3 │ fn main(x: [u32; DEPTH], y: u32) {
│ ------------ expected `u32`, found `Field`

error: The numeric generic is not of type `u32`
┌─ src/main.nr:8:27
8 │ unconstrained fn clear(x: [u32; DEPTH], y: u32) -> [u32] {
│ ------------ expected `u32`, found `Field`

error: Call to unconstrained function is unsafe and must be in an unconstrained function or unsafe block
┌─ src/main.nr:5:13
Expand Down Expand Up @@ -54,4 +40,4 @@ error: No method named 'push_back' found for type '[u32; 0]'
│ -----------------

Aborting due to 6 previous errors
Aborting due to 4 previous errors
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
global DEPTH: Field = 40000;
global DEPTH: u32 = 40000;

fn main(x: [u32; DEPTH], y: u32) {
let mut new_x = Vec::new();
Expand Down
16 changes: 1 addition & 15 deletions test_programs/compile_failure/brillig_vec_to_acir/stderr.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
error: The numeric generic is not of type `u32`
┌─ src/main.nr:3:12
3 │ fn main(x: [u32; DEPTH], y: u32) {
│ ------------ expected `u32`, found `Field`

error: The numeric generic is not of type `u32`
┌─ src/main.nr:8:27
8 │ unconstrained fn clear(x: [u32; DEPTH], y: u32) -> Vec<u32> {
│ ------------ expected `u32`, found `Field`

error: Call to unconstrained function is unsafe and must be in an unconstrained function or unsafe block
┌─ src/main.nr:5:13
Expand All @@ -26,4 +12,4 @@ error: Slices cannot be returned from an unconstrained runtime to a constrained
│ -----------

Aborting due to 4 previous errors
Aborting due to 2 previous errors
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Regression for issue #8398 (https://github.com/noir-lang/noir/issues/8398)
fn main(
a: (i8, u32, i8),
b: call_data(0) [(i8, i8, bool, bool, str<0>); 2],
_a: (i8, u32, i8),
_b: call_data(0) [(i8, i8, bool, bool, str<0>); 2],
) -> pub [(bool, str<3>, str<0>, u32); 0] {
[]
}
8 changes: 8 additions & 0 deletions test_programs/compile_failure/databus_dead_param/stderr.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: Only sized types may be used in the entry point to a program
┌─ src/main.nr:4:22
4 │ _b: call_data(0) [(i8, i8, bool, bool, str<0>); 2],
│ --------------------------------- Slices, references, or any type containing them may not be used in main, contract functions, or foldable functions

Aborting due to 1 previous error
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: Only sized types may be used in the entry point to a program
┌─ src/main.nr:1:17
1 │ fn main(_empty: [u32; 0], value_1: u32, value_2: call_data(0) u32) {
│ -------- Slices, references, or any type containing them may not be used in main, contract functions, or foldable functions

Aborting due to 1 previous error
9 changes: 8 additions & 1 deletion test_programs/compile_failure/main_with_generics/stderr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,11 @@ error: `main` entry-point function is not allowed to have generic parameters
│ ------

Aborting due to 1 previous error
error: Only sized types may be used in the entry point to a program
┌─ src/main.nr:1:24
1 │ fn main<let F: u32>(x: [Field; F]) {
│ ---------- Slices, references, or any type containing them may not be used in main, contract functions, or foldable functions

Aborting due to 2 previous errors

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
global G_C: [[str<0>; 4]; 4] =
[["", "", "", ""], ["", "", "", ""], ["", "", "", ""], ["", "", "", ""]];
unconstrained fn main(a: [[str<0>; 4]; 4]) {
global G_C: [[str<1>; 4]; 4] =
[["a", "a", "a", "a"], ["a", "a", "a", "a"], ["a", "a", "a", "a"], ["a", "a", "a", "a"]];
unconstrained fn main(a: [[str<1>; 4]; 4]) {
let mut f = a;
f[0] = G_C[3];
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ b = [
c = [
[
"0x1eac91250e5e424f9c8b3eb451e0b343131fcf4342053cfad6337e7ca1350adb",
"",
false,
false,
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
fn main(
a: bool,
b: ([bool; 2], [bool; 2], str<2>, (u16, u16), u16),
c: ((Field, str<0>, bool, bool), (u16, str<2>)),
c: ((Field, bool, bool), (u16, str<2>)),
) -> pub u16 {
b.4
% if c.0.2 {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading