Skip to content

Commit

Permalink
chore: let add_definition_location take a Location (noir-lang/noir#…
Browse files Browse the repository at this point in the history
…7185)

fix(LSP): correct signature for assert and assert_eq (noir-lang/noir#7184)
chore(experimental): Prevent enum panics by returning Options where possible instead of panicking (noir-lang/noir#7180)
feat(experimental): Construct enum variants in expressions (noir-lang/noir#7174)
feat: add `noir-inspector` (noir-lang/noir#7136)
fix: ensure canonical bits decomposition (noir-lang/noir#7168)
fix: Keep `inc_rc` for array inputs during preprocessing  (noir-lang/noir#7163)
fix(docs): Update broken links to EC lib (noir-lang/noir#7141)
feat: inline simple functions (noir-lang/noir#7160)
feat(ssa): Expand feature set of the Brillig constraint check (noir-lang/noir#7060)
fix(ssa): Resolve value before fetching from DFG in a couple cases (noir-lang/noir#7169)
fix: `Function::is_no_predicates` always returned false for brillig f… (noir-lang/noir#7167)
chore(refactor): Remove globals field on Ssa object and use only the shared globals graph (noir-lang/noir#7156)
chore: let `Function::inlined` take a `should_inline_call` function (noir-lang/noir#7149)
chore: add compile-time assertions on generic arguments of stdlib functions (noir-lang/noir#6981)
fix: LSP hover over function with `&mut self` (noir-lang/noir#7155)
feat(brillig): Set global memory size at program compile time (noir-lang/noir#7151)
feat: LSP autocomplete module declaration (noir-lang/noir#7154)
feat(ssa): Reuse constants from the globals graph when making constants in a function DFG (noir-lang/noir#7153)
feat: LSP chain inlay hints (noir-lang/noir#7152)
chore: turn on overflow checks in CI rust tests (noir-lang/noir#7145)
fix(ssa): Use post order when mapping instructions in loop invariant pass (noir-lang/noir#7140)
fix: preserve types when reading from calldata arrays (noir-lang/noir#7144)
feat: Resolve enums & prepare type system (noir-lang/noir#7115)
feat: `loop` must have at least one `break` (noir-lang/noir#7126)
feat: parse globals in SSA parser (noir-lang/noir#7112)
fix: allow calling trait impl method from struct if multiple impls exist (noir-lang/noir#7124)
fix: avoid creating unnecessary memory blocks (noir-lang/noir#7114)
chore: relax threshold for reporting regressions (noir-lang/noir#7130)
fix: proper cleanup when breaking from comptime loop on error (noir-lang/noir#7125)
fix: Prevent overlapping associated types impls (noir-lang/noir#7047)
feat: unconstrained optimizations for BoundedVec (noir-lang/noir#7119)
chore: mark libs good (noir-lang/noir#7123)
chore: remove comments for time/memory benchmarks (noir-lang/noir#7121)
fix: don't always use an exclusive lock in `nargo check` (noir-lang/noir#7120)
feat(ssa): Pass to preprocess functions (noir-lang/noir#7072)
chore: Formatting issues / minor errors in the docs (noir-lang/noir#7105)
fix: defunctionalize pass on the caller runtime to apply (noir-lang/noir#7100)
feat: Parser and formatter support for `enum`s (noir-lang/noir#7110)
feat(brillig): SSA globals code gen (noir-lang/noir#7021)
feat: `loop` keyword in runtime and comptime code (noir-lang/noir#7096)
chore: Add benchmarking dashboard (noir-lang/noir#7068)
feat(experimental): try to infer lambda argument types inside calls (noir-lang/noir#7088)
feat(ssa): Add flag to DIE pass to be able to keep `store` instructions (noir-lang/noir#7106)
chore: Cookbook Onboard integration (noir-lang/noir#7044)
chore: lock to ubuntu 22.04 (noir-lang/noir#7098)
fix: Remove unused brillig functions (noir-lang/noir#7102)
chore(ssa): Use correct prefix when printing array values in global space (noir-lang/noir#7095)
  • Loading branch information
AztecBot committed Jan 25, 2025
2 parents 7bc19a4 + bdf5fa7 commit d672928
Show file tree
Hide file tree
Showing 44 changed files with 1,289 additions and 326 deletions.
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a0704aa53250aed9c5460a60f5aaffa87772732f
c44b62615f1c8ee657eedd82f2b80e2ec76c9078
4 changes: 2 additions & 2 deletions noir/noir-repo/Cargo.lock

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

2 changes: 1 addition & 1 deletion noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType {

Type::DataType(def, args) => {
let struct_type = def.borrow();
let fields = struct_type.get_fields(args);
let fields = struct_type.get_fields(args).unwrap_or_default();
let fields =
vecmap(fields, |(name, typ)| (name, abi_type_from_hir_type(context, &typ)));
// For the ABI, we always want to resolve the struct paths from the root crate
Expand Down
7 changes: 4 additions & 3 deletions noir/noir-repo/compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,10 @@ fn compile_contract_inner(
.map(|struct_id| {
let typ = context.def_interner.get_type(struct_id);
let typ = typ.borrow();
let fields = vecmap(typ.get_fields(&[]), |(name, typ)| {
(name, abi_type_from_hir_type(context, &typ))
});
let fields =
vecmap(typ.get_fields(&[]).unwrap_or_default(), |(name, typ)| {
(name, abi_type_from_hir_type(context, &typ))
});
let path =
context.fully_qualified_struct_path(context.root_crate_id(), typ.id);
AbiType::Struct { path, fields }
Expand Down
2 changes: 1 addition & 1 deletion noir/noir-repo/compiler/noirc_evaluator/src/acir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3705,7 +3705,7 @@ mod test {
constrain v7 == Field 0
return
}
brillig(inline) fn foo f1 {
b0(v0: u32, v1: [Field]):
return
Expand Down
157 changes: 157 additions & 0 deletions noir/noir-repo/compiler/noirc_frontend/src/elaborator/enums.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
use iter_extended::vecmap;
use noirc_errors::Location;

use crate::{
ast::{EnumVariant, FunctionKind, NoirEnumeration, UnresolvedType, Visibility},
hir_def::{
expr::{HirEnumConstructorExpression, HirExpression, HirIdent},
function::{FuncMeta, FunctionBody, HirFunction, Parameters},
stmt::HirPattern,
},
node_interner::{DefinitionKind, FuncId, FunctionModifiers, TypeId},
token::Attributes,
DataType, Shared, Type,
};

use super::Elaborator;

impl Elaborator<'_> {
#[allow(clippy::too_many_arguments)]
pub(super) fn define_enum_variant_function(
&mut self,
enum_: &NoirEnumeration,
type_id: TypeId,
variant: &EnumVariant,
variant_arg_types: Vec<Type>,
variant_index: usize,
datatype: &Shared<DataType>,
self_type: &Type,
self_type_unresolved: UnresolvedType,
) {
let name_string = variant.name.to_string();
let datatype_ref = datatype.borrow();
let location = Location::new(variant.name.span(), self.file);

let id = self.interner.push_empty_fn();

let modifiers = FunctionModifiers {
name: name_string.clone(),
visibility: enum_.visibility,
attributes: Attributes { function: None, secondary: Vec::new() },
is_unconstrained: false,
generic_count: datatype_ref.generics.len(),
is_comptime: false,
name_location: location,
};
let definition_id =
self.interner.push_function_definition(id, modifiers, type_id.module_id(), location);

let hir_name = HirIdent::non_trait_method(definition_id, location);
let parameters = self.make_enum_variant_parameters(variant_arg_types, location);
self.push_enum_variant_function_body(id, datatype, variant_index, &parameters, location);

let function_type =
datatype_ref.variant_function_type_with_forall(variant_index, datatype.clone());
self.interner.push_definition_type(definition_id, function_type.clone());

let meta = FuncMeta {
name: hir_name,
kind: FunctionKind::Normal,
parameters,
parameter_idents: Vec::new(),
return_type: crate::ast::FunctionReturnType::Ty(self_type_unresolved),
return_visibility: Visibility::Private,
typ: function_type,
direct_generics: datatype_ref.generics.clone(),
all_generics: datatype_ref.generics.clone(),
location,
has_body: false,
trait_constraints: Vec::new(),
type_id: Some(type_id),
trait_id: None,
trait_impl: None,
enum_variant_index: Some(variant_index),
is_entry_point: false,
has_inline_attribute: false,
function_body: FunctionBody::Resolved,
source_crate: self.crate_id,
source_module: type_id.local_module_id(),
source_file: self.file,
self_type: None,
};

self.interner.push_fn_meta(meta, id);
self.interner.add_method(self_type, name_string, id, None);

let name = variant.name.clone();
Self::get_module_mut(self.def_maps, type_id.module_id())
.declare_function(name, enum_.visibility, id)
.ok();
}

// Given:
// ```
// enum FooEnum { Foo(u32, u8), ... }
//
// fn Foo(a: u32, b: u8) -> FooEnum {}
// ```
// Create (pseudocode):
// ```
// fn Foo(a: u32, b: u8) -> FooEnum {
// // This can't actually be written directly in Noir
// FooEnum {
// tag: Foo_tag,
// Foo: (a, b),
// // fields from other variants are zeroed in monomorphization
// }
// }
// ```
fn push_enum_variant_function_body(
&mut self,
id: FuncId,
self_type: &Shared<DataType>,
variant_index: usize,
parameters: &Parameters,
location: Location,
) {
// Each parameter of the enum variant function is used as a parameter of the enum
// constructor expression
let arguments = vecmap(&parameters.0, |(pattern, typ, _)| match pattern {
HirPattern::Identifier(ident) => {
let id = self.interner.push_expr(HirExpression::Ident(ident.clone(), None));
self.interner.push_expr_type(id, typ.clone());
self.interner.push_expr_location(id, location.span, location.file);
id
}
_ => unreachable!(),
});

let enum_generics = self_type.borrow().generic_types();
let construct_variant = HirExpression::EnumConstructor(HirEnumConstructorExpression {
r#type: self_type.clone(),
enum_generics: enum_generics.clone(),
arguments,
variant_index,
});
let body = self.interner.push_expr(construct_variant);
self.interner.update_fn(id, HirFunction::unchecked_from_expr(body));

let typ = Type::DataType(self_type.clone(), enum_generics);
self.interner.push_expr_type(body, typ);
self.interner.push_expr_location(body, location.span, location.file);
}

fn make_enum_variant_parameters(
&mut self,
parameter_types: Vec<Type>,
location: Location,
) -> Parameters {
Parameters(vecmap(parameter_types.into_iter().enumerate(), |(i, parameter_type)| {
let name = format!("${i}");
let parameter = DefinitionKind::Local(None);
let id = self.interner.push_definition(name, false, false, parameter, location);
let pattern = HirPattern::Identifier(HirIdent::non_trait_method(id, location));
(pattern, parameter_type, Visibility::Private)
}))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ impl<'context> Elaborator<'context> {
self.push_err(ResolverError::UnquoteUsedOutsideQuote { span: expr.span });
(HirExpression::Error, Type::Error)
}
ExpressionKind::AsTraitPath(_) => todo!("Implement AsTraitPath"),
ExpressionKind::AsTraitPath(_) => {
self.push_err(ResolverError::UnquoteUsedOutsideQuote { span: expr.span });
(HirExpression::Error, Type::Error)
}
ExpressionKind::TypePath(path) => return self.elaborate_type_path(path),
};
let id = self.interner.push_expr(hir_expr);
Expand Down Expand Up @@ -619,7 +622,9 @@ impl<'context> Elaborator<'context> {
(typ, generics)
} else {
match self.lookup_type_or_error(path) {
Some(Type::DataType(r#type, struct_generics)) => (r#type, struct_generics),
Some(Type::DataType(r#type, struct_generics)) if r#type.borrow().is_struct() => {
(r#type, struct_generics)
}
Some(typ) => {
self.push_err(ResolverError::NonStructUsedInConstructor {
typ: typ.to_string(),
Expand All @@ -646,7 +651,11 @@ impl<'context> Elaborator<'context> {
let generics = struct_generics.clone();

let fields = constructor.fields;
let field_types = r#type.borrow().get_fields_with_visibility(&struct_generics);
let field_types = r#type
.borrow()
.get_fields_with_visibility(&struct_generics)
.expect("This type should already be validated to be a struct");

let fields =
self.resolve_constructor_expr_fields(struct_type.clone(), field_types, fields, span);
let expr = HirExpression::Constructor(HirConstructorExpression {
Expand All @@ -657,7 +666,7 @@ impl<'context> Elaborator<'context> {

let struct_id = struct_type.borrow().id;
let reference_location = Location::new(last_segment.ident.span(), self.file);
self.interner.add_struct_reference(struct_id, reference_location, is_self_type);
self.interner.add_type_reference(struct_id, reference_location, is_self_type);

(expr, Type::DataType(struct_type, generics))
}
Expand All @@ -680,7 +689,10 @@ impl<'context> Elaborator<'context> {
) -> Vec<(Ident, ExprId)> {
let mut ret = Vec::with_capacity(fields.len());
let mut seen_fields = HashSet::default();
let mut unseen_fields = struct_type.borrow().field_names();
let mut unseen_fields = struct_type
.borrow()
.field_names()
.expect("This type should already be validated to be a struct");

for (field_name, field) in fields {
let expected_field_with_index = field_types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ fn can_return_without_recursing(interner: &NodeInterner, func_id: FuncId, expr_i
HirExpression::Lambda(_)
| HirExpression::Literal(_)
| HirExpression::Constructor(_)
| HirExpression::EnumConstructor(_)
| HirExpression::Quote(_)
| HirExpression::Unquote(_)
| HirExpression::Comptime(_)
Expand Down
Loading

0 comments on commit d672928

Please sign in to comment.