Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: pull frontend changes from sync PR #9935

Merged
merged 10 commits into from
Nov 14, 2024
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
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