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
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
78262c96d5b116c77e50653f9059da60824db812
2174ffb92b5d88e7e0926c91f42bc7f849e8ddc1
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,11 @@ global TUBE_PROOF_LENGTH = RECURSIVE_PROOF_LENGTH; // in the future these can di
global VERIFICATION_KEY_LENGTH_IN_FIELDS = 128;

// The length is 2 + AvmFlavor::NUM_PRECOMPUTED_ENTITIES * 4
global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 2 + 16 * 4;
global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS: u32 = 2 + 16 * 4;
// `AVM_PROOF_LENGTH_IN_FIELDS` must be updated when AVM circuit changes.
// To determine latest value, hover `COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS`
// in barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp
global AVM_PROOF_LENGTH_IN_FIELDS = 3812;
global AVM_PROOF_LENGTH_IN_FIELDS: u32 = 3812;
/**
* Enumerate the hash_indices which are used for pedersen hashing.
* We start from 1 to avoid the default generators. The generator indices are listed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ pub fn inject_note_exports(
note.borrow().id,
"get_note_type_id",
false,
true,
)
.ok_or((
AztecMacroError::CouldNotExportStorageLayout {
Expand Down
1 change: 1 addition & 0 deletions noir/noir-repo/aztec_macros/src/transforms/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ pub fn assign_storage_slots(
storage_struct.borrow().id,
"init",
false,
true,
)
.ok_or((
AztecMacroError::CouldNotAssignStorageSlots {
Expand Down
6 changes: 6 additions & 0 deletions noir/noir-repo/aztec_macros/src/utils/parse_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ fn empty_expression(expression: &mut Expression) {
empty_unresolved_type(&mut path.typ);
empty_path(&mut path.trait_path);
empty_ident(&mut path.impl_item);
empty_type_args(&mut path.trait_generics);
}
ExpressionKind::TypePath(path) => {
empty_unresolved_type(&mut path.typ);
empty_ident(&mut path.item);
empty_type_args(&mut path.turbofish);
}
ExpressionKind::Quote(..)
| ExpressionKind::Resolved(_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,15 @@ impl<F: AcirField> AcirContext<F> {
Ok(())
}

/// Insert the MemoryInit for the Return Data array, using the provided witnesses
pub(crate) fn initialize_return_data(&mut self, block_id: BlockId, init: Vec<Witness>) {
self.acir_ir.push_opcode(Opcode::MemoryInit {
block_id,
init,
block_type: BlockType::ReturnData,
});
}

/// Initializes an array in memory with the given values `optional_values`.
/// If `optional_values` is empty, then the array is initialized with zeros.
pub(crate) fn initialize_array(
Expand Down
68 changes: 33 additions & 35 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,16 +434,9 @@ impl<'a> Context<'a> {
for instruction_id in entry_block.instructions() {
warnings.extend(self.convert_ssa_instruction(*instruction_id, dfg, ssa, brillig)?);
}

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

let call_data_arrays: Vec<ValueId> =
self.data_bus.call_data.iter().map(|cd| cd.array_id).collect();
for call_data_array in call_data_arrays {
self.ensure_array_is_initialized(call_data_array, dfg)?;
}

// TODO: This is a naive method of assigning the return values to their witnesses as
// we're likely to get a number of constraints which are asserting one witness to be equal to another.
//
Expand All @@ -452,13 +445,42 @@ impl<'a> Context<'a> {
self.acir_context.assert_eq_var(*witness_var, return_var, None)?;
}

self.initialize_databus(&return_witnesses, dfg)?;
warnings.extend(return_warnings);
warnings.extend(self.acir_context.warnings.clone());

// Add the warnings from the alter Ssa passes
Ok(self.acir_context.finish(input_witness, return_witnesses, warnings))
}

fn initialize_databus(
&mut self,
witnesses: &Vec<Witness>,
dfg: &DataFlowGraph,
) -> Result<(), RuntimeError> {
// Initialize return_data using provided witnesses
if let Some(return_data) = self.data_bus.return_data {
let block_id = self.block_id(&return_data);
let already_initialized = self.initialized_arrays.contains(&block_id);
if !already_initialized {
// We hijack ensure_array_is_initialized() because we want the return data to use the return value witnesses,
// but the databus contains the computed values instead, that have just been asserted to be equal to the return values.
// We do not use initialize_array either for the case where a constant value is returned.
// In that case, the constant value has already been assigned a witness and the returned acir vars will be
// converted to it, instead of the corresponding return value witness.
self.acir_context.initialize_return_data(block_id, witnesses.to_owned());
}
}

// Initialize call_data
let call_data_arrays: Vec<ValueId> =
self.data_bus.call_data.iter().map(|cd| cd.array_id).collect();
for call_data_array in call_data_arrays {
self.ensure_array_is_initialized(call_data_array, dfg)?;
}
Ok(())
}

fn convert_brillig_main(
mut self,
main_func: &Function,
Expand Down Expand Up @@ -1792,19 +1814,9 @@ impl<'a> Context<'a> {
_ => unreachable!("ICE: Program must have a singular return"),
};

return_values.iter().fold(0, |acc, value_id| {
let is_databus = self
.data_bus
.return_data
.map_or(false, |return_databus| dfg[*value_id] == dfg[return_databus]);

if is_databus {
// We do not return value for the data bus.
acc
} else {
acc + dfg.type_of_value(*value_id).flattened_size()
}
})
return_values
.iter()
.fold(0, |acc, value_id| acc + dfg.type_of_value(*value_id).flattened_size())
}

/// Converts an SSA terminator's return values into their ACIR representations
Expand All @@ -1824,27 +1836,13 @@ impl<'a> Context<'a> {
let mut has_constant_return = false;
let mut return_vars: Vec<AcirVar> = Vec::new();
for value_id in return_values {
let is_databus = self
.data_bus
.return_data
.map_or(false, |return_databus| dfg[*value_id] == dfg[return_databus]);
let value = self.convert_value(*value_id, dfg);

// `value` may or may not be an array reference. Calling `flatten` will expand the array if there is one.
let acir_vars = self.acir_context.flatten(value)?;
for (acir_var, _) in acir_vars {
has_constant_return |= self.acir_context.is_constant(&acir_var);
if is_databus {
// We do not return value for the data bus.
self.ensure_array_is_initialized(
self.data_bus.return_data.expect(
"`is_databus == true` implies `data_bus.return_data` is `Some`",
),
dfg,
)?;
} else {
return_vars.push(acir_var);
}
return_vars.push(acir_var);
}
}

Expand Down
14 changes: 13 additions & 1 deletion noir/noir-repo/compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use acvm::{acir::AcirField, FieldElement};
use iter_extended::vecmap;
use noirc_errors::{Span, Spanned};

use super::{AsTraitPath, UnaryRhsMemberAccess};
use super::{AsTraitPath, TypePath, UnaryRhsMemberAccess};

#[derive(Debug, PartialEq, Eq, Clone)]
pub enum ExpressionKind {
Expand All @@ -38,6 +38,7 @@ pub enum ExpressionKind {
Comptime(BlockExpression, Span),
Unsafe(BlockExpression, Span),
AsTraitPath(AsTraitPath),
TypePath(TypePath),

// This variant is only emitted when inlining the result of comptime
// code. It is used to translate function values back into the AST while
Expand Down Expand Up @@ -621,6 +622,7 @@ impl Display for ExpressionKind {
write!(f, "quote {{ {} }}", tokens.join(" "))
}
AsTraitPath(path) => write!(f, "{path}"),
TypePath(path) => write!(f, "{path}"),
InternedStatement(_) => write!(f, "?InternedStatement"),
}
}
Expand Down Expand Up @@ -787,6 +789,16 @@ impl Display for AsTraitPath {
}
}

impl Display for TypePath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}::{}", self.typ, self.item)?;
if !self.turbofish.is_empty() {
write!(f, "::{}", self.turbofish)?;
}
Ok(())
}
}

impl FunctionDefinition {
pub fn normal(
name: &Ident,
Expand Down
10 changes: 10 additions & 0 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,16 @@ pub struct AsTraitPath {
pub impl_item: Ident,
}

/// A special kind of path in the form `Type::ident::<turbofish>`
/// Unlike normal paths, the type here can be a primitive type or
/// interned type.
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct TypePath {
pub typ: UnresolvedType,
pub item: Ident,
pub turbofish: GenericTypeArgs,
}

// Note: Path deliberately doesn't implement Recoverable.
// No matter which default value we could give in Recoverable::error,
// it would most likely cause further errors during name resolution
Expand Down
20 changes: 19 additions & 1 deletion noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{

use super::{
FunctionReturnType, GenericTypeArgs, IntegerBitSize, ItemVisibility, Pattern, Signedness,
TraitImplItemKind, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType,
TraitImplItemKind, TypePath, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType,
UnresolvedTypeData, UnresolvedTypeExpression,
};

Expand Down Expand Up @@ -340,6 +340,10 @@ pub trait Visitor {
true
}

fn visit_type_path(&mut self, _: &TypePath, _: Span) -> bool {
true
}

fn visit_unresolved_type(&mut self, _: &UnresolvedType) -> bool {
true
}
Expand Down Expand Up @@ -838,6 +842,7 @@ impl Expression {
ExpressionKind::AsTraitPath(as_trait_path) => {
as_trait_path.accept(self.span, visitor);
}
ExpressionKind::TypePath(path) => path.accept(self.span, visitor),
ExpressionKind::Quote(tokens) => visitor.visit_quote(tokens),
ExpressionKind::Resolved(expr_id) => visitor.visit_resolved_expression(*expr_id),
ExpressionKind::Interned(id) => visitor.visit_interned_expression(*id),
Expand Down Expand Up @@ -1208,6 +1213,19 @@ impl AsTraitPath {
}
}

impl TypePath {
pub fn accept(&self, span: Span, visitor: &mut impl Visitor) {
if visitor.visit_type_path(self, span) {
self.accept_children(visitor);
}
}

pub fn accept_children(&self, visitor: &mut impl Visitor) {
self.typ.accept(visitor);
self.turbofish.accept(visitor);
}
}

impl UnresolvedType {
pub fn accept(&self, visitor: &mut impl Visitor) {
if visitor.visit_unresolved_type(self) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
HirArrayLiteral, HirBinaryOp, HirBlockExpression, HirCallExpression, HirCastExpression,
HirConstructorExpression, HirExpression, HirIfExpression, HirIndexExpression,
HirInfixExpression, HirLambda, HirMemberAccess, HirMethodCallExpression,
HirMethodReference, HirPrefixExpression,
HirPrefixExpression,
},
traits::TraitConstraint,
},
Expand Down Expand Up @@ -76,6 +76,7 @@ impl<'context> Elaborator<'context> {
(HirExpression::Error, Type::Error)
}
ExpressionKind::AsTraitPath(_) => todo!("Implement AsTraitPath"),
ExpressionKind::TypePath(path) => return self.elaborate_type_path(path),
};
let id = self.interner.push_expr(hir_expr);
self.interner.push_expr_location(id, expr.span, self.file);
Expand Down Expand Up @@ -406,21 +407,13 @@ impl<'context> Elaborator<'context> {

let method_name_span = method_call.method_name.span();
let method_name = method_call.method_name.0.contents.as_str();
match self.lookup_method(&object_type, method_name, span) {
match self.lookup_method(&object_type, method_name, span, true) {
Some(method_ref) => {
// Automatically add `&mut` if the method expects a mutable reference and
// the object is not already one.
let func_id = match &method_ref {
HirMethodReference::FuncId(func_id) => *func_id,
HirMethodReference::TraitMethodId(method_id, _) => {
let id = self.interner.trait_method_id(*method_id);
let definition = self.interner.definition(id);
let DefinitionKind::Function(func_id) = definition.kind else {
unreachable!("Expected trait function to be a DefinitionKind::Function")
};
func_id
}
};
let func_id = method_ref
.func_id(self.interner)
.expect("Expected trait function to be a DefinitionKind::Function");

let generics = if func_id != FuncId::dummy_id() {
let function_type = self.interner.function_meta(&func_id).typ.clone();
Expand Down Expand Up @@ -478,7 +471,17 @@ impl<'context> Elaborator<'context> {

// Type check the new call now that it has been changed from a method call
// to a function call. This way we avoid duplicating code.
let typ = self.type_check_call(&function_call, func_type, function_args, span);
let mut typ = self.type_check_call(&function_call, func_type, function_args, span);
if is_macro_call {
if self.in_comptime_context() {
typ = self.interner.next_type_variable();
} else {
let args = function_call.arguments.clone();
return self
.call_macro(function_call.func, args, location, typ)
.unwrap_or_else(|| (HirExpression::Error, Type::Error));
}
}
(HirExpression::Call(function_call), typ)
}
None => (HirExpression::Error, Type::Error),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub struct Elaborator<'context> {

def_maps: &'context mut DefMaps,

file: FileId,
pub(crate) file: FileId,

in_unsafe_block: bool,
nested_loops: usize,
Expand Down
Loading