-
Notifications
You must be signed in to change notification settings - Fork 259
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. |
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.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Test Suite Duration'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20
.
Benchmark suite | Current: 02fe712 | Previous: d8ea3a4 | Ratio |
---|---|---|---|
zkemail_zkemail.nr_lib |
3 s |
1 s |
3 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @TomAFrench
fn noir_type_alias_with_file(noir_type_alias: TypeAlias, file: FileId) -> TypeAlias { | ||
type_alias_with_file(noir_type_alias, file) | ||
} |
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.
Is this necessary? This function is private so we should be able to update all the references to it pretty cleanly.
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 believe it was needed when I used an enum to distinguish numeric type aliases, but it's probably not needed anymore, indeed. I will check.
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.
Lets remove this before merging
let (typ, num_expr) = if let Some(num_type) = alias.type_alias_def.numeric_type { | ||
let num_type = self.resolve_type(num_type); | ||
let kind = Kind::numeric(num_type); | ||
let num_expr = if let UnresolvedTypeData::Expression(expr) = |
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 looks to be the issue with the identity alias. This is a pretty fragile check it seems as we can avoid it by just ensuring that the last step is an expression and it doesn't look deeper?
type Quadruple<let N: u32>: u32 = Double<N> + 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.
I added a stronger test which only authorised numeric expressions for the type alias to reference.
Such type aliases did cause stack overflow during resolution so I had to return an error type.
I'm a little sus by how loose we're being with the various kinds of type aliases now. e.g. type Foo: u32 = u32; This errors with
but really we should be rejecting it as an invalid type alias off the bat. |
Can you add some unit tests for the cases where composing numeric type aliases results in issues? Ideally we'd have tests that we can use to determine when we can remove the block on nested numeric type aliases |
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 couple more things I found before we merge.
@@ -22,7 +22,7 @@ fn errors_if_type_alias_aliases_more_private_type() { | |||
let src = r#" | |||
struct Foo {} | |||
pub type Bar = Foo; | |||
^^^ Type `Foo` is more private than item `Bar` | |||
^^^^^^^^^^^^^^^^^^ Type `Foo` is more private than item `Bar` |
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.
Can these locations be changed back to just the item? As is now we're highlighting the entire line which I don't think is as helpful
fn noir_type_alias_with_file(noir_type_alias: TypeAlias, file: FileId) -> TypeAlias { | ||
type_alias_with_file(noir_type_alias, file) | ||
} |
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.
Lets remove this before merging
} | ||
|
||
#[test] | ||
fn disallows_numeric_type_aliases_to_expression_with_alias_1() { |
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.
fn disallows_numeric_type_aliases_to_expression_with_alias_1() { | |
fn disallows_numeric_type_aliases_to_expression_with_alias_2() { |
type Quadruple<let N: u32>: u32 = N*(Double::<N>+3); | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Cannot use a type alias inside a type alias |
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.
Can this location be changed so that it is just on Double::<N>
?
let mut diag = Diagnostic::simple_error( | ||
format!("duplicate definitions of {name} found"), | ||
"second definition found here".to_string(), | ||
*second_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.
Looks like the formatter broke in this file? Not sure what happened here
pub(crate) fn resolve_type_with_kind(&mut self, typ: UnresolvedType, kind: &Kind) -> Type { | ||
let location = typ.location; | ||
let resolved_type = self.resolve_type_inner(typ, kind); | ||
if resolved_type.is_nested_slice() { | ||
self.push_err(ResolverError::NestedSlices { location }); | ||
} | ||
resolved_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.
Was this added from this PR? We used to have this method although it looks like it was removed a while back. Just flagging this in case it was the result of a merge and we don't need it any more.
// Type alias to numeric generics are aliases to some global value | ||
// Therefore we allow this case although we cannot provide the value yet | ||
return Ok((DefinitionId::dummy_id(), item)); |
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 looks potentially suspicious - when are these dummy ids filled in? If we assign each numeric type alias a DefinitionId we can probably do away with the dummy ids here.
if expr.id == DefinitionId::dummy_id() { | ||
if let Some(PathResolutionItem::TypeAlias(alias)) = item { |
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.
Is the outer == dummy_id
check necessary here? Seems like all numeric type aliases are expected to have that ID anyway and only checking for PathResolutionItem::TypeAlias
would be more clear I think.
} | ||
} | ||
|
||
fn operator_to_binary_op_kind_helper(op: &BinaryTypeOperator) -> BinaryOpKind { |
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 should be a method on BinaryTypeOperator
|
||
pub(crate) fn is_valid_expression(&self) -> bool { | ||
match self { | ||
UnresolvedTypeExpression::Variable(path) => path.is_ident(), |
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.
The comment in elaborator/mod.rs mentions this function should allow globals & constants. We can have multiple segment paths that still resolve to constants or globals. E.g. crate::CONSTANT
or foo::bar::my_global
, but this method disallows these.
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.