tree-sitter-rust
tree-sitter-rust copied to clipboard
[meta] cases where treesitter rejects code that rustc accepts
There are a a bunch of more cases where rustc compiles a file whereas treesitter-rustc throws an error, indicating a parsing failure in treesitter-rust.
Since I deem filing all these issues separately is not worth my time, here is a list of interesting test files:
the files can be found inside the rustc repo @ 0038c021031ce9f1ec2329469c8d85d0e681ef8f
Tested tree-sitter version was 0038c021031ce9f1ec2329469c8d85d0e681ef8f with a patched version of tree-sitter-rust 04352146022062c101b8ddd853adf17eadd8cf56 , as just adding both -git deps to a crate did not work out for me.
tests/ui/parser/keyword-union-as-identifier.rs
tests/ui/associated-type-bounds/type-alias.rs
tests/ui/traits/object/issue-33140-traitobject-crate.rs
tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs
tests/ui/type/type-alias-bounds.rs
tests/ui/associated-types/project-recursion-limit-non-fatal.rs
tests/pretty/ast-stmt-expr-attr.rs
tests/ui/codegen/subtyping-impacts-selection-1.rs
tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
tests/ui/implied-bounds/normalization-placeholder-leak.rs
tests/ui/macros/type-macros-hlist.rs
tests/ui/sized/coinductive-1-gat.rs
tests/ui/structs-enums/struct-aliases.rs
tests/ui/borrowck/alias-liveness/higher-ranked.rs
tests/rustdoc/where.rs
tests/pretty/issue-25031.rs
tests/ui/binding/use-uninit-match2.rs
tests/ui/const-generics/defaults/trait_objects.rs
tests/rustdoc/bounds.rs
tests/ui/const-generics/defaults/rp_impl_trait.rs
tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
tests/ui/or-patterns/or-patterns-syntactic-pass.rs
tests/ui/parser/trait-plusequal-splitting.rs
tests/ui/const-generics/defaults/auxiliary/const_defaulty.rs
tests/ui/underscore-method-after-integer.rs
tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-bare-trait-objects-const-trait-bounds.rs
tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs
tests/ui/structs-enums/numeric-fields.rs
tests/ui/parser/trait-item-with-defaultness-pass.rs
tests/ui/issues/issue-26186.rs
tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs
tests/rustdoc/inline_cross/auxiliary/default-generic-args.rs
tests/ui/associated-item/issue-105449.rs
tests/ui/where-clauses/issue-50825-1.rs
tests/rustdoc/higher-ranked-trait-bounds.rs
tests/ui/const-generics/defaults/repr-c-issue-82792.rs
tests/coverage/unicode.rs
tests/ui/nll/issue-112604-closure-output-normalize.rs
tests/ui/macros/user-defined-macro-rules.rs
tests/ui/traits/issue-72455.rs
tests/ui/macros/edition-macro-pats.rs
tests/ui/parser/extern-abi-raw-strings.rs
tests/ui/binding/match-bot.rs
tests/ui/issues/issue-50714.rs
tests/rustdoc/const-generics/const-generic-defaults.rs
tests/ui/implied-bounds/hrlt-implied-trait-bounds-roundtrip.rs
tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
tests/ui/feature-gates/feature-gate-trivial_bounds-lint.rs
tests/pretty/nested-item-vis-defaultness.rs
tests/ui/parser/parser-unicode-whitespace.rs
tests/ui/derives/derive-macro-const-default.rs
tests/ui/dropck/trivial-impl-bounds.rs
tests/ui/issues/issue-43692.rs
tests/ui/const-generics/arg-in-pat-3.rs
tests/ui/type_length_limit.rs
tests/ui/issues/issue-36116.rs
tests/ui/traits/issue-78632.rs
tests/ui/pattern/size-and-align.rs
tests/ui/impl-trait/different_where_bounds.rs
tests/ui/trivial-bounds/trivial-bounds-object.rs
tests/ui/auto-traits/pre-cfg.rs
tests/ui/const-generics/defaults/const-param-as-default-value.rs
tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs
tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs
tests/ui/empty-type-parameter-list.rs
tests/ui/structs-enums/simple-match-generic-tag.rs
tests/ui/lifetimes/elided-lifetime-in-param-pat.rs
tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
tests/ui/issues/issue-61475.rs
tests/ui/nll/empty-type-predicate-2.rs
tests/ui/rfcs/rfc-2008-non-exhaustive/structs_same_crate.rs
tests/ui/match/match-bot-panic.rs
tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs
tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs
tests/ui/issues/issue-22471.rs
tests/ui/const-generics/defaults/type-default-const-param-name.rs
tests/ui/attributes/issue-115264-pat-field.rs
tests/ui/issues/issue-34751.rs
tests/ui/half-open-range-patterns/pat-tuple-4.rs
tests/ui/codegen/mono-impossible.rs
tests/ui/binding/use-uninit-match.rs
tests/ui/higher-ranked/trait-bounds/issue-95230.rs
tests/ui/binding/match-join.rs
tests/ui/feature-gates/soft-syntax-gates-without-errors.rs
tests/ui/traits/issue-22110.rs
tests/ui/attrs-resolution.rs
tests/ui/nll/empty-type-predicate.rs
tests/ui/pattern/usefulness/integer-ranges/issue-117648-overlapping_range_endpoints-false-positive.rs
tests/ui/traits/object/lifetime-first.rs
tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs
tests/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs
tests/ui/parser/shebang/shebang-and-attrib.rs
tests/ui/destructuring-assignment/struct_destructure.rs
tests/ui/parser/issues/issue-88583-union-as-ident.rs
tests/ui/parser/foreign-ty-syntactic-pass.rs
tests/ui/parser/impls-nested-within-anon-consts-semantic.rs
tests/pretty/where-clauses.rs
tests/ui/parser/item-free-type-bounds-syntactic-pass.rs
tests/pretty/if-attr.rs
tests/ui/nll/assign-while-to-immutable.rs
tests/ui/const-generics/defaults/const-default.rs
tests/ui/const-generics/min_const_generics/type_and_const_defaults.rs
tests/ui/codegen/mono-impossible-2.rs
tests/ui/parser/shebang/valid-shebang.rs
tests/ui/issues/issue-37733.rs
tests/ui/binding/nested-matchs.rs
tests/ui/const-generics/min_const_generics/default_trait_param.rs
tests/ui/parser/shebang/sneaky-attrib.rs
tests/ui/parser/shebang/shebang-space.rs
tests/ui/traits/dyn-trait.rs
tests/ui/issues/issue-39089.rs
tests/ui/consts/const-labeled-break.rs
tests/ui/associated-types/issue-64855-2.rs
tests/ui/parser/shebang/shebang-empty.rs
tests/ui/error-codes/E0646.rs
Have fun :)
ooh this is awesome, thanks for the list.
update on tree-sitter-rust 0.24.0 vs rustc 919c40924373c248315a76618d8c52d39aed5e6e
compiler/rustc_baked_icu_data/src/data/macros.rs
library/alloctests/tests/slice.rs
library/core/src/num/libm.rs
library/coretests/tests/mem.rs
library/std/src/sys/pal/unix/thread_parking.rs
library/std/src/sys/pal/zkvm/abi.rs
library/std/src/sys/random/fuchsia.rs
src/doc/book/listings/ch20-advanced-features/listing-20-08/src/main.rs
src/doc/book/listings/ch20-advanced-features/listing-20-09/src/main.rs
src/tools/cargo/src/cargo/util/cpu.rs
src/tools/clippy/tests/ui/crashes/ice-7423.rs
src/tools/clippy/tests/ui/crashes/ice-9414.rs
src/tools/clippy/tests/ui/decimal_literal_representation.rs
src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
src/tools/clippy/tests/ui/single_match.rs
src/tools/miri/tests/pass/transmute_ptr.rs
src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/extern_block.rs
src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0004_file_shebang.rs
src/tools/rustfmt/tests/source/issue-2995.rs
src/tools/rustfmt/tests/source/issue-3639.rs
src/tools/rustfmt/tests/source/unsafe-mod.rs
src/tools/rustfmt/tests/target/unsafe-mod.rs
tests/coverage/holes.rs
tests/coverage/unicode.rs
tests/pretty/ast-stmt-expr-attr.rs
tests/pretty/if-attr.rs
tests/pretty/nested-item-vis-defaultness.rs
tests/pretty/where-clauses.rs
tests/rustdoc/bounds.rs
tests/rustdoc/extern/unsafe-extern-blocks.rs
tests/rustdoc/higher-ranked-trait-bounds.rs
tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs
tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
tests/rustdoc-json/fns/extern_safe.rs
tests/rustdoc-json/statics/extern.rs
tests/ui/associated-item/issue-105449.rs
tests/ui/associated-types/project-recursion-limit-non-fatal.rs
tests/ui/attributes/issue-115264-pat-field.rs
tests/ui/auto-traits/pre-cfg.rs
tests/ui/borrowck/alias-liveness/higher-ranked.rs
tests/ui/check-cfg/hrtb-crash.rs
tests/ui/codegen/mono-impossible-2.rs
tests/ui/codegen/mono-impossible.rs
tests/ui/codegen/subtyping-impacts-selection-1.rs
tests/ui/coherence/auxiliary/pr_review_132289_3_lib.rs
tests/ui/coherence/coherent-due-to-fulfill.rs
tests/ui/const-generics/arg-in-pat-3.rs
tests/ui/consts/const-labeled-break.rs
tests/ui/destructuring-assignment/struct_destructure.rs
tests/ui/dropck/trivial-impl-bounds.rs
tests/ui/error-codes/E0646.rs
tests/ui/feature-gates/feature-gate-trivial_bounds-lint.rs
tests/ui/feature-gates/soft-syntax-gates-without-errors.rs
tests/ui/generics/empty-generic-brackets-equiv.rs
tests/ui/implied-bounds/hrlt-implied-trait-bounds-roundtrip.rs
tests/ui/implied-bounds/normalization-placeholder-leak.rs
tests/ui/impl-trait/different_where_bounds.rs
tests/ui/impl-trait/precise-capturing/illegal-positions.rs
tests/ui/issues/issue-36116.rs
tests/ui/issues/issue-37733.rs
tests/ui/issues/issue-43692.rs
tests/ui/issues/issue-50714.rs
tests/ui/issues/issue-61475.rs
tests/ui/lifetimes/elided-lifetime-in-param-pat.rs
tests/ui/linking/cdylib-no-mangle.rs
tests/ui/linking/no-gc-encapsulation-symbols.rs
tests/ui/lint/unused/unused-field-in-pat-field.rs
tests/ui/macros/type-macros-hlist.rs
tests/ui/macros/user-defined-macro-rules.rs
tests/ui/nll/assign-while-to-immutable.rs
tests/ui/nll/empty-type-predicate-2.rs
tests/ui/nll/empty-type-predicate.rs
tests/ui/nll/issue-112604-closure-output-normalize.rs
tests/ui/or-patterns/or-patterns-syntactic-pass.rs
tests/ui/parser/extern-abi-raw-strings.rs
tests/ui/parser/foreign-ty-syntactic-pass.rs
tests/ui/parser/impls-nested-within-anon-consts-semantic.rs
tests/ui/parser/integer-literal-method-call-underscore.rs
tests/ui/parser/issues/issue-65041-empty-vis-matcher-in-trait.rs
tests/ui/parser/issues/issue-88583-union-as-ident.rs
tests/ui/parser/item-free-type-bounds-syntactic-pass.rs
tests/ui/parser/keyword-union-as-identifier.rs
tests/ui/parser/parser-unicode-whitespace.rs
tests/ui/parser/shebang/multiline-attrib.rs
tests/ui/parser/shebang/sneaky-attrib.rs
tests/ui/parser/trailing-plus-in-bounds.rs
tests/ui/parser/trait-item-with-defaultness-pass.rs
tests/ui/parser/trait-plusequal-splitting.rs
tests/ui/parser/ty-path-followed-by-single-colon.rs
tests/ui/parser/unsafe-foreign-mod.rs
tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.rs
tests/ui/pattern/issue-22546.rs
tests/ui/raw-ref-op/amp-raw-without-mut-const-is-a-normal-borrow.rs
tests/ui/resolve/non-macro-attrs-accepted.rs
tests/ui/rfcs/rfc-2008-non-exhaustive/structs_same_crate.rs
tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs
tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
tests/ui/sized/coinductive-1-gat.rs
tests/ui/structs-enums/numeric-fields.rs
tests/ui/structs-enums/struct-aliases.rs
tests/ui/traits/dyn-trait.rs
tests/ui/traits/issue-22110.rs
tests/ui/traits/issue-72455.rs
tests/ui/traits/issue-78632.rs
tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs
tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs
tests/ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs
tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs
tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs
tests/ui/traits/object/lifetime-first.rs
tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs
tests/ui/traits/winnowing/global-non-global-env-1.rs
tests/ui/traits/winnowing/global-non-global-env-2.rs
tests/ui/traits/winnowing/global-non-global-env-3.rs
tests/ui/traits/winnowing/global-non-global-env-4.rs
tests/ui/trivial-bounds/trivial-bounds-object.rs
tests/ui/unpretty/extern-static.rs
tests/ui/where-clauses/issue-50825-1.rs
also for comparison ran against the grammar of https://codeberg.org/grammar-orchard/tree-sitter-rust-orchard/commit/374744b32f4b46bb3a2030a975069b3ca664fbb5 // ( cc @wetneb )
compiler/rustc_baked_icu_data/src/data/macros.rs
library/alloctests/tests/slice.rs
src/tools/clippy/tests/ui/single_match.rs
src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0004_file_shebang.rs
src/tools/rustfmt/tests/source/issue-2995.rs
src/tools/rustfmt/tests/source/issue-3639.rs
src/tools/rustfmt/tests/source/unsafe-mod.rs
src/tools/rustfmt/tests/target/unsafe-mod.rs
tests/pretty/nested-item-vis-defaultness.rs
tests/ui/associated-item/issue-105449.rs
tests/ui/attributes/issue-115264-pat-field.rs
tests/ui/auto-traits/auto-is-contextual.rs
tests/ui/codegen/mono-impossible-2.rs
tests/ui/codegen/mono-impossible.rs
tests/ui/codegen/subtyping-impacts-selection-1.rs
tests/ui/coherence/coherent-due-to-fulfill.rs
tests/ui/const-generics/arg-in-pat-3.rs
tests/ui/consts/const-labeled-break.rs
tests/ui/destructuring-assignment/struct_destructure.rs
tests/ui/error-codes/E0646.rs
tests/ui/generics/empty-generic-brackets-equiv.rs
tests/ui/implied-bounds/hrlt-implied-trait-bounds-roundtrip.rs
tests/ui/implied-bounds/normalization-placeholder-leak.rs
tests/ui/impl-trait/different_where_bounds.rs
tests/ui/impl-trait/precise-capturing/illegal-positions.rs
tests/ui/issues/issue-36116.rs
tests/ui/issues/issue-37733.rs
tests/ui/issues/issue-43692.rs
tests/ui/issues/issue-50714.rs
tests/ui/issues/issue-61475.rs
tests/ui/lifetimes/elided-lifetime-in-param-pat.rs
tests/ui/lint/unused/unused-field-in-pat-field.rs
tests/ui/macros/type-macros-hlist.rs
tests/ui/macros/user-defined-macro-rules.rs
tests/ui/nll/assign-while-to-immutable.rs
tests/ui/parser/extern-abi-raw-strings.rs
tests/ui/parser/integer-literal-method-call-underscore.rs
tests/ui/parser/issues/issue-88583-union-as-ident.rs
tests/ui/parser/keyword-union-as-identifier.rs
tests/ui/parser/parser-unicode-whitespace.rs
tests/ui/parser/shebang/multiline-attrib.rs
tests/ui/parser/shebang/sneaky-attrib.rs
tests/ui/parser/trailing-plus-in-bounds.rs
tests/ui/parser/trait-item-with-defaultness-pass.rs
tests/ui/parser/trait-plusequal-splitting.rs
tests/ui/parser/ty-path-followed-by-single-colon.rs
tests/ui/pattern/issue-22546.rs
tests/ui/resolve/non-macro-attrs-accepted.rs
tests/ui/rfcs/rfc-2008-non-exhaustive/structs_same_crate.rs
tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-allowed.rs
tests/ui/sized/coinductive-1-gat.rs
tests/ui/structs-enums/numeric-fields.rs
tests/ui/structs-enums/struct-aliases.rs
tests/ui/traits/issue-22110.rs
tests/ui/traits/issue-78632.rs
tests/ui/traits/next-solver/alias-relate/alias_eq_dont_use_normalizes_to_if_substs_eq.rs
tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs
tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs
tests/ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs
tests/ui/traits/next-solver/unevaluated-const-impl-trait-ref.rs
tests/ui/traits/non_lifetime_binders/disqualifying-object-candidates.rs
tests/ui/traits/solver-cycles/inductive-canonical-cycle.rs
tests/ui/traits/winnowing/global-non-global-env-1.rs
tests/ui/traits/winnowing/global-non-global-env-2.rs
tests/ui/traits/winnowing/global-non-global-env-3.rs
tests/ui/traits/winnowing/global-non-global-env-4.rs
tests/ui/trivial-bounds/trivial-bounds-object.rs
tests/ui/where-clauses/issue-50825-1.rs
Thanks for the update @matthiaskrgr. Can you share which criterion you use to determine if rustc considers a file syntactically valid?
When I worked on minimizing those failures, I ran rustc --edition 2024 -Z unpretty=ast-tree path/to/file.rs and check that the exit code is 0. But this seems to have become a lot more lax with recent nightly versions, still accepting to parse files which are probably rejected at a later stage. For instance, that's the case of tests/rustdoc-ui/issues/ice-bare-dyn-106213.rs:
fn use_avx() -> dyn {
//~^ ERROR at least one trait is required for an object type
!( ident_error )
}
I'm happy with such files being rejected by the tree-sitter grammar, so it'd be very helpful to have a more conservative criterion to select files to benchmark the grammar on.
Running tree-sitter looks like this, I'm checking the tree-sitter error status with tree.root_node().has_errors()
let mut parser = tree_sitter::Parser::new();
parser
.set_language(&tree_sitter_rust_orchard::LANGUAGE.into())
.expect("Error loading Rust grammar");
let tree = parser.parse(&file_string, None).unwrap();
let root_node = tree.root_node();
let treesitter_failed_parsing = root_node.has_error();
For the rust part, I run
rustc --crate-type=lib --edition=2021 (should probably check 2024 actually now that I see that..) and just check the exit code
let tempdir = TempDir::new_in(global_tempdir_path, "rustc_testrunner_tmpdir").unwrap();
let tempdir_path = tempdir.path();
let file_string = std::fs::read_to_string(file).unwrap_or_default();
// treesitter parser
let mut parser = tree_sitter::Parser::new();
parser
.set_language(&tree_sitter_rust_orchard::LANGUAGE.into())
.expect("Error loading Rust grammar");
let tree = parser.parse(&file_string, None).unwrap();
let root_node = tree.root_node();
let treesitter_failed_parsing = root_node.has_error();
let mut rustc_command = Command::new(Executable::Rustc.path());
rustc_command
.arg("--crate-type=lib")
.arg(file)
.env("SYSROOT", &*SYSROOT_PATH)
// avoid error: the generated executable for the input file .. conflicts with the existing directory..
.arg(format!("-o{}/output", tempdir_path.display()))
.arg("--edition=2021")
.arg("-Zwrite-long-types-to-disk=no");
let rustc_output = prlimit_run_command(&mut rustc_command).unwrap();
let rustc_has_errors = !rustc_output.status.success();
if treesitter_failed_parsing && !rustc_has_errors && !file_string.contains("feature(") {
let ts = if treesitter_failed_parsing {
"error"
} else {
"ok "
};
let rs = if rustc_has_errors { "error" } else { "ok " };
eprintln!(
"\n\nPARSING DIFFERERENCE: {:?} treesitter: {}, rustc {}\n\n",
file.display(),
ts,
rs
);
eprintln!("{root_node}");
eprintln!("\n\n")
}