Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: handle warnings in evaluator #3205

Merged
merged 26 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
af39408
return warnings from evaluator
guipublic Oct 17, 2023
f3c0094
cargo.lock
guipublic Oct 17, 2023
ddac566
Merge branch 'master' into gd/issue_3131
guipublic Oct 17, 2023
18da5dd
contracts do not handle warnings
guipublic Oct 17, 2023
6a856ed
Merge branch 'master' into gd/issue_3131
guipublic Oct 17, 2023
70a64f9
Merge branch 'master' into gd/issue_3131
guipublic Oct 20, 2023
116ef16
separate warnings from errors in the evaluator
guipublic Oct 20, 2023
44c866a
Merge branch 'master' into gd/issue_3131
guipublic Oct 20, 2023
4f8fb9a
fix some cargo fmt
guipublic Oct 20, 2023
9b95d56
cargo fmt
guipublic Oct 20, 2023
39b2f0b
Merge branch 'master' into gd/issue_3131
guipublic Oct 23, 2023
9ed7209
remove comments
guipublic Oct 23, 2023
b4931c8
Merge branch 'master' into gd/issue_3131
kevaundray Oct 23, 2023
848a870
Merge branch 'master' into gd/issue_3131
guipublic Oct 24, 2023
24ec025
chore: Update ACIR artifacts (#3263)
kevaundray Oct 24, 2023
09f8a6d
fix: recompile artefacts from a different noir version (#3248)
guipublic Oct 24, 2023
d3f7be2
feat(debugger): Print limited source code context (#3217)
mverzilli Oct 24, 2023
5db9514
chore(docs): Document `nargo fmt` (#3262)
Savio-Sou Oct 24, 2023
6d116f7
chore(docs): Rearrange NoirJS section (#3260)
Savio-Sou Oct 24, 2023
19ab5b7
feat: noir-wasm takes dependency graph (#3213)
alexghr Oct 24, 2023
d05a423
feat!: Switch to new pedersen implementation (#3151)
kevaundray Oct 24, 2023
a82543a
fmt
guipublic Oct 24, 2023
ef6f1e8
Merge branch 'master' into gd/issue_3131
guipublic Oct 24, 2023
b12974b
fmt
guipublic Oct 24, 2023
17fc22d
Merge branch 'master' into gd/issue_3131
guipublic Oct 24, 2023
2303495
Merge branch 'master' into gd/issue_3131
guipublic Oct 26, 2023
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
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions compiler/noirc_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ noirc_frontend.workspace = true
noirc_evaluator.workspace = true
noirc_abi.workspace = true
acvm.workspace = true
iter-extended.workspace = true
fm.workspace = true
serde.workspace = true
base64.workspace = true
Expand Down
41 changes: 26 additions & 15 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
use clap::Args;
use debug::filter_relevant_files;
use fm::FileId;
use iter_extended::vecmap;
use noirc_abi::{AbiParameter, AbiType, ContractEvent};
use noirc_errors::{CustomDiagnostic, FileDiagnostic};
use noirc_evaluator::errors::RuntimeError;
use noirc_evaluator::errors::SsaReport;
use noirc_evaluator::{create_circuit, into_abi_params};
use noirc_frontend::graph::{CrateId, CrateName};
use noirc_frontend::hir::def_map::{Contract, CrateDefMap};
Expand Down Expand Up @@ -164,7 +166,7 @@ pub fn compile_main(
cached_program: Option<CompiledProgram>,
force_compile: bool,
) -> CompilationResult<CompiledProgram> {
let (_, warnings) = check_crate(context, crate_id, options.deny_warnings)?;
let (_, mut warnings) = check_crate(context, crate_id, options.deny_warnings)?;

let main = match context.get_main_function(&crate_id) {
Some(m) => m,
Expand All @@ -178,8 +180,14 @@ pub fn compile_main(
}
};

let compiled_program = compile_no_check(context, options, main, cached_program, force_compile)
.map_err(FileDiagnostic::from)?;
let (compiled_program, compilation_warnings) =
compile_no_check(context, options, main, cached_program, force_compile)
.map_err(FileDiagnostic::from)?;
let compilation_warnings = vecmap(compilation_warnings, FileDiagnostic::from);
if options.deny_warnings && !compilation_warnings.is_empty() {
return Err(compilation_warnings);
}
warnings.extend(compilation_warnings);

if options.print_acir {
println!("Compiled ACIR for main (unoptimized):");
Expand Down Expand Up @@ -274,7 +282,7 @@ fn compile_contract_inner(
}

let function = match compile_no_check(context, options, function_id, None, true) {
Ok(function) => function,
Ok((function, _warnings)) => function,
guipublic marked this conversation as resolved.
Show resolved Hide resolved
Err(new_error) => {
errors.push(FileDiagnostic::from(new_error));
continue;
Expand Down Expand Up @@ -332,7 +340,7 @@ pub fn compile_no_check(
main_function: FuncId,
cached_program: Option<CompiledProgram>,
force_compile: bool,
) -> Result<CompiledProgram, RuntimeError> {
) -> Result<(CompiledProgram, Vec<SsaReport>), RuntimeError> {
let program = monomorphize(main_function, &context.def_interner);

let hash = fxhash::hash64(&program);
Expand All @@ -342,22 +350,25 @@ pub fn compile_no_check(
if !(force_compile || options.print_acir || options.show_brillig || options.show_ssa) {
if let Some(cached_program) = cached_program {
if hash == cached_program.hash {
return Ok(cached_program);
return Ok((cached_program, Vec::new()));
guipublic marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

let (circuit, debug, abi) =
let (circuit, debug, abi, warnings) =
create_circuit(context, program, options.show_ssa, options.show_brillig)?;

let file_map = filter_relevant_files(&[debug.clone()], &context.file_manager);

Ok(CompiledProgram {
hash,
circuit,
debug,
abi,
file_map,
noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(),
})
Ok((
CompiledProgram {
hash,
circuit,
debug,
abi,
file_map,
noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(),
},
warnings,
))
}
42 changes: 32 additions & 10 deletions compiler/noirc_evaluator/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,37 @@ fn format_failed_constraint(message: &Option<String>) -> String {
}
}

#[derive(Debug)]
pub enum SsaReport {
Warning(InternalWarning),
}

impl From<SsaReport> for FileDiagnostic {
fn from(error: SsaReport) -> FileDiagnostic {
match error {
SsaReport::Warning(warning) => {
let InternalWarning::ReturnConstant { ref call_stack } = warning;
let call_stack = vecmap(call_stack, |location| *location);
let file_id = call_stack.last().map(|location| location.file).unwrap_or_default();
let message = warning.to_string();
let location = call_stack.last().expect("Expected RuntimeError to have a location");
let diagnostic = Diagnostic::simple_warning(
message,
"constant value".to_string(),
location.span,
);
diagnostic.in_file(file_id).with_call_stack(call_stack)
}
}
}
}

#[derive(Debug, PartialEq, Eq, Clone, Error)]
pub enum InternalWarning {
#[error("Returning a constant value is not allowed")]
ReturnConstant { call_stack: CallStack },
}

#[derive(Debug, PartialEq, Eq, Clone, Error)]
pub enum InternalError {
#[error("ICE: Both expressions should have degree<=1")]
Expand All @@ -69,8 +100,6 @@ pub enum InternalError {
UndeclaredAcirVar { call_stack: CallStack },
#[error("ICE: Expected {expected:?}, found {found:?}")]
UnExpected { expected: String, found: String, call_stack: CallStack },
#[error("Returning a constant value is not allowed")]
ReturnConstant { call_stack: CallStack },
}

impl RuntimeError {
Expand All @@ -83,8 +112,7 @@ impl RuntimeError {
| InternalError::MissingArg { call_stack, .. }
| InternalError::NotAConstant { call_stack, .. }
| InternalError::UndeclaredAcirVar { call_stack }
| InternalError::UnExpected { call_stack, .. }
| InternalError::ReturnConstant { call_stack, .. },
| InternalError::UnExpected { call_stack, .. },
)
| RuntimeError::FailedConstraint { call_stack, .. }
| RuntimeError::IndexOutOfBounds { call_stack, .. }
Expand All @@ -111,12 +139,6 @@ impl From<RuntimeError> for FileDiagnostic {
impl RuntimeError {
fn into_diagnostic(self) -> Diagnostic {
match self {
RuntimeError::InternalError(InternalError::ReturnConstant { ref call_stack }) => {
let message = self.to_string();
let location =
call_stack.back().expect("Expected RuntimeError to have a location");
Diagnostic::simple_error(message, "constant value".to_string(), location.span)
}
RuntimeError::InternalError(cause) => {
Diagnostic::simple_error(
"Internal Consistency Evaluators Errors: \n
Expand Down
7 changes: 4 additions & 3 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

use std::collections::BTreeSet;

use crate::errors::RuntimeError;
use crate::errors::{RuntimeError, SsaReport};
use acvm::acir::{
circuit::{Circuit, PublicInputs},
native_types::Witness,
Expand Down Expand Up @@ -72,7 +72,7 @@ pub fn create_circuit(
program: Program,
enable_ssa_logging: bool,
enable_brillig_logging: bool,
) -> Result<(Circuit, DebugInfo, Abi), RuntimeError> {
) -> Result<(Circuit, DebugInfo, Abi, Vec<SsaReport>), RuntimeError> {
let func_sig = program.main_function_signature.clone();
let mut generated_acir =
optimize_into_acir(program, enable_ssa_logging, enable_brillig_logging)?;
Expand All @@ -83,6 +83,7 @@ pub fn create_circuit(
locations,
input_witnesses,
assert_messages,
warnings,
..
} = generated_acir;

Expand Down Expand Up @@ -119,7 +120,7 @@ pub fn create_circuit(
let (optimized_circuit, transformation_map) = acvm::compiler::optimize(circuit);
debug_info.update_acir(transformation_map);

Ok((optimized_circuit, debug_info, abi))
Ok((optimized_circuit, debug_info, abi, warnings))
}

// This is just a convenience object to bundle the ssa with `print_ssa_passes` for debug printing.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::generated_acir::GeneratedAcir;
use crate::brillig::brillig_gen::brillig_directive;
use crate::brillig::brillig_ir::artifact::GeneratedBrillig;
use crate::errors::{InternalError, RuntimeError};
use crate::errors::{InternalError, RuntimeError, SsaReport};
use crate::ssa::acir_gen::{AcirDynamicArray, AcirValue};
use crate::ssa::ir::dfg::CallStack;
use crate::ssa::ir::types::Type as SsaType;
Expand Down Expand Up @@ -1162,8 +1162,9 @@ impl AcirContext {
}

/// Terminates the context and takes the resulting `GeneratedAcir`
pub(crate) fn finish(mut self, inputs: Vec<u32>) -> GeneratedAcir {
pub(crate) fn finish(mut self, inputs: Vec<u32>, warnings: Vec<SsaReport>) -> GeneratedAcir {
self.acir_ir.input_witnesses = vecmap(inputs, Witness);
self.acir_ir.warnings = warnings;
self.acir_ir
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::BTreeMap;

use crate::{
brillig::{brillig_gen::brillig_directive, brillig_ir::artifact::GeneratedBrillig},
errors::{InternalError, RuntimeError},
errors::{InternalError, RuntimeError, SsaReport},
ssa::ir::dfg::CallStack,
};

Expand Down Expand Up @@ -53,6 +53,8 @@ pub(crate) struct GeneratedAcir {

/// Correspondence between an opcode index and the error message associated with it.
pub(crate) assert_messages: BTreeMap<OpcodeLocation, String>,

pub(crate) warnings: Vec<SsaReport>,
}

impl GeneratedAcir {
Expand Down
26 changes: 13 additions & 13 deletions compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use super::{
use crate::brillig::brillig_ir::artifact::GeneratedBrillig;
use crate::brillig::brillig_ir::BrilligContext;
use crate::brillig::{brillig_gen::brillig_fn::FunctionContext as BrilligFunctionContext, Brillig};
use crate::errors::{InternalError, RuntimeError};
use crate::errors::{InternalError, InternalWarning, RuntimeError, SsaReport};
pub(crate) use acir_ir::generated_acir::GeneratedAcir;
use acvm::{
acir::{circuit::opcodes::BlockId, native_types::Expression},
Expand Down Expand Up @@ -201,9 +201,9 @@ impl Context {
self.convert_ssa_instruction(*instruction_id, dfg, ssa, &brillig, last_array_uses)?;
}

self.convert_ssa_return(entry_block.unwrap_terminator(), dfg)?;
let warnings = self.convert_ssa_return(entry_block.unwrap_terminator(), dfg)?;

Ok(self.acir_context.finish(input_witness.collect()))
Ok(self.acir_context.finish(input_witness.collect(), warnings))
}

fn convert_brillig_main(
Expand Down Expand Up @@ -240,7 +240,7 @@ impl Context {
self.acir_context.return_var(acir_var)?;
}

Ok(self.acir_context.finish(witness_inputs))
Ok(self.acir_context.finish(witness_inputs, Vec::new()))
}

/// Adds and binds `AcirVar`s for each numeric block parameter or block parameter array element.
Expand Down Expand Up @@ -1247,8 +1247,8 @@ impl Context {
&mut self,
terminator: &TerminatorInstruction,
dfg: &DataFlowGraph,
) -> Result<(), InternalError> {
let (return_values, _call_stack) = match terminator {
) -> Result<Vec<SsaReport>, InternalError> {
let (return_values, call_stack) = match terminator {
TerminatorInstruction::Return { return_values, call_stack } => {
(return_values, call_stack)
}
Expand All @@ -1258,16 +1258,16 @@ impl Context {
// The return value may or may not be an array reference. Calling `flatten_value_list`
// will expand the array if there is one.
let return_acir_vars = self.flatten_value_list(return_values, dfg);
let mut warnings = Vec::new();
for acir_var in return_acir_vars {
// TODO(Guillaume) -- disabled as it has shown to break
// TODO with important programs. We will add it back once
// TODO we change it to a warning.
// if self.acir_context.is_constant(&acir_var) {
// return Err(InternalError::ReturnConstant { call_stack: call_stack.clone() });
// }
if self.acir_context.is_constant(&acir_var) {
warnings.push(SsaReport::Warning(InternalWarning::ReturnConstant {
call_stack: call_stack.clone(),
}));
}
self.acir_context.return_var(acir_var)?;
}
Ok(())
Ok(warnings)
}

/// Gets the cached `AcirVar` that was converted from the corresponding `ValueId`. If it does
Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo/src/ops/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn run_test<B: BlackBoxFunctionSolver>(
) -> TestStatus {
let program = compile_no_check(context, config, test_function.get_id(), None, false);
match program {
Ok(program) => {
Ok((program, _)) => {
// Run the backend to ensure the PWG evaluates functions like std::hash::pedersen,
// otherwise constraints involving these expressions will not error.
let circuit_execution =
Expand Down
Loading