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(errors): Refactor errors representation in compiler #2760

Conversation

yordanmadzhunkov
Copy link
Contributor

Summary*

Refactoring DefCollector to return CompilationErrors

pub struct CompilationErrors {
    pub parser_errors: Vec<(ParserError, FileId)>,
    pub def_errors: Vec<(DefCollectorErrorKind, FileId)>,
    pub resolver_errors: Vec<(ResolverError, FileId)>,
    pub type_errors: Vec<(TypeCheckError, FileId)>,
}

Problem*

The motivation for this changes are:

  • Allow to write an unit test that checks for specific compilation error
  • Allow propagation of parsing errors from sub-modules
  • Improve code readability. Now it's clear just from function signature what kind of errors the caller can expect

The refactoring of the test will be in next code review, to keep this one as short as possible

PR Checklist*

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

@yordanmadzhunkov
Copy link
Contributor Author

@jfecher Welcome back :)

@jfecher
Copy link
Contributor

jfecher commented Sep 20, 2023

I've skimmed over the code and it seems reasonable. Can you elaborate more on the motivations for this PR though?

Allow to write an unit test that checks for specific compilation error

What are some examples of unit tests we'd like to write here?

Allow propagation of parsing errors from sub-modules

How so? I would think errors from sub modules are already propagated since they wouldn't be displayed at all otherwise. Is this a separate bug?

@nickysn nickysn mentioned this pull request Sep 21, 2023
46 tasks
@yordanmadzhunkov
Copy link
Contributor Author

Allow propagation of parsing errors from sub-modules -> I can't recall where I encountered this, so ignore it for now. Sorry!

Allow to write an unit test that checks for specific compilation error
One such example:

    #[test]
    fn check_trait_wrong_parameter() {
        let src = "
        trait Default {
            fn default(x: Field) -> Self;
        }
        
        struct Foo {
            bar: u32,
        }
        
        impl Default for Foo {
            fn default(x: u32) -> Self {
                Foo {bar: x}
            }
        }
        
        fn main() {
        }
        ";
        let compilator_errors = get_program_errors(src);
        //The following check will ignore warnings that are emitted by parser
        assert!(!compilator_errors.has_parser_errors()); 
        assert!(compilator_errors.resolver_errors.len() == 0);
        assert!(compilator_errors.def_errors.len() == 0);
        assert!(compilator_errors.type_errors.len() == 1);
        for err in compilator_errors.type_errors {
            match &err {
                (
                    TypeCheckError::TraitMethodParameterTypeMismatch {
                        method_name,
                        expected_typ,
                        actual_typ,
                        ..
                    },
                    _file_id,
                ) => {
                    assert_eq!(method_name, "default");
                    assert_eq!(expected_typ, "Field");
                    assert_eq!(actual_typ, "u32");
                }
                _ => {
                    assert!(
                        false,
                        "No other errors are expected in this test case! Found = {:?}",
                        err
                    );
                }
            };
        }
    }

In the old testing system, we only check if the test fails compilation, not HOW it fails to compile. This actually hide some bugs in both test code & production code. For example:

in tooling/nargo_cli/tests/compile_failure/trait_wrong_parameters_count/src/main.nr

trait Default {
    fn default(x: Field, y: Field) -> Self;
}

// This should fail to compile as `default()` should return `Foo`
impl Default for Foo {
    fn default() -> Field {
        x
    }
}

fn main() {
}

If we judge by the file name it should fail because there is wrong number of parameters.
If we judge by the comment it should fail because there is wrong return type.

Last time I checked it actually fails because x is undefined variable

An other problem I saw is in this example:

    #[test]
    fn unresolved_path() {
        let src = "
            fn main(x : Field) {
                let _z = some::path::to::a::func(x);
            }
        ";

        let mut errors = resolve_src_code(src, vec!["main", "foo"]);
        assert_eq!(errors.len(), 1);
        let err = errors.pop().unwrap();

        path_unresolved_error(err, "func");
    }

this tests uses resolve_src_code to mimic compilation behavior. When I refactored the test to share the same code as the compiler the unresolved path became from "func" to "some". In my understanding the correct one should be "some" because it's the begging of the path that can't be resolved. This actually shows that this test does not test the production code, but it actually tested the compilation mimic function resolve_src_code

After this changes are merged into the master I have prepared an other set of PRs that rewrite the tests.

@yordanmadzhunkov yordanmadzhunkov force-pushed the yordan/refactor_compilation_errors_step_1 branch 2 times, most recently from 4a1a4eb to fe4cdda Compare September 21, 2023 14:51
@yordanmadzhunkov yordanmadzhunkov force-pushed the yordan/refactor_compilation_errors_step_1 branch from fe4cdda to a7ef0e7 Compare September 25, 2023 15:35
Copy link
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 don't want to block this anymore, but eventually we should reconsider storing the errors in a tuple of (error, file). As it is now there are a lot more calls to extend which obscure the happy path of the code more.

