-
Notifications
You must be signed in to change notification settings - Fork 249
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: type alias for numeric generics #7583
base: master
Are you sure you want to change the base?
Conversation
I am not sure why I had to update some unit tests. |
// It must be a numeric type | ||
num_typ = Some(self.parse_type_or_error()); | ||
} | ||
let location = self.location_since(start_location); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This location should be created right before finishing parsing the type alias (I think this is why you get a difference in the tests). It seems previously this was right before the semicolons.
#[derive(Clone, Debug)] | ||
pub struct NumericTypeAlias { | ||
pub type_alias: NormalTypeAlias, | ||
pub numeric_type: UnresolvedType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the only difference between the two aliases is this numeric_type, maybe it could be turned into numeric_type: Option<UnresolvedType>
in NoirTypeAlias
to avoid an enum. I think parsing will be simplified too, and maybe the elaborator side too. The only downside I can see is that we need to remember to check this field during elaboration, but it's a one-time case and with a test we'll have it covered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think the Option<UnresolvedType>
approach may be simpler
let generics = vecmap(&self.type_alias.generics, |generic| generic.to_string()); | ||
write!( | ||
f, | ||
"numeric ({}) type {}<{}> = {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if we use this strings for compilation, but right now that output doesn't match the syntax that we use for parsing it.
let b: [u8; 6] = foo(); | ||
assert(b[0] == 0); | ||
} | ||
fn foo<let N:u32>() -> [u8;Double::<N>] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate we can't parse this as Double<N>
without the turbofish. We're parsing an expression here not a type so we run into something like D < N > 2
actually being a valid expression...
May need to keep this for now. Can you add a test that shows we can still use the alias without the turbofish, where a type is expected? E.g. BoundedVec<Field, Double<N>>
if let Some((span, message)) = | ||
get_error_line_span_and_message(line, '-', byte, last_line_length) | ||
{ | ||
custom_spans_with_errors.push((span, message)); | ||
continue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsure why we'd need to change this either. @asterite any insights?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the overall location of the type alias was changed so these tests broke (though I'm not sure why we'd need custom spans here).
code_lines.push(line); | ||
|
||
byte += line.len() + 1; // For '\n' | ||
last_line_length = line.len(); | ||
} | ||
|
||
dbg!(&custom_spans_with_errors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few leftover dbg
in this function
#[derive(Clone, Debug)] | ||
pub struct NumericTypeAlias { | ||
pub type_alias: NormalTypeAlias, | ||
pub numeric_type: UnresolvedType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think the Option<UnresolvedType>
approach may be simpler
let b: [u8; 6] = foo(); | ||
assert(b[0] == 0); | ||
} | ||
fn foo<let N:u32>() -> [u8;Double::<N>] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate we can't parse this as Double<N>
without the turbofish. We're parsing an expression here not a type so we run into something like D < N > 2
actually being a valid expression...
May need to keep this for now. Can you add a test that shows we can still use the alias without the turbofish, where a type is expected? E.g. BoundedVec<Field, Double<N>>
Description
Problem*
Resolves #7272
Summary*
Allow type alias to reference numeric generic expression.
Additional Context
Changes are minimal, more use cases need to be tested. In particular there is no documentation. It can be added as a subsequent PR (or even in this one).
The PR is done in order to validate the approach taken.
Documentation*
Check one:
PR Checklist*
cargo fmt
on default settings.