Skip to content

Commit

Permalink
Add --arithmetic-generics flag
Browse files Browse the repository at this point in the history
  • Loading branch information
jfecher committed Jul 30, 2024
1 parent 5b665ca commit 9446402
Show file tree
Hide file tree
Showing 20 changed files with 67 additions and 49 deletions.
4 changes: 2 additions & 2 deletions aztec_macros/src/utils/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub fn inject_fn(
let trait_id = None;
items.functions.push(UnresolvedFunctions { file_id, functions, trait_id, self_type: None });

let mut errors = Elaborator::elaborate(context, *crate_id, items, None);
let mut errors = Elaborator::elaborate(context, *crate_id, items, None, false);
errors.retain(|(error, _)| !CustomDiagnostic::from(error).is_warning());

if !errors.is_empty() {
Expand Down Expand Up @@ -241,7 +241,7 @@ pub fn inject_global(
let mut items = CollectedItems::default();
items.globals.push(UnresolvedGlobal { file_id, module_id, global_id, stmt_def: global });

let _errors = Elaborator::elaborate(context, *crate_id, items, None);
let _errors = Elaborator::elaborate(context, *crate_id, items, None, false);
}

pub fn fully_qualified_note_path(context: &HirContext, note_id: StructId) -> Option<String> {
Expand Down
22 changes: 10 additions & 12 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ pub struct CompileOptions {
/// Outputs the paths to any modified artifacts
#[arg(long, hide = true)]
pub show_artifact_paths: bool,

/// Outputs the paths to any modified artifacts
#[arg(long, hide = true)]
pub arithmetic_generics: bool,
}

pub fn parse_expression_width(input: &str) -> Result<ExpressionWidth, std::io::Error> {
Expand Down Expand Up @@ -262,21 +266,19 @@ pub fn add_dep(
pub fn check_crate(
context: &mut Context,
crate_id: CrateId,
deny_warnings: bool,
disable_macros: bool,
debug_comptime_in_file: Option<&str>,
options: &CompileOptions,
) -> CompilationResult<()> {
let macros: &[&dyn MacroProcessor] =
if disable_macros { &[] } else { &[&aztec_macros::AztecMacro as &dyn MacroProcessor] };
if options.disable_macros { &[] } else { &[&aztec_macros::AztecMacro as &dyn MacroProcessor] };

let mut errors = vec![];
let diagnostics = CrateDefMap::collect_defs(crate_id, context, debug_comptime_in_file, macros);
let diagnostics = CrateDefMap::collect_defs(crate_id, context, options.debug_comptime_in_file.as_deref(), options.arithmetic_generics, macros);
errors.extend(diagnostics.into_iter().map(|(error, file_id)| {
let diagnostic = CustomDiagnostic::from(&error);
diagnostic.in_file(file_id)
}));

if has_errors(&errors, deny_warnings) {
if has_errors(&errors, options.deny_warnings) {
Err(errors)
} else {
Ok(((), errors))
Expand Down Expand Up @@ -305,9 +307,7 @@ pub fn compile_main(
let (_, mut warnings) = check_crate(
context,
crate_id,
options.deny_warnings,
options.disable_macros,
options.debug_comptime_in_file.as_deref(),
options,
)?;

let main = context.get_main_function(&crate_id).ok_or_else(|| {
Expand Down Expand Up @@ -346,9 +346,7 @@ pub fn compile_contract(
let (_, warnings) = check_crate(
context,
crate_id,
options.deny_warnings,
options.disable_macros,
options.debug_comptime_in_file.as_deref(),
options,
)?;

// TODO: We probably want to error if contracts is empty
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl<'context> Elaborator<'context> {
self.def_maps,
self.crate_id,
self.debug_comptime_in_file,
self.enable_arithmetic_generics,
);

elaborator.function_context.push(FunctionContext::default());
Expand Down
13 changes: 11 additions & 2 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ pub struct Elaborator<'context> {
/// This map is used to lazily evaluate these globals if they're encountered before
/// they are elaborated (e.g. in a function's type or another global's RHS).
unresolved_globals: BTreeMap<GlobalId, UnresolvedGlobal>,

/// Temporary flag to enable the experimental arithmetic generics feature
enable_arithmetic_generics: bool,
}

#[derive(Default)]
Expand All @@ -198,6 +201,7 @@ impl<'context> Elaborator<'context> {
def_maps: &'context mut DefMaps,
crate_id: CrateId,
debug_comptime_in_file: Option<FileId>,
enable_arithmetic_generics: bool,
) -> Self {
Self {
scopes: ScopeForest::default(),
Expand All @@ -219,19 +223,22 @@ impl<'context> Elaborator<'context> {
comptime_scopes: vec![HashMap::default()],
debug_comptime_in_file,
unresolved_globals: BTreeMap::new(),
enable_arithmetic_generics,
}
}

pub fn from_context(
context: &'context mut Context,
crate_id: CrateId,
debug_comptime_in_file: Option<FileId>,
enable_arithmetic_generics: bool,
) -> Self {
Self::new(
&mut context.def_interner,
&mut context.def_maps,
crate_id,
debug_comptime_in_file,
enable_arithmetic_generics,
)
}

Expand All @@ -240,17 +247,19 @@ impl<'context> Elaborator<'context> {
crate_id: CrateId,
items: CollectedItems,
debug_comptime_in_file: Option<FileId>,
enable_arithmetic_generics: bool,
) -> Vec<(CompilationError, FileId)> {
Self::elaborate_and_return_self(context, crate_id, items, debug_comptime_in_file).errors
Self::elaborate_and_return_self(context, crate_id, items, debug_comptime_in_file, enable_arithmetic_generics).errors
}

pub fn elaborate_and_return_self(
context: &'context mut Context,
crate_id: CrateId,
items: CollectedItems,
debug_comptime_in_file: Option<FileId>,
enable_arithmetic_generics: bool,
) -> Self {
let mut this = Self::from_context(context, crate_id, debug_comptime_in_file);
let mut this = Self::from_context(context, crate_id, debug_comptime_in_file, enable_arithmetic_generics);
this.elaborate_items(items);
this.check_and_pop_function_context();
this
Expand Down
11 changes: 10 additions & 1 deletion compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,14 +385,23 @@ impl<'context> Elaborator<'context> {
}
UnresolvedTypeExpression::Constant(int, _) => Type::Constant(int),
UnresolvedTypeExpression::BinaryOperation(lhs, op, rhs, _) => {
let (lhs_span, rhs_span) = (lhs.span(), rhs.span());
let lhs = self.convert_expression_type(*lhs);
let rhs = self.convert_expression_type(*rhs);

match (lhs, rhs) {
(Type::Constant(lhs), Type::Constant(rhs)) => {
Type::Constant(op.function(lhs, rhs))
}
(lhs, rhs) => Type::InfixExpr(Box::new(lhs), op, Box::new(rhs)),
(lhs, rhs) => {
if !self.enable_arithmetic_generics {
let span =
if !matches!(lhs, Type::Constant(_)) { lhs_span } else { rhs_span };
self.push_err(ResolverError::InvalidArrayLengthExpr { span });
}

Type::InfixExpr(Box::new(lhs), op, Box::new(rhs)).canonicalize()
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/comptime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn interpret_helper(src: &str) -> Result<Value, InterpreterError> {

let main = context.get_main_function(&krate).expect("Expected 'main' function");
let mut elaborator =
Elaborator::elaborate_and_return_self(&mut context, krate, collector.items, None);
Elaborator::elaborate_and_return_self(&mut context, krate, collector.items, None, false);
assert_eq!(elaborator.errors.len(), 0);

let mut interpreter = elaborator.setup_interpreter();
Expand Down
5 changes: 4 additions & 1 deletion compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ impl DefCollector {
ast: SortedModule,
root_file_id: FileId,
debug_comptime_in_file: Option<&str>,
enable_arithmetic_generics: bool,
macro_processors: &[&dyn MacroProcessor],
) -> Vec<(CompilationError, FileId)> {
let mut errors: Vec<(CompilationError, FileId)> = vec![];
Expand All @@ -264,6 +265,7 @@ impl DefCollector {
dep.crate_id,
context,
debug_comptime_in_file,
enable_arithmetic_generics,
macro_processors,
));

Expand Down Expand Up @@ -387,7 +389,8 @@ impl DefCollector {
});

let mut more_errors =
Elaborator::elaborate(context, crate_id, def_collector.items, debug_comptime_in_file);
Elaborator::elaborate(context, crate_id, def_collector.items, debug_comptime_in_file, enable_arithmetic_generics);

errors.append(&mut more_errors);

for macro_processor in macro_processors {
Expand Down
2 changes: 2 additions & 0 deletions compiler/noirc_frontend/src/hir/def_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl CrateDefMap {
crate_id: CrateId,
context: &mut Context,
debug_comptime_in_file: Option<&str>,
enable_arithmetic_generics: bool,
macro_processors: &[&dyn MacroProcessor],
) -> Vec<(CompilationError, FileId)> {
// Check if this Crate has already been compiled
Expand Down Expand Up @@ -125,6 +126,7 @@ impl CrateDefMap {
ast,
root_file_id,
debug_comptime_in_file,
enable_arithmetic_generics,
macro_processors,
));

Expand Down
9 changes: 9 additions & 0 deletions compiler/noirc_frontend/src/hir/resolution/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ pub enum ResolverError {
NonFunctionInAnnotation { span: Span },
#[error("Unknown annotation")]
UnknownAnnotation { span: Span },
#[error("Arithmetic Generics are currently experimental")]
ArithmeticGenerics { span: Span },
}

impl ResolverError {
Expand Down Expand Up @@ -467,6 +469,13 @@ impl<'a> From<&'a ResolverError> for Diagnostic {
*span,
)
},
ResolverError::ArithmeticGenerics { span } => {
Diagnostic::simple_warning(
"Arithmetic Generics are currently an experimental feature".into(),
"Use --arithmetic-generics to enable this feature".into(),
*span,
)
},
}
}
}
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,7 @@ impl Type {
/// For example:
/// - `canonicalize[((1 + N) + M) + 2] = (M + N) + 3`
/// - `canonicalize[A + 2 * B + 3 - 2] = A + (B * 2) + 3 - 2`
fn canonicalize(&self) -> Type {
pub fn canonicalize(&self) -> Type {
match self.follow_bindings() {
Type::InfixExpr(lhs, op, rhs) => {
if let Some(value) = self.evaluate_to_u32() {
Expand Down
5 changes: 3 additions & 2 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ pub(crate) fn get_program(src: &str) -> (ParsedModule, Context, Vec<(Compilation
&mut context,
program.clone().into_sorted(),
root_file_id,
None, // No debug_comptime_in_file
&[], // No macro processors
None, // No debug_comptime_in_file
false, // Disallow arithmetic generics
&[], // No macro processors
));
}
(program, context, errors)
Expand Down
2 changes: 1 addition & 1 deletion tooling/lsp/src/notifications/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ pub(crate) fn process_workspace_for_noir_document(
let (mut context, crate_id) =
crate::prepare_package(&workspace_file_manager, &parsed_files, package);

let file_diagnostics = match check_crate(&mut context, crate_id, false, false, None) {
let file_diagnostics = match check_crate(&mut context, crate_id, &Default::default()) {
Ok(((), warnings)) => warnings,
Err(errors_and_warnings) => errors_and_warnings,
};
Expand Down
2 changes: 1 addition & 1 deletion tooling/lsp/src/requests/code_lens_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fn on_code_lens_request_inner(
let (mut context, crate_id) = prepare_source(source_string, state);
// We ignore the warnings and errors produced by compilation for producing code lenses
// because we can still get the test functions even if compilation fails
let _ = check_crate(&mut context, crate_id, false, false, None);
let _ = check_crate(&mut context, crate_id, &Default::default());

let collected_lenses =
collect_lenses_for_package(&context, crate_id, &workspace, package, None);
Expand Down
2 changes: 1 addition & 1 deletion tooling/lsp/src/requests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ where
interner = def_interner;
} else {
// We ignore the warnings and errors produced by compilation while resolving the definition
let _ = noirc_driver::check_crate(&mut context, crate_id, false, false, None);
let _ = noirc_driver::check_crate(&mut context, crate_id, &Default::default());
interner = &context.def_interner;
}

Expand Down
2 changes: 1 addition & 1 deletion tooling/lsp/src/requests/test_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn on_test_run_request_inner(
Some(package) => {
let (mut context, crate_id) =
crate::prepare_package(&workspace_file_manager, &parsed_files, package);
if check_crate(&mut context, crate_id, false, false, None).is_err() {
if check_crate(&mut context, crate_id, &Default::default()).is_err() {
let result = NargoTestRunResult {
id: params.id.clone(),
result: "error".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion tooling/lsp/src/requests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn on_tests_request_inner(
crate::prepare_package(&workspace_file_manager, &parsed_files, package);
// We ignore the warnings and errors produced by compilation for producing tests
// because we can still get the test functions even if compilation fails
let _ = check_crate(&mut context, crate_id, false, false, None);
let _ = check_crate(&mut context, crate_id, &Default::default());

// We don't add test headings for a package if it contains no `#[test]` functions
get_package_tests_in_crate(&context, &crate_id, &package.name)
Expand Down
2 changes: 1 addition & 1 deletion tooling/nargo_cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn generate_compile_success_empty_tests(test_file: &mut File, test_data_dir: &Pa
&test_dir,
&format!(
r#"
nargo.arg("info").arg("--json").arg("--force");
nargo.arg("info").arg("--arithmetic-generics").arg("--json").arg("--force");
{assert_zero_opcodes}"#,
),
Expand Down
14 changes: 4 additions & 10 deletions tooling/nargo_cli/src/cli/check_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,7 @@ fn check_package(
check_crate_and_report_errors(
&mut context,
crate_id,
compile_options.deny_warnings,
compile_options.disable_macros,
compile_options.silence_warnings,
compile_options.debug_comptime_in_file.as_deref(),
compile_options,
)?;

if package.is_library() || package.is_contract() {
Expand Down Expand Up @@ -157,14 +154,11 @@ fn create_input_toml_template(
pub(crate) fn check_crate_and_report_errors(
context: &mut Context,
crate_id: CrateId,
deny_warnings: bool,
disable_macros: bool,
silence_warnings: bool,
debug_comptime_in_file: Option<&str>,
options: &CompileOptions,
) -> Result<(), CompileError> {
let result =
check_crate(context, crate_id, deny_warnings, disable_macros, debug_comptime_in_file);
report_errors(result, &context.file_manager, deny_warnings, silence_warnings)
check_crate(context, crate_id, options);
report_errors(result, &context.file_manager, options.deny_warnings, options.silence_warnings)
}

#[cfg(test)]
Expand Down
5 changes: 1 addition & 4 deletions tooling/nargo_cli/src/cli/export_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,7 @@ fn compile_exported_functions(
check_crate_and_report_errors(
&mut context,
crate_id,
compile_options.deny_warnings,
compile_options.disable_macros,
compile_options.silence_warnings,
compile_options.debug_comptime_in_file.as_deref(),
compile_options,
)?;

let exported_functions = context.get_all_exported_functions_in_crate(&crate_id);
Expand Down
9 changes: 2 additions & 7 deletions tooling/nargo_cli/src/cli/test_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,7 @@ fn run_test<S: BlackBoxFunctionSolver<FieldElement> + Default>(
check_crate(
&mut context,
crate_id,
compile_options.deny_warnings,
compile_options.disable_macros,
compile_options.debug_comptime_in_file.as_deref(),
compile_options,
)
.expect("Any errors should have occurred when collecting test functions");

Expand Down Expand Up @@ -240,10 +238,7 @@ fn get_tests_in_package(
check_crate_and_report_errors(
&mut context,
crate_id,
compile_options.deny_warnings,
compile_options.disable_macros,
compile_options.silence_warnings,
compile_options.debug_comptime_in_file.as_deref(),
compile_options,
)?;

Ok(context
Expand Down

0 comments on commit 9446402

Please sign in to comment.