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

feat: Explicit Associated Types & Constants #5739

Merged
merged 49 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
523beef
Parse associated constants
jfecher Jul 16, 2024
2c7eb02
Merge branch 'master' into jf/associated-constants
jfecher Aug 6, 2024
7901f66
Add features to the AST
jfecher Aug 6, 2024
38e09ef
Some progress
jfecher Aug 6, 2024
b862af3
Resolve associated type paths from Self
jfecher Aug 7, 2024
9f1402b
Break everything
jfecher Aug 8, 2024
2b16d75
Overhaul resolution of generics
jfecher Aug 9, 2024
98e0db6
It compiles!
jfecher Aug 12, 2024
21baa22
Update some tests
jfecher Aug 12, 2024
91a80a7
Fix merge conflicts
jfecher Aug 12, 2024
bda71e0
Fix name shadowing test
jfecher Aug 13, 2024
11864a2
Get some programs compiling w/ type annotations
jfecher Aug 13, 2024
488db35
Add TraitGenerics
jfecher Aug 13, 2024
a35d718
Fix interpreter builtins
jfecher Aug 13, 2024
e0a3d2b
Make type spans mandatory
jfecher Aug 14, 2024
480a91d
Start trying to resolve AsTraitPaths
jfecher Aug 14, 2024
2553e31
Get associated types mostly working
jfecher Aug 15, 2024
ea4a31e
Try to solve math
jfecher Aug 15, 2024
cef4256
Get Serialize working
jfecher Aug 16, 2024
f4b29a9
Add test programs
jfecher Aug 16, 2024
f73d550
Merge branch 'master' into jf/associated-constants2
jfecher Aug 16, 2024
5dabf3c
Remove comment; fix bad merge
jfecher Aug 16, 2024
a514799
Add location to panic
jfecher Aug 16, 2024
b5fb036
Merge branch 'master' into jf/associated-constants2
jfecher Aug 16, 2024
a2542fd
Fix let-inferred type issue
jfecher Aug 16, 2024
c6d1829
Fix auto deref
jfecher Aug 16, 2024
98597e4
unsafe::zeroed -> mem::zeroed
jfecher Aug 16, 2024
c71e1d1
Merge branch 'master' into jf/associated-constants2
jfecher Aug 16, 2024
3f3f050
Fix formatter
jfecher Aug 16, 2024
ff41698
Format the formatter
jfecher Aug 16, 2024
9b41358
Remove dbg
jfecher Aug 16, 2024
0721cb2
Fix formatter again
jfecher Aug 16, 2024
ca65712
Don't crash the linker
jfecher Aug 19, 2024
c6739c3
Merge branch 'jf/associated-constants2' of https://github.com/noir-la…
jfecher Aug 19, 2024
3ba02e6
Merge branch 'master' into jf/associated-constants2
jfecher Aug 19, 2024
d67a9f0
Add a missing `follow_bindings` call
asterite Aug 19, 2024
81c764e
Add frontend tests
jfecher Aug 19, 2024
e25565f
Merge branch 'master' into jf/associated-constants2
TomAFrench Aug 20, 2024
d1661fd
Merge branch 'jf/associated-constants2' of https://github.com/noir-la…
jfecher Aug 20, 2024
e174c7d
Store TraitGenerics in a TraitConstraint
jfecher Aug 20, 2024
4471eea
Type hints aren't needed!
jfecher Aug 20, 2024
7de6992
Fix lint
jfecher Aug 20, 2024
f444b58
Fix tests, add another
jfecher Aug 20, 2024
b804228
Add docs
jfecher Aug 20, 2024
becadba
Remove experimental warnings
jfecher Aug 20, 2024
c91dffb
Fix merge conflicts
jfecher Aug 20, 2024
f0331ba
Merge branch 'master' into jf/associated-constants2
jfecher Aug 21, 2024
c9558cc
Merge branch 'master' into jf/associated-constants2
TomAFrench Aug 22, 2024
4bd91a1
Limit max parallel threads
jfecher Aug 22, 2024
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
6 changes: 3 additions & 3 deletions aztec_macros/src/transforms/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ fn create_inputs(ty: &str) -> Param {
let path_snippet = ty.to_case(Case::Snake); // e.g. private_context_inputs
let type_path = chained_dep!("aztec", "context", "inputs", &path_snippet, ty);

let context_type = make_type(UnresolvedTypeData::Named(type_path, vec![], true));
let context_type = make_type(UnresolvedTypeData::Named(type_path, Default::default(), true));
let visibility = Visibility::Private;

Param { pattern: context_pattern, typ: context_type, visibility, span: Span::default() }
Expand Down Expand Up @@ -396,7 +396,7 @@ fn serialize_to_hasher(
Signedness::Unsigned,
ast::IntegerBitSize::ThirtyTwo,
),
span: None,
span: Span::default(),
},
hasher_name,
))
Expand Down Expand Up @@ -595,7 +595,7 @@ fn abstract_return_values(func: &NoirFunction) -> Result<Option<Vec<Statement>>,
serialize_to_hasher(&ident(return_value_name), &current_return_type, hasher_name)
.ok_or_else(|| AztecMacroError::UnsupportedFunctionReturnType {
typ: current_return_type.clone(),
span: func.return_type().span.unwrap_or_default(),
span: func.return_type().span,
})?;

replacement_statements.extend(serialization_statements);
Expand Down
62 changes: 32 additions & 30 deletions aztec_macros/src/transforms/note_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ pub fn generate_note_interface_impl(
note_struct.name.0.contents
)),
})?;
let note_interface_impl_span: Option<Span> =
if empty_spans { None } else { trait_impl.object_type.span };
let note_interface_impl_span =
if empty_spans { Span::default() } else { trait_impl.object_type.span };

// Look for the note struct implementation, generate a default one if it doesn't exist (in order to append methods to it)
let existing_impl = module.impls.iter_mut().find(|r#impl| match &r#impl.object_type.typ {
UnresolvedTypeData::Named(path, _, _) => path.last_ident().eq(&note_struct.name),
Expand All @@ -87,14 +88,15 @@ 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()),
UnresolvedTypeData::Expression(UnresolvedTypeExpression::Constant(val, _)) => {
Ok(val.to_string())
}
_ => Err(AztecMacroError::CouldNotImplementNoteInterface {
span: trait_impl.object_type.span,
span: Some(trait_impl.object_type.span),
secondary_message: Some(format!(
"NoteInterface must be generic over NOTE_LEN and NOTE_BYTES_LEN: {}",
note_type
Expand All @@ -119,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 Expand Up @@ -231,7 +233,7 @@ fn generate_note_to_be_bytes(
note_type: &String,
byte_length: &str,
serialized_length: &str,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
let function_source = format!(
Expand Down Expand Up @@ -268,21 +270,21 @@ fn generate_note_to_be_bytes(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn to_be_bytes). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}

let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}

fn generate_note_get_header(
note_type: &String,
note_header_field_name: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
let function_source = format!(
Expand All @@ -300,21 +302,21 @@ fn generate_note_get_header(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn get_header). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}

let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}

fn generate_note_set_header(
note_type: &String,
note_header_field_name: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
let function_source = format!(
Expand All @@ -331,13 +333,13 @@ fn generate_note_set_header(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn set_header). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}

let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}
Expand All @@ -346,7 +348,7 @@ fn generate_note_set_header(
// of the conversion of the characters in the note's struct name to unsigned integers.
fn generate_get_note_type_id(
note_type_id: u32,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
// TODO(#7165): replace {} with dep::aztec::protocol_types::abis::note_selector::compute_note_selector(\"{}\") in the function source below
Expand All @@ -365,13 +367,13 @@ fn generate_get_note_type_id(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn get_note_type_id). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}

let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}
Expand All @@ -389,7 +391,7 @@ fn generate_note_properties_struct(
note_type: &str,
note_fields: &[(String, String)],
note_header_field_name: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirStruct, AztecMacroError> {
let struct_source =
Expand All @@ -400,7 +402,7 @@ fn generate_note_properties_struct(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some(format!("Failed to parse Noir macro code (struct {}Properties). This is either a bug in the compiler or the Noir macro code", note_type)),
span: impl_span
span: Some(impl_span)
});
}

Expand All @@ -423,7 +425,7 @@ fn generate_note_deserialize_content(
note_fields: &[(String, String)],
note_serialize_len: &String,
note_header_field_name: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
let function_source = generate_note_deserialize_content_source(
Expand All @@ -438,13 +440,13 @@ fn generate_note_deserialize_content(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn deserialize_content). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}

let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}
Expand All @@ -461,7 +463,7 @@ fn generate_note_serialize_content(
note_fields: &[(String, String)],
note_serialize_len: &String,
note_header_field_name: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
let function_source = generate_note_serialize_content_source(
Expand All @@ -476,13 +478,13 @@ fn generate_note_serialize_content(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn serialize_content). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}

let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}
Expand All @@ -492,7 +494,7 @@ fn generate_note_properties_fn(
note_type: &str,
note_fields: &[(String, String)],
note_header_field_name: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
let function_source =
Expand All @@ -502,12 +504,12 @@ fn generate_note_properties_fn(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn properties). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}
let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}
Expand All @@ -519,7 +521,7 @@ fn generate_note_properties_fn(
//
fn generate_compute_note_hiding_point(
note_type: &String,
impl_span: Option<Span>,
impl_span: Span,
empty_spans: bool,
) -> Result<NoirFunction, AztecMacroError> {
// TODO(#7771): update this to do only 1 MSM call
Expand All @@ -541,12 +543,12 @@ fn generate_compute_note_hiding_point(
dbg!(errors);
return Err(AztecMacroError::CouldNotImplementNoteInterface {
secondary_message: Some("Failed to parse Noir macro code (fn compute_note_hiding_point). This is either a bug in the compiler or the Noir macro code".to_string()),
span: impl_span
span: Some(impl_span)
});
}
let mut function_ast = function_ast.into_sorted();
let mut noir_fn = function_ast.functions.remove(0);
noir_fn.def.span = impl_span.unwrap_or_default();
noir_fn.def.span = impl_span;
noir_fn.def.visibility = ItemVisibility::Public;
Ok(noir_fn)
}
Expand Down
34 changes: 20 additions & 14 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,14 +238,13 @@ 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,
),
span: Some(Span::default()),
typ: UnresolvedTypeData::Named(chained_path!(storage_struct_name), generics, true),
span: Span::default(),
},
type_span: Span::default(),
generics: vec![generic_context_ident.into()],
Expand Down
9 changes: 3 additions & 6 deletions aztec_macros/src/utils/ast_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,14 @@ pub fn assignment_with_type(
}

pub fn return_type(path: Path) -> FunctionReturnType {
let ty = make_type(UnresolvedTypeData::Named(path, vec![], true));
let ty = make_type(UnresolvedTypeData::Named(path, Default::default(), true));
FunctionReturnType::Ty(ty)
}

pub fn lambda(parameters: Vec<(Pattern, UnresolvedType)>, body: Expression) -> Expression {
expression(ExpressionKind::Lambda(Box::new(Lambda {
parameters,
return_type: UnresolvedType {
typ: UnresolvedTypeData::Unspecified,
span: Some(Span::default()),
},
return_type: UnresolvedType { typ: UnresolvedTypeData::Unspecified, span: Span::default() },
body,
})))
}
Expand Down Expand Up @@ -179,7 +176,7 @@ pub fn cast(lhs: Expression, ty: UnresolvedTypeData) -> Expression {
}

pub fn make_type(typ: UnresolvedTypeData) -> UnresolvedType {
UnresolvedType { typ, span: Some(Span::default()) }
UnresolvedType { typ, span: Span::default() }
}

pub fn index_array(array: Ident, index: &str) -> Expression {
Expand Down
Loading
Loading