Skip to content

feat: arithmetic generics #5060

Closed
michaeljklein wants to merge 30 commits intomasterfrom
michaeljklein/interned-arith-generics
Closed

feat: arithmetic generics #5060
michaeljklein wants to merge 30 commits intomasterfrom
michaeljklein/interned-arith-generics

Conversation

@michaeljklein
Copy link
Copy Markdown
Contributor

@michaeljklein michaeljklein commented May 21, 2024

Description

Problem*

Supersedes #4958

Summary*

  • keeping variables up to date in the other approach was too heavy
  • this approach interns the arithmetic part so that a generic arithmetic expression can be represented as:
(id_to_expr_with_holes, Vec<variable_in_expr>)

Additional Context

Remaining issues:

Documentation*

Check one:

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

…d register in node interner, add generic arith ~tuple-like to hir, add key cases in monomorphizer, resolver, etc (wip)
…ssions for convert_expression_type, add conversion from BinaryTypeOperator for ArithOpKind, add node_interner api for arithmetic_expressions
Copy link
Copy Markdown
Contributor

@jfecher jfecher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial approach looks good, nothing really jumped out at me

michaeljklein and others added 22 commits May 22, 2024 14:44
…ation to interner map for errors, add constraint validator to monomorphizer, add ArithConstraintError w/ conversion to MonomorphizerError, add monomorphizer evaluator, add evaluator and validator for arith expressions
… the node interner instead of a mutable parameter
…r locations in the call stack for emitting, evaluate generic args to u64, add error for distinct expressions
…rith's, intern constants as generic arith expressions, block unsupported impl's, add function to check for any GenericArith's in a Type, unify with constant case, wip following bindings and unifying against GenericArith, wip patching TypeVariable's, convert ArithId to a hash of the expression and do normalization, wip testing and added tests for blocked impl's
…ypeVariableId's, get_outer_type_variable, map_variables, converting 'stale' TypeVariables to the 'fresh' ones in the arguments
…n variables as generic arith during resolution, add missing integer-like test for generic arith, add cases where a generic arith constraint was missing during try_unify, wip testing
…ry_evaluate_to_u64, propagate interner arg, found case that's causing current error in evaluate_generics_to_u64
…d', add NeedsInterning, filter out dummy locations for monomorphizer errors, add recursive follow_bindings case, fix sorting ArithOpKind::Sub expressions, calculate the maximum generic index for offsets, add errors for underflow and unexpected cases, added test cases
…h Vec, rename GenericIndex -> ArithGenericId, factor out impute_variables function, reduce clones where possible, add test result for turbofish
…on to convert_type_to_arith_expr, skip linting false positive
…ce hack of hash to order ArithExpr with proper ordering, fix broken impute, key test passing with elaborator
…ric_arith_in_self_type and prevent_generic_arith_in_trait_generics as separate functions, add issues for TODO's, add message to --use-elaborator, nargo fmt
@michaeljklein michaeljklein marked this pull request as ready for review May 31, 2024 01:31

// it also fails when using turbofish
//
// assert(tail::<Field, 3>([1,2,3]) == [2, 3]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this line and the other commented out assertions also pass in the elaborator?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question: it and the other commented assertions pass nargo check with the elaborator, but not nargo test (with a test that just calls main). The unification assertion in node_interner/generic_arith.rs doesn't pass in either case: #5150

Copy link
Copy Markdown
Contributor

@jfecher jfecher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hesitant on the approach here and want to hold off on merging for now.

The use of interning bloats the code a bit and it's unclear to me why we need to intern every constant used in a type position for example. I would have thought we'd only need to remember arith expressions that are unified against each other.

I also think delaying these type checks until monomorphization will probably introduce bugs that are difficult/impossible to fix without changing the approach.

I'm thinking now maybe we should just admit we're adding dependent types to Noir and try to add unification / checking for those directly. We may need to switch to a bidirectional type checker but I think it'd end up being the cleaner approach in the end and could let us eventually handle traits as well.

let typevars = vecmap(typevars, |var| var.id().to_string());
write!(f, "forall {}. {}", typevars.join(" "), typ)
}
Type::GenericArith(arith_id, generics) => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a TODO: this prints the arith ID

@TomAFrench
Copy link
Copy Markdown
Member

Closing after discussing with Michael

@TomAFrench TomAFrench closed this Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants