This is a fuzzing application for comparing Rust parsers, currently rustc, syn, and rust-analyzer.
It uses the brilliant cargo-fuzz tool to generate random(-ish) files and attempts to parse them with every parser.
It then converts the resulting ASTs into a common representation and compares them, it reports a bug if any of the parsers disagree on whether the code is valid or not, or if they produce different ASTs for valid code.
This project is slightly finnicky to build due to it depending on rustc.
- Source the
.envrcfile, it contains a couple of environment variables required to build rustc. - I'd strongly recommend
[patch]-ing therustcdependency inCargo.tomlto point to a local checkout of rustc, as cargo will clone a new copy into your cache which takes a while and takes a bunch of space. You can copy this section to.cargo/config.tomlto persist it without committing to the repo. - You need to use a recent version of rust to build rustc, I recommend using the same version that the rustc checkout is (which should be latest stable).
- If you want to actually fuzz, install
cargo-fuzzwithcargo install cargo-fuzz. You probably want to seed the corpus with a bunch of rust code too. The best source I've found is to copy all the rustc testsuite, something likecp <rust checkout>/tests/ui/**/*.rs fuzz/corpus/diff/.
To fuzz the parsers run: cargo fuzz run diff --no-cfg-fuzzing (proc-macro2 does weird things if cfg(fuzzing) is enabled).
To run against the fuzz corpus run: cargo run --release (debug will probably stack overflow).
To test a specific file run: cargo run path/to/file.rs.\
For now, please don't report bugs found by this tool to the parser projects directly, as it finds a lot of edge cases and I don't want to spam them. Also, parsers like rust-analyzer intentionally parse some invalid Rust code for better IDE support so a bunch of the bugs will be false positives.
The repo isn't too big so I hope it's approachable, but a quick overview:
src/lib.rs: The main entry point that can diff parsers. It's used byfuzz/fuzz_targets/diff.rsandsrc/main.rs.src/ast.rs: The common AST representation.src/<parser>: Each supported parser has its own module with parsing and AST conversion code.mod.rs: Parser implementation and a bunch of filters that detect known bugs and cause the fuzzer to skip that bug without erroring out, so we can continue fuzzing without fixing all the bugs.convert.rs: Conversion from parser-specific AST to common representation.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
This project welcomes contributions and suggestions, just open an issue or pull request!
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.