Skip to content

Commit

Permalink
Merge branch 'master' into ab/lsp-autocomplete-in-the-middle
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Aug 22, 2024
2 parents 7fbd4f8 + e050e93 commit f287cde
Show file tree
Hide file tree
Showing 60 changed files with 1,752 additions and 657 deletions.
3 changes: 2 additions & 1 deletion aztec_macros/src/transforms/note_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub fn generate_note_interface_impl(
let mut note_fields = vec![];
let note_interface_generics = trait_impl
.trait_generics
.ordered_args
.iter()
.map(|gen| match gen.typ.clone() {
UnresolvedTypeData::Named(path, _, _) => Ok(path.last_name().to_string()),
Expand Down Expand Up @@ -120,7 +121,7 @@ pub fn generate_note_interface_impl(
ident("header"),
make_type(UnresolvedTypeData::Named(
chained_dep!("aztec", "note", "note_header", "NoteHeader"),
vec![],
Default::default(),
false,
)),
);
Expand Down
32 changes: 19 additions & 13 deletions aztec_macros/src/transforms/storage.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use acvm::acir::AcirField;
use noirc_errors::Span;
use noirc_frontend::ast::{
BlockExpression, Expression, ExpressionKind, FunctionDefinition, Ident, Literal, NoirFunction,
NoirStruct, Pattern, StatementKind, TypeImpl, UnresolvedType, UnresolvedTypeData,
BlockExpression, Expression, ExpressionKind, FunctionDefinition, GenericTypeArgs, Ident,
Literal, NoirFunction, NoirStruct, Pattern, StatementKind, TypeImpl, UnresolvedType,
UnresolvedTypeData,
};
use noirc_frontend::{
graph::CrateId,
Expand Down Expand Up @@ -54,13 +55,13 @@ pub fn check_for_storage_definition(
fn inject_context_in_storage_field(field: &mut UnresolvedType) -> Result<(), AztecMacroError> {
match &mut field.typ {
UnresolvedTypeData::Named(path, generics, _) => {
generics.push(make_type(UnresolvedTypeData::Named(
generics.ordered_args.push(make_type(UnresolvedTypeData::Named(
ident_path("Context"),
vec![],
GenericTypeArgs::default(),
false,
)));
match path.last_name() {
"Map" => inject_context_in_storage_field(&mut generics[1]),
"Map" => inject_context_in_storage_field(&mut generics.ordered_args[1]),
_ => Ok(()),
}
}
Expand Down Expand Up @@ -144,7 +145,10 @@ pub fn generate_storage_field_constructor(
generate_storage_field_constructor(
// Map is expected to have three generic parameters: key, value and context (i.e.
// Map<K, V, Context>. Here `get(1)` fetches the value type.
&(type_ident.clone(), generics.get(1).unwrap().clone()),
&(
type_ident.clone(),
generics.ordered_args.get(1).unwrap().clone(),
),
variable("slot"),
)?,
),
Expand Down Expand Up @@ -219,8 +223,11 @@ pub fn generate_storage_implementation(

// This is the type over which the impl is generic.
let generic_context_ident = ident("Context");
let generic_context_type =
make_type(UnresolvedTypeData::Named(ident_path("Context"), vec![], true));
let generic_context_type = make_type(UnresolvedTypeData::Named(
ident_path("Context"),
GenericTypeArgs::default(),
true,
));

let init = NoirFunction::normal(FunctionDefinition::normal(
&ident("init"),
Expand All @@ -231,13 +238,12 @@ pub fn generate_storage_implementation(
&return_type(chained_path!("Self")),
));

let ordered_args = vec![generic_context_type.clone()];
let generics = GenericTypeArgs { ordered_args, named_args: Vec::new() };

let storage_impl = TypeImpl {
object_type: UnresolvedType {
typ: UnresolvedTypeData::Named(
chained_path!(storage_struct_name),
vec![generic_context_type.clone()],
true,
),
typ: UnresolvedTypeData::Named(chained_path!(storage_struct_name), generics, true),
span: Span::default(),
},
type_span: Span::default(),
Expand Down
30 changes: 22 additions & 8 deletions aztec_macros/src/utils/parse_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use noirc_frontend::{
ast::{
ArrayLiteral, AssignStatement, BlockExpression, CallExpression, CastExpression,
ConstrainStatement, ConstructorExpression, Expression, ExpressionKind, ForLoopStatement,
ForRange, FunctionReturnType, Ident, IfExpression, IndexExpression, InfixExpression,
LValue, Lambda, LetStatement, Literal, MemberAccessExpression, MethodCallExpression,
ModuleDeclaration, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, Path,
PathSegment, Pattern, PrefixExpression, Statement, StatementKind, TraitImplItem, TraitItem,
TypeImpl, UnresolvedGeneric, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType,
UnresolvedTypeData, UnresolvedTypeExpression, UseTree, UseTreeKind,
ForRange, FunctionReturnType, GenericTypeArgs, Ident, IfExpression, IndexExpression,
InfixExpression, LValue, Lambda, LetStatement, Literal, MemberAccessExpression,
MethodCallExpression, ModuleDeclaration, NoirFunction, NoirStruct, NoirTrait,
NoirTraitImpl, NoirTypeAlias, Path, PathSegment, Pattern, PrefixExpression, Statement,
StatementKind, TraitImplItem, TraitItem, TypeImpl, UnresolvedGeneric, UnresolvedGenerics,
UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression,
UseTree, UseTreeKind,
},
parser::{Item, ItemKind, ParsedSubModule, ParserError},
ParsedModule,
Expand Down Expand Up @@ -297,6 +298,14 @@ fn empty_unresolved_types(unresolved_types: &mut [UnresolvedType]) {
}
}

fn empty_type_args(generics: &mut GenericTypeArgs) {
empty_unresolved_types(&mut generics.ordered_args);
for (name, typ) in &mut generics.named_args {
empty_ident(name);
empty_unresolved_type(typ);
}
}

fn empty_unresolved_type(unresolved_type: &mut UnresolvedType) {
unresolved_type.span = Default::default();

Expand All @@ -318,11 +327,11 @@ fn empty_unresolved_type(unresolved_type: &mut UnresolvedType) {
}
UnresolvedTypeData::Named(path, unresolved_types, _) => {
empty_path(path);
empty_unresolved_types(unresolved_types);
empty_type_args(unresolved_types);
}
UnresolvedTypeData::TraitAsType(path, unresolved_types) => {
empty_path(path);
empty_unresolved_types(unresolved_types);
empty_type_args(unresolved_types);
}
UnresolvedTypeData::MutableReference(unresolved_type) => {
empty_unresolved_type(unresolved_type)
Expand Down Expand Up @@ -543,5 +552,10 @@ fn empty_unresolved_type_expression(unresolved_type_expression: &mut UnresolvedT
empty_unresolved_type_expression(rhs);
}
UnresolvedTypeExpression::Constant(_, _) => (),
UnresolvedTypeExpression::AsTraitPath(path) => {
empty_unresolved_type(&mut path.typ);
empty_path(&mut path.trait_path);
empty_ident(&mut path.impl_item);
}
}
}
7 changes: 7 additions & 0 deletions compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ pub struct CompileOptions {
/// Temporary flag to enable the experimental arithmetic generics feature
#[arg(long, hide = true)]
pub arithmetic_generics: bool,

/// Flag to turn off the compiler check for under constrained values.
/// Warning: This can improve compilation speed but can also lead to correctness errors.
/// This check should always be run on production code.
#[arg(long)]
pub skip_underconstrained_check: bool,
}

pub fn parse_expression_width(input: &str) -> Result<ExpressionWidth, std::io::Error> {
Expand Down Expand Up @@ -574,6 +580,7 @@ pub fn compile_no_check(
ExpressionWidth::default()
},
emit_ssa: if options.emit_ssa { Some(context.package_build_path.clone()) } else { None },
skip_underconstrained_check: options.skip_underconstrained_check,
};

let SsaProgramArtifact { program, debug, warnings, names, brillig_names, error_types, .. } =
Expand Down
11 changes: 10 additions & 1 deletion compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ pub struct SsaEvaluatorOptions {

/// Dump the unoptimized SSA to the supplied path if it exists
pub emit_ssa: Option<PathBuf>,

/// Skip the check for under constrained values
pub skip_underconstrained_check: bool,
}

pub(crate) struct ArtifactsAndWarnings(Artifacts, Vec<SsaReport>);
Expand Down Expand Up @@ -117,7 +120,13 @@ pub(crate) fn optimize_into_acir(
.run_pass(Ssa::array_set_optimization, "After Array Set Optimizations:")
.finish();

let ssa_level_warnings = ssa.check_for_underconstrained_values();
let ssa_level_warnings = if options.skip_underconstrained_check {
vec![]
} else {
time("After Check for Underconstrained Values", options.print_codegen_timings, || {
ssa.check_for_underconstrained_values()
})
};
let brillig = time("SSA to Brillig", options.print_codegen_timings, || {
ssa.to_brillig(options.enable_brillig_logging)
});
Expand Down
14 changes: 9 additions & 5 deletions compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,11 +1165,15 @@ impl<'a> Context<'a> {
let index_var = self.convert_numeric_value(index, dfg)?;
let index_var = self.get_flattened_index(&array_typ, array_id, index_var, dfg)?;

// predicate_index = index*predicate + (1-predicate)*offset
let offset = self.acir_context.add_constant(offset);
let sub = self.acir_context.sub_var(index_var, offset)?;
let pred = self.acir_context.mul_var(sub, self.current_side_effects_enabled_var)?;
let predicate_index = self.acir_context.add_var(pred, offset)?;
let predicate_index = if dfg.is_safe_index(index, array_id) {
index_var
} else {
// index*predicate + (1-predicate)*offset
let offset = self.acir_context.add_constant(offset);
let sub = self.acir_context.sub_var(index_var, offset)?;
let pred = self.acir_context.mul_var(sub, self.current_side_effects_enabled_var)?;
self.acir_context.add_var(pred, offset)?
};

let new_value = if let Some(store) = store_value {
let store_value = self.convert_value(store, dfg);
Expand Down
8 changes: 8 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ impl DataFlowGraph {
}
}

/// A constant index less than the array length is safe
pub(crate) fn is_safe_index(&self, index: ValueId, array: ValueId) -> bool {
#[allow(clippy::match_like_matches_macro)]
match (self.type_of_value(array), self.get_numeric_constant(index)) {
(Type::Array(_, len), Some(index)) if index.to_u128() < (len as u128) => true,
_ => false,
}
}
/// Sets the terminator instruction for the given basic block
pub(crate) fn set_block_terminator(
&mut self,
Expand Down
8 changes: 2 additions & 6 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,9 @@ impl Instruction {
true
}

// `ArrayGet`s which read from "known good" indices from an array don't need a predicate.
Instruction::ArrayGet { array, index } => {
#[allow(clippy::match_like_matches_macro)]
match (dfg.type_of_value(*array), dfg.get_numeric_constant(*index)) {
(Type::Array(_, len), Some(index)) if index.to_u128() < (len as u128) => false,
_ => true,
}
// `ArrayGet`s which read from "known good" indices from an array should not need a predicate.
!dfg.is_safe_index(*index, *array)
}

Instruction::EnableSideEffects { .. } | Instruction::ArraySet { .. } => true,
Expand Down
Loading

0 comments on commit f287cde

Please sign in to comment.