Skip to content

Commit

Permalink
chore: pull frontend changes from sync PR (#9935)
Browse files Browse the repository at this point in the history
Please read [contributing guidelines](CONTRIBUTING.md) and remove this
line.
  • Loading branch information
TomAFrench authored Nov 14, 2024
1 parent b12d3e4 commit 92a4c5d
Show file tree
Hide file tree
Showing 86 changed files with 3,264 additions and 1,776 deletions.
15 changes: 14 additions & 1 deletion noir/noir-repo/Cargo.lock

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

20 changes: 17 additions & 3 deletions noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use iter_extended::vecmap;
use noirc_abi::{
Abi, AbiErrorType, AbiParameter, AbiReturnType, AbiType, AbiValue, AbiVisibility, Sign,
};
use noirc_errors::Span;
use noirc_evaluator::ErrorType;
use noirc_frontend::ast::{Signedness, Visibility};
use noirc_frontend::TypeBinding;
Expand Down Expand Up @@ -40,11 +41,21 @@ pub(super) fn gen_abi(
Abi { parameters, return_type, error_types }
}

// Get the Span of the root crate's main function, or else a dummy span if that fails
fn get_main_function_span(context: &Context) -> Span {
if let Some(func_id) = context.get_main_function(context.root_crate_id()) {
context.function_meta(&func_id).location.span
} else {
Span::default()
}
}

fn build_abi_error_type(context: &Context, typ: ErrorType) -> AbiErrorType {
match typ {
ErrorType::Dynamic(typ) => {
if let Type::FmtString(len, item_types) = typ {
let length = len.evaluate_to_u32().expect("Cannot evaluate fmt length");
let span = get_main_function_span(context);
let length = len.evaluate_to_u32(span).expect("Cannot evaluate fmt length");
let Type::Tuple(item_types) = item_types.as_ref() else {
unreachable!("FmtString items must be a tuple")
};
Expand All @@ -63,8 +74,9 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType {
match typ {
Type::FieldElement => AbiType::Field,
Type::Array(size, typ) => {
let span = get_main_function_span(context);
let length = size
.evaluate_to_u32()
.evaluate_to_u32(span)
.expect("Cannot have variable sized arrays as a parameter to main");
let typ = typ.as_ref();
AbiType::Array { length, typ: Box::new(abi_type_from_hir_type(context, typ)) }
Expand All @@ -91,8 +103,9 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType {
}
Type::Bool => AbiType::Boolean,
Type::String(size) => {
let span = get_main_function_span(context);
let size = size
.evaluate_to_u32()
.evaluate_to_u32(span)
.expect("Cannot have variable sized strings as a parameter to main");
AbiType::String { length: size }
}
Expand All @@ -107,6 +120,7 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType {
AbiType::Struct { fields, path }
}
Type::Alias(def, args) => abi_type_from_hir_type(context, &def.borrow().get_type(args)),
Type::CheckedCast { to, .. } => abi_type_from_hir_type(context, to),
Type::Tuple(fields) => {
let fields = vecmap(fields, |typ| abi_type_from_hir_type(context, typ));
AbiType::Tuple { fields }
Expand Down
5 changes: 2 additions & 3 deletions noir/noir-repo/compiler/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,9 +456,8 @@ fn compile_contract_inner(
.secondary
.iter()
.filter_map(|attr| match attr {
SecondaryAttribute::Tag(attribute) | SecondaryAttribute::Meta(attribute) => {
Some(attribute.contents.clone())
}
SecondaryAttribute::Tag(attribute) => Some(attribute.contents.clone()),
SecondaryAttribute::Meta(attribute) => Some(attribute.to_string()),
_ => None,
})
.collect();
Expand Down
4 changes: 2 additions & 2 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@ fn split_public_and_private_inputs(
func_sig
.0
.iter()
.map(|(_, typ, visibility)| {
let num_field_elements_needed = typ.field_count() as usize;
.map(|(pattern, typ, visibility)| {
let num_field_elements_needed = typ.field_count(&pattern.location()) as usize;
let witnesses = input_witnesses[idx..idx + num_field_elements_needed].to_vec();
idx += num_field_elements_needed;
(visibility, witnesses)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl DataBusBuilder {
ast::Visibility::CallData(id) => DatabusVisibility::CallData(id),
ast::Visibility::ReturnData => DatabusVisibility::ReturnData,
};
let len = param.1.field_count() as usize;
let len = param.1.field_count(&param.0.location()) as usize;
params_is_databus.extend(vec![is_databus; len]);
}
params_is_databus
Expand Down
2 changes: 2 additions & 0 deletions noir/noir-repo/compiler/noirc_frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ strum_macros = "0.24"

[dev-dependencies]
base64.workspace = true
proptest.workspace = true
proptest-derive = "0.5.0"

[features]
experimental_parser = []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc fc27f4091dfa5f938973048209b5fcf22aefa1cfaffaaa3e349f30e9b1f93f49 # shrinks to infix_and_bindings = (((0: numeric bool) % (Numeric(Shared(RefCell { value: Unbound('2, Numeric(bool)) }): bool) + Numeric(Shared(RefCell { value: Unbound('0, Numeric(bool)) }): bool))), [('0, (0: numeric bool)), ('1, (0: numeric bool)), ('2, (0: numeric bool))])
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc fc27f4091dfa5f938973048209b5fcf22aefa1cfaffaaa3e349f30e9b1f93f49 # shrinks to infix_and_bindings = (((0: numeric bool) % (Numeric(Shared(RefCell { value: Unbound('2, Numeric(bool)) }): bool) + Numeric(Shared(RefCell { value: Unbound('0, Numeric(bool)) }): bool))), [('0, (0: numeric bool)), ('1, (0: numeric bool)), ('2, (0: numeric bool))])
4 changes: 2 additions & 2 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl UnresolvedGeneric {
UnresolvedGeneric::Variable(_) => Ok(Kind::Normal),
UnresolvedGeneric::Numeric { typ, .. } => {
let typ = self.resolve_numeric_kind_type(typ)?;
Ok(Kind::Numeric(Box::new(typ)))
Ok(Kind::numeric(typ))
}
UnresolvedGeneric::Resolved(..) => {
panic!("Don't know the kind of a resolved generic here")
Expand Down Expand Up @@ -504,7 +504,7 @@ impl FunctionDefinition {
}

pub fn is_test(&self) -> bool {
if let Some(attribute) = &self.attributes.function {
if let Some(attribute) = self.attributes.function() {
matches!(attribute, FunctionAttribute::Test(..))
} else {
false
Expand Down
4 changes: 2 additions & 2 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl NoirFunction {
&self.def.attributes
}
pub fn function_attribute(&self) -> Option<&FunctionAttribute> {
self.def.attributes.function.as_ref()
self.def.attributes.function()
}
pub fn secondary_attributes(&self) -> &[SecondaryAttribute] {
self.def.attributes.secondary.as_ref()
Expand Down Expand Up @@ -108,7 +108,7 @@ impl NoirFunction {
impl From<FunctionDefinition> for NoirFunction {
fn from(fd: FunctionDefinition) -> Self {
// The function type is determined by the existence of a function attribute
let kind = match fd.attributes.function {
let kind = match fd.attributes.function() {
Some(FunctionAttribute::Builtin(_)) => FunctionKind::Builtin,
Some(FunctionAttribute::Foreign(_)) => FunctionKind::LowLevel,
Some(FunctionAttribute::Test { .. }) => FunctionKind::Normal,
Expand Down
4 changes: 4 additions & 0 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub use visitor::Visitor;
pub use expression::*;
pub use function::*;

#[cfg(test)]
use proptest_derive::Arbitrary;

use acvm::FieldElement;
pub use docs::*;
use noirc_errors::Span;
Expand All @@ -37,6 +40,7 @@ use crate::{
use acvm::acir::AcirField;
use iter_extended::vecmap;

#[cfg_attr(test, derive(Arbitrary))]
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd)]
pub enum IntegerBitSize {
One,
Expand Down
10 changes: 2 additions & 8 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,6 @@ impl Path {
self.span
}

pub fn first_segment(&self) -> PathSegment {
assert!(!self.segments.is_empty());
self.segments.first().unwrap().clone()
}

pub fn last_segment(&self) -> PathSegment {
assert!(!self.segments.is_empty());
self.segments.last().unwrap().clone()
Expand All @@ -459,9 +454,8 @@ impl Path {
self.last_segment().ident
}

pub fn first_name(&self) -> &str {
assert!(!self.segments.is_empty());
&self.segments.first().unwrap().ident.0.contents
pub fn first_name(&self) -> Option<&str> {
self.segments.first().map(|segment| segment.ident.0.contents.as_str())
}

pub fn last_name(&self) -> &str {
Expand Down
21 changes: 15 additions & 6 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
InternedUnresolvedTypeData, QuotedTypeId,
},
parser::{Item, ItemKind, ParsedSubModule},
token::{CustomAttribute, SecondaryAttribute, Tokens},
token::{MetaAttribute, SecondaryAttribute, Tokens},
ParsedModule, QuotedType,
};

Expand Down Expand Up @@ -474,7 +474,9 @@ pub trait Visitor {
true
}

fn visit_custom_attribute(&mut self, _: &CustomAttribute, _target: AttributeTarget) {}
fn visit_meta_attribute(&mut self, _: &MetaAttribute, _target: AttributeTarget) -> bool {
true
}
}

impl ParsedModule {
Expand Down Expand Up @@ -1441,15 +1443,22 @@ impl SecondaryAttribute {
}

pub fn accept_children(&self, target: AttributeTarget, visitor: &mut impl Visitor) {
if let SecondaryAttribute::Meta(custom) = self {
custom.accept(target, visitor);
if let SecondaryAttribute::Meta(meta_attribute) = self {
meta_attribute.accept(target, visitor);
}
}
}

impl CustomAttribute {
impl MetaAttribute {
pub fn accept(&self, target: AttributeTarget, visitor: &mut impl Visitor) {
visitor.visit_custom_attribute(self, target);
if visitor.visit_meta_attribute(self, target) {
self.accept_children(visitor);
}
}

pub fn accept_children(&self, visitor: &mut impl Visitor) {
self.name.accept(visitor);
visit_expressions(&self.arguments, visitor);
}
}

Expand Down
62 changes: 11 additions & 51 deletions noir/noir-repo/compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ use crate::{
resolution::errors::ResolverError,
},
hir_def::expr::{HirExpression, HirIdent},
lexer::Lexer,
node_interner::{DefinitionKind, DependencyId, FuncId, NodeInterner, StructId, TraitId},
parser::{Item, ItemKind, Parser},
token::SecondaryAttribute,
parser::{Item, ItemKind},
token::{MetaAttribute, SecondaryAttribute},
Type, TypeBindings, UnificationError,
};

Expand Down Expand Up @@ -162,10 +161,9 @@ impl<'context> Elaborator<'context> {
if let SecondaryAttribute::Meta(attribute) = attribute {
self.elaborate_in_comptime_context(|this| {
if let Err(error) = this.run_comptime_attribute_name_on_item(
&attribute.contents,
attribute,
item.clone(),
span,
attribute.contents_span,
attribute_context,
generated_items,
) {
Expand All @@ -177,27 +175,21 @@ impl<'context> Elaborator<'context> {

fn run_comptime_attribute_name_on_item(
&mut self,
attribute: &str,
attribute: &MetaAttribute,
item: Value,
span: Span,
attribute_span: Span,
attribute_context: AttributeContext,
generated_items: &mut CollectedItems,
) -> Result<(), (CompilationError, FileId)> {
self.file = attribute_context.attribute_file;
self.local_module = attribute_context.attribute_module;

let location = Location::new(attribute_span, self.file);
let Some((function, arguments)) = Self::parse_attribute(attribute, location)? else {
return Err((
ResolverError::UnableToParseAttribute {
attribute: attribute.to_string(),
span: attribute_span,
}
.into(),
self.file,
));
let location = Location::new(attribute.span, self.file);
let function = Expression {
kind: ExpressionKind::Variable(attribute.name.clone()),
span: attribute.span,
};
let arguments = attribute.arguments.clone();

// Elaborate the function, rolling back any errors generated in case it is unknown
let error_count = self.errors.len();
Expand All @@ -211,7 +203,7 @@ impl<'context> Elaborator<'context> {
return Err((
ResolverError::AttributeFunctionIsNotAPath {
function: function_string,
span: attribute_span,
span: attribute.span,
}
.into(),
self.file,
Expand All @@ -223,7 +215,7 @@ impl<'context> Elaborator<'context> {
return Err((
ResolverError::AttributeFunctionNotInScope {
name: function_string,
span: attribute_span,
span: attribute.span,
}
.into(),
self.file,
Expand Down Expand Up @@ -269,38 +261,6 @@ impl<'context> Elaborator<'context> {
Ok(())
}

/// Parses an attribute in the form of a function call (e.g. `#[foo(a b, c d)]`) into
/// the function and quoted arguments called (e.g. `("foo", vec![(a b, location), (c d, location)])`)
#[allow(clippy::type_complexity)]
pub(crate) fn parse_attribute(
annotation: &str,
location: Location,
) -> Result<Option<(Expression, Vec<Expression>)>, (CompilationError, FileId)> {
let (tokens, mut lexing_errors) = Lexer::lex(annotation);
if !lexing_errors.is_empty() {
return Err((lexing_errors.swap_remove(0).into(), location.file));
}

let Some(expression) = Parser::for_tokens(tokens).parse_option(Parser::parse_expression)
else {
return Ok(None);
};

let (mut func, mut arguments) = match expression.kind {
ExpressionKind::Call(call) => (*call.func, call.arguments),
ExpressionKind::Variable(_) => (expression, Vec::new()),
_ => return Ok(None),
};

func.span = func.span.shift_by(location.span.start());

for argument in &mut arguments {
argument.span = argument.span.shift_by(location.span.start());
}

Ok(Some((func, arguments)))
}

fn handle_attribute_arguments(
interpreter: &mut Interpreter,
item: &Value,
Expand Down
Loading

0 comments on commit 92a4c5d

Please sign in to comment.