@jfecher jfecher added this pull request to the merge queue Sep 25, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 25, 2023
@yordanmadzhunkov yordanmadzhunkov force-pushed the yordan/refactor_compilation_errors_step_1 branch from 6ac6d81 to cffbb9e Compare September 26, 2023 14:32
@yordanmadzhunkov
Copy link
Contributor Author

Screenshot_2023-09-26_at_13-38-22_Test_noir-lang_noirb60bb7d

@jfecher
I had to rebase to trigger an other build on ubuntu ( with actually failed and blocked the merge)

@jfecher jfecher added this pull request to the merge queue Sep 26, 2023
Merged via the queue into noir-lang:master with commit 340386a Sep 26, 2023
18 checks passed
TomAFrench added a commit that referenced this pull request Sep 26, 2023
* master:
  chore(errors): Refactor errors representation in compiler (#2760)
  chore(ci): run `noir_js` tests in CI (#2843)
TomAFrench added a commit that referenced this pull request Sep 26, 2023
* master: (28 commits)
  chore: add `CRS` directory to gitignore (#2852)
  chore: add initial version of `Backend` interface for `noir_js` (#2851)
  chore(errors): Refactor errors representation in compiler (#2760)
  chore(ci): run `noir_js` tests in CI (#2843)
  chore(noir_js)!: Rename inner and outer proof methods (#2845)
  chore: remove unnecessary `AcirValue`s (#2823)
  fix: Conditionally run the "Create or Update PR" step in acir artifacts rebuild workflow (#2849)
  fix: lack of cjs package version (#2848)
  chore: delete unnecessary nix files (#2840)
  chore!: `generateWitness` now returns a serialized witness file (#2842)
  chore: fix `acvm_js` linting and tests (#2834)
  feat: remove redundant predicate from brillig quotients (#2784)
  chore: Fix dependencies in acvm_js and remove local lock file (#2833)
  chore: add acvm_js to integration build
  chore: update discord link (#2831)
  chore: discard changes in nargo directory
  chore: Update ACIR artifacts (#2810)
  chore: yarn install
  chore: Remove acvm tracking workflow (#2829)
  add acvm_js to workspace
  ...
TomAFrench added a commit that referenced this pull request Sep 27, 2023
* master: (40 commits)
  chore(noir): Release (master) (#2859)
  chore: remove rebuild script since its failing
  chore(ci): rename CI workflows based on theme (#2853)
  chore(noir): Release (master) (#2827)
  chore: add solidity verifier workflow (#2749)
  chore: add `CRS` directory to gitignore (#2852)
  chore: add initial version of `Backend` interface for `noir_js` (#2851)
  chore(errors): Refactor errors representation in compiler (#2760)
  chore(ci): run `noir_js` tests in CI (#2843)
  chore(noir_js)!: Rename inner and outer proof methods (#2845)
  chore: remove unnecessary `AcirValue`s (#2823)
  fix: Conditionally run the "Create or Update PR" step in acir artifacts rebuild workflow (#2849)
  fix: lack of cjs package version (#2848)
  chore: delete unnecessary nix files (#2840)
  chore!: `generateWitness` now returns a serialized witness file (#2842)
  chore: fix `acvm_js` linting and tests (#2834)
  feat: remove redundant predicate from brillig quotients (#2784)
  chore: Fix dependencies in acvm_js and remove local lock file (#2833)
  chore: add acvm_js to integration build
  chore: update discord link (#2831)
  ...
TomAFrench added a commit that referenced this pull request Sep 28, 2023
* master: (107 commits)
  chore: remove leftover files from `acvm-repo` (#2861)
  chore: miscellaneous ACVM fixups (#2864)
  chore(noir): Release (master) (#2875)
  fix: Remove cast for field comparisons in brillig (#2874)
  fix: remove duplication of code to load stdlib files (#2868)
  chore(noir_js): remove unnecessary input validation in JS (#2841)
  chore: build yarn packages in parallel (#2867)
  chore(ci): remove `toml2json` dependency (#2862)
  chore: fix infinite loop in yarn workspace cleaning (#2863)
  chore(noir): Release (master) (#2859)
  chore: remove rebuild script since its failing
  chore(ci): rename CI workflows based on theme (#2853)
  chore(noir): Release (master) (#2827)
  chore: add solidity verifier workflow (#2749)
  chore: add `CRS` directory to gitignore (#2852)
  chore: add initial version of `Backend` interface for `noir_js` (#2851)
  chore(errors): Refactor errors representation in compiler (#2760)
  chore(ci): run `noir_js` tests in CI (#2843)
  chore(noir_js)!: Rename inner and outer proof methods (#2845)
  chore: remove unnecessary `AcirValue`s (#2823)
  ...
Sakapoi pushed a commit to Sakapoi/noir_fork that referenced this pull request Oct 19, 2023
…2760)

Co-authored-by: Yordan Madzhunkov <ymadzhunkov@gmail.com>
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.

3 participants