Skip to content

Commit

Permalink
Merge branch 'master' into assert-eq-builtin
Browse files Browse the repository at this point in the history
* master:
  fix(acir): Attach locations to MemoryOps in ACIR (#2389)
  feat: Use equivalence information from equality assertions to simplify circuit (#2378)
  chore: fix body expr span (#2402)
  feat(attributes): enable custom attributes (#2395)
  chore: Remove `serde` from `noirc_frontend` (#2390)
  chore: allow parenthesizing in two type locations  (#2388)
  chore(ci): automatically delete cache entries associated with closed PRs (#2342)
  • Loading branch information
TomAFrench committed Aug 22, 2023
2 parents d80cba1 + d7d7f22 commit 7668ff5
Show file tree
Hide file tree
Showing 40 changed files with 256 additions and 63 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/cache-cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This workflow cleans up any cache entries associated with a pull request once it has been closed.
# This prevents us from having many refs/pull/PR_NUMBER/merge cache entries which will never be used.
#
# Note that this will affect both PRs being closed with and without being merged.

name: Cleanup closed PR cache entries

on:
pull_request:
types:
- closed

jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
1 change: 0 additions & 1 deletion Cargo.lock

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

51 changes: 40 additions & 11 deletions crates/nargo_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ fn execute_package<B: Backend>(
// Parse the initial witness values from Prover.toml
let (inputs_map, _) =
read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &abi)?;

let solved_witness =
execute_program(backend, circuit, &abi, &inputs_map, Some((debug, context)))?;
let public_abi = abi.public_abi();
Expand All @@ -91,38 +90,68 @@ fn execute_package<B: Backend>(
Ok((return_value, solved_witness))
}

fn extract_unsatisfied_constraint_from_nargo_error(
/// There are certain errors that contain an [acvm::pwg::ErrorLocation].
/// We need to determine whether the error location has been resolving during execution.
/// If the location has been resolved we return the contained [OpcodeLocation].
fn extract_opcode_error_from_nargo_error(
nargo_err: &NargoError,
) -> Option<OpcodeLocation> {
) -> Option<(OpcodeLocation, &acvm::pwg::OpcodeResolutionError)> {
let solving_err = match nargo_err {
nargo::NargoError::SolvingError(err) => err,
_ => return None,
};

match solving_err {
acvm::pwg::OpcodeResolutionError::UnsatisfiedConstrain {
acvm::pwg::OpcodeResolutionError::IndexOutOfBounds {
opcode_location: error_location,
..
}
| acvm::pwg::OpcodeResolutionError::UnsatisfiedConstrain {
opcode_location: error_location,
} => match error_location {
ErrorLocation::Unresolved => {
unreachable!("Cannot resolve index for unsatisfied constraint")
}
ErrorLocation::Resolved(opcode_location) => Some(*opcode_location),
ErrorLocation::Resolved(opcode_location) => Some((*opcode_location, solving_err)),
},
_ => None,
}
}

fn report_unsatisfied_constraint_error(
opcode_location: Option<OpcodeLocation>,
/// Resolve an [OpcodeLocation] using debug information generated during compilation
/// to determine an opcode's call stack. Then report the error using the resolved
/// call stack and any other relevant error information returned from the ACVM.
fn report_error_with_opcode_location(
opcode_err_info: Option<(OpcodeLocation, &acvm::pwg::OpcodeResolutionError)>,
debug: &DebugInfo,
context: &Context,
) {
if let Some(opcode_location) = opcode_location {
if let Some((opcode_location, opcode_err)) = opcode_err_info {
if let Some(locations) = debug.opcode_location(&opcode_location) {
// The location of the error itself will be the location at the top
// of the call stack (the last item in the Vec).
if let Some(location) = locations.last() {
let message = "Failed constraint".into();
let message = match opcode_err {
acvm::pwg::OpcodeResolutionError::IndexOutOfBounds {
index,
array_size,
..
} => {
format!(
"Index out of bounds, array has size {array_size:?}, but index was {index:?}"
)
}
acvm::pwg::OpcodeResolutionError::UnsatisfiedConstrain { .. } => {
"Failed constraint".into()
}
_ => {
// All other errors that do not have corresponding opcode locations
// should not be reported in this method.
// If an error with an opcode location is not handled in this match statement
// the basic message attached to the original error from the ACVM should be reported.
return;
}
};
CustomDiagnostic::simple_error(message, String::new(), location.span)
.in_file(location.file)
.with_call_stack(locations)
Expand All @@ -145,8 +174,8 @@ pub(crate) fn execute_program<B: Backend>(
Ok(solved_witness) => Ok(solved_witness),
Err(err) => {
if let Some((debug, context)) = debug_data {
let opcode_location = extract_unsatisfied_constraint_from_nargo_error(&err);
report_unsatisfied_constraint_error(opcode_location, &debug, &context);
let opcode_err_info = extract_opcode_error_from_nargo_error(&err);
report_error_with_opcode_location(opcode_err_info, &debug, &context);
}

Err(crate::errors::CliError::NargoError(err))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "dynamic_index_failure"
type = "bin"
authors = [""]
compiler_version = "0.10.3"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x = [104, 101, 108, 108, 111]
z = "4"
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
fn main(mut x: [u32; 5], z: Field) {
let idx = z + 10;

x[z] = 4;

// Dynamic index is greater than length of the array
assert(x[idx] != 0);

// TODO(#2133): Provide more accurate call stacks for arrays merged in if statements
// if z != 20 {
// x[0] = x[4];
// } else {
// // TODO: Dynamic predicate still gives index out of bounds error
// if idx as u32 < 3 {
// x[idx] = 10;
// }
// x[idx] = 10;
// for i in 0..5 {
// x[idx] = x[i];
// }
// }
// assert(x[idx] != 0);
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
H4sIAAAAAAAA/+1YbW7DIAx1SJoPbeqPnSDqCSCEBv6tR1m09P5H2NAgcxjR1MZUrVSkyALBs7Hl91BeAeANfkb2/TFnWzRnwTx389x94WDOvjvLtw2REWIxOiweufpWbJEQe/bBEGbh7A6tNaiOfm/prK1Fjs4e0LkM2QxhHNCZ2J5sBadBa/78HsUCdDnhJfJLhblHmNQBC9+MBUqmndtCtoHPPIFvKizckJIf+34auklI8cE7M2rFezUetdBCafXZaSkn3evBjGbgRvRyEmdl5NmBvUCa5g7zd2WcnYtTFIR33hHWIlX+GE3+5jvnhHcmzB9fE0RiYtGUMUfCfTgR84JQobVLROwEf2sVitgJ/hexGM5TxNbHLGI28BZ+RayC5CK2aKKthF4CHblVcHtCuoOYPWmYSLgPR0i1s7j5n69qGsybEFINy1e1TVob+CR6FUabaCsh1YRxNZCmualJqAZa4gRY/vIIxxcx6kLKOxEAAA==
H4sIAAAAAAAA/+1YXW7DIAx2SJofberDThD1BBBCA2/rURYtvf8RNjTIHEY0bTFVW9VSZIHg85/sD+UZAF7gS7LPjzndojUL1rlb5+4LhTn96jTfJiIjxGJ0WDwS+lZskRB7tsEQZuH0Du01qI7+bOm0rUWO7h7QvQzpDGEc0J3YmWwFp0F7/v4e+QJ0OeElskuFuUeY1A4L34wFSqZd20K2gc08gW0qLNyQkh/7fhq6SUjxxjszasV7NR610EJp9d5pKSfd68GMZuBG9HISZ2Xk2YE9QZrmDvP3Tz8756coCGPeEdYiVf4YTf7mmHPCmAnzx9cIkXiwaML474LEPCFUaO8vJHaCn7UKSewEv5NYDOdBYusyk5h1vIVvEqsgOYktmmjrQC+BbrhVcPmBdAU++6FhIu7e3ECqncbN/3hV02BeZCDVsHxV26S1gU2iV2G0ibYOpJrQrwbSNDf1EKqBdnACLH95hPIBeRc5PjsRAAA=
Original file line number Diff line number Diff line change
@@ -1 +1 @@
H4sIAAAAAAAA/+1WW26DMBAczDOtFKkHqJTcwOZp/zVHKSrc/wgtrSEbMIpS1lIiZSW0MsLDsOuZ5RXAG/4i+LmEzQeyFnYd2gvk+SE+bJbbQgUEkxFXwhEbsZVH7OkdgmCOdY/IvZ3NY4+GSEhv6J4T2ReQHBCME9njeiZYwdk5eO4JF/DVRCZgP3dyj8tzxwmuRhENhTngLKrIrgF/QprjFrIuy67JO1WoT5mbVleyrNpaK60qXX3luig6XerGtKaRRpVFp/rKFL0FfoEfUYY8PHPLU4WM3xwx9sVX/QTz+RH3WT85H0DwpB9Ozg66XNjaI/bF8IltpoZ+y/A5Ytmr+fA54vrwceE8h896TMNnaOA7zsMnwVJIIfO7qYj+ayJd/xsmBp8hJXg8Q2LkXDvoPpwhpTZn5N4thhRj2au5IcW4bkgunKchrcdkSCkp5rDO4N+QqIi2GlIKPkPK4Efc3H//KR9PKQhHgWV8A0IPkd6XEAAA
H4sIAAAAAAAA/+1WbYqDMBB9xs/uQmEPsNDeIPEz+bc9ysrq/Y+w6zbaqUZKcQIt9IEMEfMcZzLv+Q7gA2cEf5ew8UDWwq5De4E8P+DLRrkNKiCcjLwSDmzkVh65p3cIwjnWPSL3djaOPRqQkN7QPSeyLyAxIBwnssf1TLDCs3PkuSe5gK8mMgH7uZN7XJ87TnI1DtFQmAMuQxXZNeBvkOa8hazLsmvyThXqW+am1ZUsq7bWSqtKVz+5LopOl7oxrWmkUWXRqb4yRW+J3+BnKEOePHObpwoZvzli7Iuv+gnm8yMes35ybkDwND8CD20+I7RH7ivziW2kgn6P+Ryx7NXcfI64bT4unpf5rGMyn6GBn7iYT4LlIIXM7+YQka7/h4nBJ0gJnk+QGHOuHek+nSClNmbk3j2CFGPZq7kgxbgtSC6elyCtYxKklBRzWGfwL0h0iLYKUgo+QcrgZ7i5//5TvjylIDkKLPELOATMzJcQAAA=

Large diffs are not rendered by default.

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
H4sIAAAAAAAA/9WOsREAAATE/k3EBvafSqNwlDTSpMtFAAgmTHtadxjvWvrlk+2xEhsKjNN4AQAA
H4sIAAAAAAAA/63OwQkAAAgCQG2i2qD9p+pTEPWs+wg+RAFAbNV5pt4Y/7aU42MX2r0K/NAAAAA=
Original file line number Diff line number Diff line change
@@ -1 +1 @@
H4sIAAAAAAAA/+WRMQ6AMAwDQ/lQ0iRtsvEVKtL/P4GllZBggw0vljxYPnkFgAR3zWwbju9Ey6WLsYhEzUFMO2ZvpijaipGRmh7ZmMPEqjev6CQc1NW5j7L03S78I/PkXOD5+xNlB/w7FAIAAA==
H4sIAAAAAAAA/62PsQ3AIAwEDVnIxjbYXVYJitl/hDREQkoZrvnu9HcAQIIvee45F/9BaXExVpFoJYjpwuLdFEV7NTJS07sYc5hY8+4NnYSDhjqPKcv7fuHbmZbmlQftqXpaIAEAAA==
Original file line number Diff line number Diff line change
@@ -1 +1 @@
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
Binary file not shown.
Loading

0 comments on commit 7668ff5

Please sign in to comment.