Update to latest tree-sitter Rust parser on crates.io

pull/813/head
Wilfred Hughes 2025-01-25 17:10:30 +07:00
parent 8fcfdae7bd
commit 6f35d13fee
50 changed files with 19 additions and 181787 deletions

@ -14,7 +14,8 @@ effect since 0.46.
File detection now supports Windows-1252 encoded test (an extension of
ISO-8859-1), and is stricter about UTF-16 detection.
Updated to the latest tree-sitter parser for LaTeX, Make and YAML.
Updated to the latest tree-sitter parser for LaTeX, Make, Rust and
YAML.
## 0.62 (released 20th December 2024)

11
Cargo.lock generated

@ -294,6 +294,7 @@ dependencies = [
"tree-sitter-php",
"tree-sitter-python",
"tree-sitter-ruby",
"tree-sitter-rust",
"tree-sitter-scala",
"tree-sitter-toml-ng",
"tree-sitter-typescript",
@ -1194,6 +1195,16 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-rust"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4d64d449ca63e683c562c7743946a646671ca23947b9c925c0cfbe65051a4af"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-scala"
version = "0.23.3"

@ -98,6 +98,7 @@ tree-sitter-xml = "0.7.0"
tree-sitter-make = "1.1.1"
tree-sitter-yaml = "0.7.0"
encoding_rs = "0.8.35"
tree-sitter-rust = "0.23.2"
[dev-dependencies]
# assert_cmd 2.0.10 requires predicates 3.

@ -197,11 +197,6 @@ fn main() {
src_dir: "vendored_parsers/tree-sitter-racket-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-rust",
src_dir: "vendored_parsers/tree-sitter-rust-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-scheme",
src_dir: "vendored_parsers/tree-sitter-scheme-src",

@ -88,7 +88,6 @@ extern "C" {
fn tree_sitter_qmljs() -> ts::Language;
fn tree_sitter_r() -> ts::Language;
fn tree_sitter_racket() -> ts::Language;
fn tree_sitter_rust() -> ts::Language;
fn tree_sitter_scheme() -> ts::Language;
fn tree_sitter_smali() -> ts::Language;
fn tree_sitter_scss() -> ts::Language;
@ -917,16 +916,15 @@ pub(crate) fn from_language(language: guess::Language) -> TreeSitterConfig {
}
}
Rust => {
let language = unsafe { tree_sitter_rust() };
let language_fn = tree_sitter_rust::LANGUAGE;
let language = tree_sitter::Language::new(language_fn);
TreeSitterConfig {
language: language.clone(),
atom_nodes: vec!["char_literal", "string_literal"].into_iter().collect(),
delimiter_tokens: vec![("{", "}"), ("(", ")"), ("[", "]"), ("|", "|"), ("<", ">")],
highlight_query: ts::Query::new(
&language,
include_str!("../../vendored_parsers/highlights/rust.scm"),
)
.unwrap(),
highlight_query: ts::Query::new(&language, tree_sitter_rust::HIGHLIGHTS_QUERY)
.unwrap(),
sub_languages: vec![],
}
}

@ -1 +0,0 @@
../tree-sitter-rust/queries/highlights.scm

@ -1 +0,0 @@
tree-sitter-rust/src

@ -1,20 +0,0 @@
module.exports = {
'env': {
'commonjs': true,
'es2021': true,
},
'extends': 'google',
'overrides': [
],
'parserOptions': {
'ecmaVersion': 'latest',
'sourceType': 'module',
},
'rules': {
'indent': ['error', 2, {'SwitchCase': 1}],
'max-len': [
'error',
{'code': 120, 'ignoreComments': true, 'ignoreUrls': true, 'ignoreStrings': true},
],
},
};

@ -1,10 +0,0 @@
/src/** linguist-vendored
/examples/* linguist-vendored
src/grammar.json linguist-generated
src/node-types.json linguist-generated
src/parser.c linguist-generated
src/grammar.json -diff
src/node-types.json -diff
src/parser.c -diff

@ -1,37 +0,0 @@
name: CI
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- run: npm test
test_windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- run: npm run-script test-windows

@ -1,22 +0,0 @@
name: Fuzz Parser
on:
push:
paths:
- src/scanner.c
pull_request:
paths:
- src/scanner.c
workflow_dispatch:
jobs:
test:
name: Parser fuzzing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: vigoux/tree-sitter-fuzz-action@v1
with:
language: bash
external-scanner: src/scanner.c
time: 60

@ -1,19 +0,0 @@
name: Lint
on:
push:
branches:
- master
pull_request:
branches:
- "**"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install modules
run: npm install
- name: Run ESLint
run: npm run lint

@ -1,103 +0,0 @@
name: Release
on:
workflow_run:
workflows: ["CI"]
branches:
- master
types:
- completed
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get previous commit SHA
id: get_previous_commit
run: |
LATEST_TAG=$(git describe --tags --abbrev=0)
if [[ -z "$LATEST_TAG" ]]; then
echo "No tag found. Failing..."
exit 1
fi
echo "latest_tag=${LATEST_TAG#v}" >> "$GITHUB_ENV" # Remove 'v' prefix from the tag
- name: Check if version changed and is greater than the previous
id: version_check
run: |
# Compare the current version with the version from the previous commit
PREVIOUS_NPM_VERSION=${{ env.latest_tag }}
CURRENT_NPM_VERSION=$(jq -r '.version' package.json)
CURRENT_CARGO_VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml)
if [[ "$CURRENT_NPM_VERSION" != "$CURRENT_CARGO_VERSION" ]]; then # Cargo.toml and package.json versions must match
echo "Mismatch: NPM version ($CURRENT_NPM_VERSION) and Cargo.toml version ($CURRENT_CARGO_VERSION)"
echo "version_changed=false" >> "$GITHUB_ENV"
else
if [[ "$PREVIOUS_NPM_VERSION" == "$CURRENT_NPM_VERSION" ]]; then
echo "version_changed=" >> "$GITHUB_ENV"
else
IFS='.' read -ra PREVIOUS_VERSION_PARTS <<< "$PREVIOUS_NPM_VERSION"
IFS='.' read -ra CURRENT_VERSION_PARTS <<< "$CURRENT_NPM_VERSION"
VERSION_CHANGED=false
for i in "${!PREVIOUS_VERSION_PARTS[@]}"; do
if [[ ${CURRENT_VERSION_PARTS[i]} -gt ${PREVIOUS_VERSION_PARTS[i]} ]]; then
VERSION_CHANGED=true
break
elif [[ ${CURRENT_VERSION_PARTS[i]} -lt ${PREVIOUS_VERSION_PARTS[i]} ]]; then
break
fi
done
echo "version_changed=$VERSION_CHANGED" >> "$GITHUB_ENV"
echo "current_version=${CURRENT_NPM_VERSION}" >> "$GITHUB_ENV"
fi
fi
- name: Display result
run: |
echo "Version bump detected: ${{ env.version_changed }}"
- name: Fail if version is lower
if: env.version_changed == 'false'
run: exit 1
- name: Setup Node
if: env.version_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: 18
registry-url: "https://registry.npmjs.org"
- name: Publish to NPM
if: env.version_changed == 'true'
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish
- name: Setup Rust
if: env.version_changed == 'true'
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Publish to Crates.io
if: env.version_changed == 'true'
uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Tag versions
if: env.version_changed == 'true'
run: |
git checkout master
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git tag -d "v${{ env.current_version }}" || true
git push origin --delete "v${{ env.current_version }}" || true
git tag -a "v${{ env.current_version }}" -m "Version ${{ env.current_version }}"
git push origin "v${{ env.current_version }}"

@ -1,8 +0,0 @@
Cargo.lock
node_modules
build
*.log
package-lock.json
/examples
!examples/ast.rs
/target/

@ -1,6 +0,0 @@
/test
/examples
/build
/script
/target
bindings/rust

@ -1,24 +0,0 @@
[package]
name = "tree-sitter-rust"
description = "Rust grammar for tree-sitter"
version = "0.20.4"
authors = ["Max Brunsfeld <maxbrunsfeld@gmail.com>"]
license = "MIT"
readme = "bindings/rust/README.md"
keywords = ["incremental", "parsing", "rust"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/tree-sitter/tree-sitter-rust"
edition = "2021"
autoexamples = false
build = "bindings/rust/build.rs"
include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "~0.20.10"
[build-dependencies]
cc = "~1.0.82"

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2017 Maxim Sokolov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,39 +0,0 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterRust",
platforms: [.macOS(.v10_13), .iOS(.v11)],
products: [
.library(name: "TreeSitterRust", targets: ["TreeSitterRust"]),
],
dependencies: [],
targets: [
.target(name: "TreeSitterRust",
path: ".",
exclude: [
"binding.gyp",
"bindings",
"Cargo.toml",
"corpus",
"examples",
"grammar.js",
"LICENSE",
"Makefile",
"package.json",
"README.md",
"script",
"src/grammar.json",
"src/node-types.json",
],
sources: [
"src/parser.c",
"src/scanner.c",
],
resources: [
.copy("queries")
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")])
]
)

@ -1,38 +0,0 @@
# tree-sitter-rust
[![CI](https://github.com/tree-sitter/tree-sitter-c/actions/workflows/ci.yml/badge.svg)](https://github.com/tree-sitter/tree-sitter-c/actions/workflows/ci.yml)
Rust grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter)
## Features
- **Speed** — When initially parsing a file, `tree-sitter-rust` takes around twice
as long as Rustc's hand-coded parser.
```sh
$ wc -l examples/ast.rs
2157 examples/ast.rs
$ rustc -Z ast-json-noexpand -Z time-passes examples/ast.rs | head -n1
time: 0.007 parsing # (7 ms)
$ tree-sitter parse examples/ast.rs --quiet --time
examples/ast.rs 16 ms
```
But if you _edit_ the file after parsing it, this parser can generally _update_
the previous existing syntax tree to reflect your edit in less than a millisecond,
thanks to Tree-sitter's incremental parsing system.
## References
- [The Rust Grammar Reference](https://doc.rust-lang.org/grammar.html) — The grammar
reference provides chapters that formally define the language grammar.
- [The Rust Reference](https://doc.rust-lang.org/reference/) — While Rust does
not have a specification, the reference tries to describe its working in detail.
It tends to be out of date.
- [Keywords](https://doc.rust-lang.org/stable/book/appendix-01-keywords.html) and
[Operators and Symbols](https://doc.rust-lang.org/stable/book/appendix-02-operators.html).
- Archive of the outdated [Syntax Index](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/syntax-index.html)
that contains examples of all syntax in Rust cross-referenced with the section
of The Book that describes it.

@ -1,19 +0,0 @@
{
"targets": [
{
"target_name": "tree_sitter_rust_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"src/parser.c",
"src/scanner.c",
"bindings/node/binding.cc"
],
"cflags_c": [
"-std=c99",
]
}
]
}

@ -1,28 +0,0 @@
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_rust();
namespace {
NAN_METHOD(New) {}
void Init(Local<Object> exports, Local<Object> module) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_rust());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("rust").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_rust_binding, Init)
} // namespace

@ -1,19 +0,0 @@
try {
module.exports = require("../../build/Release/tree_sitter_rust_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_rust_binding");
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

@ -1,36 +0,0 @@
# tree-sitter-rust
This crate provides a Rust grammar for the [tree-sitter][] parsing library. To
use this crate, add it to the `[dependencies]` section of your `Cargo.toml`
file. (Note that you will probably also need to depend on the
[`tree-sitter`][tree-sitter crate] crate to use the parsed result in any useful
way.)
```toml
[dependencies]
tree-sitter = "0.20.10"
tree-sitter-rust = "0.20.4"
```
Typically, you will use the [language][language func] function to add this
grammar to a tree-sitter [Parser][], and then use the parser to parse some code:
```rust
let code = r#"
fn double(x: i32) -> i32 {
x * 2
}
"#;
let mut parser = Parser::new();
parser.set_language(tree_sitter_rust::language()).expect("Error loading Rust grammar");
let parsed = parser.parse(code, None);
```
If you have any questions, please reach out to us in the [tree-sitter
discussions] page.
[language func]: https://docs.rs/tree-sitter-rust/*/tree_sitter_rust/fn.language.html
[Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
[tree-sitter]: https://tree-sitter.github.io/
[tree-sitter crate]: https://crates.io/crates/tree-sitter
[tree-sitter discussions]: https://github.com/tree-sitter/tree-sitter/discussions

@ -1,16 +0,0 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut config = cc::Build::new();
config.include(&src_dir);
config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
let scanner_path = src_dir.join("scanner.c");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
config.file(&parser_path);
config.file(&scanner_path);
config.compile("parser-scanner");
}

@ -1,71 +0,0 @@
// ------------------------------------------------------------------------------------------------
// Copyright © 2021, tree-sitter-rust authors.
// See the LICENSE file in this repo for license details.
// ------------------------------------------------------------------------------------------------
//! This crate provides a Rust grammar for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this grammar to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! use tree_sitter::Parser;
//!
//! let code = r#"
//! fn double(x: i32) -> i32 {
//! x * 2
//! }
//! "#;
//! let mut parser = Parser::new();
//! parser.set_language(tree_sitter_rust::language()).expect("Error loading Rust grammar");
//! let parsed = parser.parse(code, None);
//! # let parsed = parsed.unwrap();
//! # let root = parsed.root_node();
//! # assert!(!root.has_error());
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::Language;
extern "C" {
fn tree_sitter_rust() -> Language;
}
/// Returns the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_rust() }
}
/// The source of the Rust tree-sitter grammar description.
pub const GRAMMAR: &str = include_str!("../../grammar.js");
/// The syntax highlighting query for this language.
pub const HIGHLIGHT_QUERY: &str = include_str!("../../queries/highlights.scm");
/// The injections query for this language.
pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
/// The symbol tagging query for this language.
pub const TAGGING_QUERY: &str = include_str!("../../queries/tags.scm");
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
#[cfg(test)]
mod tests {
#[test]
fn can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(super::language())
.expect("Error loading Rust grammar");
}
}

@ -1,16 +0,0 @@
#ifndef TREE_SITTER_RUST_H_
#define TREE_SITTER_RUST_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
extern TSLanguage *tree_sitter_rust();
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_RUST_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,50 +0,0 @@
{
"name": "tree-sitter-rust",
"version": "0.20.4",
"description": "Rust grammar for tree-sitter",
"main": "bindings/node",
"keywords": [
"parser",
"rust"
],
"repository": {
"type": "git",
"url": "https://github.com/tree-sitter/tree-sitter-rust.git"
},
"author": "Maxim Sokolov <maxim0xff@gmail.com> (https://github.com/MaximSokolov)",
"license": "MIT",
"dependencies": {
"nan": "^2.17.0"
},
"devDependencies": {
"eslint": "^8.47.0",
"eslint-config-google": "^0.14.0",
"tree-sitter-cli": "^0.20.8"
},
"scripts": {
"build": "tree-sitter generate && node-gyp build",
"build-wasm": "tree-sitter build-wasm",
"lint": "eslint grammar.js",
"parse": "tree-sitter parse",
"test": "tree-sitter test && script/parse-examples",
"test-windows": "tree-sitter test"
},
"tree-sitter": [
{
"scope": "source.rust",
"injection-regex": "rust",
"file-types": [
"rs"
],
"highlights": [
"queries/highlights.scm"
],
"injections": [
"queries/injections.scm"
],
"tags": [
"queries/tags.scm"
]
}
]
}

@ -1,155 +0,0 @@
; Identifier conventions
; Assume all-caps names are constants
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]+$'"))
; Assume that uppercase names in paths are types
((scoped_identifier
path: (identifier) @type)
(#match? @type "^[A-Z]"))
((scoped_identifier
path: (scoped_identifier
name: (identifier) @type))
(#match? @type "^[A-Z]"))
((scoped_type_identifier
path: (identifier) @type)
(#match? @type "^[A-Z]"))
((scoped_type_identifier
path: (scoped_identifier
name: (identifier) @type))
(#match? @type "^[A-Z]"))
; Assume other uppercase names are enum constructors
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
; Assume all qualified names in struct patterns are enum constructors. (They're
; either that, or struct names; highlighting both as constructors seems to be
; the less glaring choice of error, visually.)
(struct_pattern
type: (scoped_type_identifier
name: (type_identifier) @constructor))
; Function calls
(call_expression
function: (identifier) @function)
(call_expression
function: (field_expression
field: (field_identifier) @function.method))
(call_expression
function: (scoped_identifier
"::"
name: (identifier) @function))
(generic_function
function: (identifier) @function)
(generic_function
function: (scoped_identifier
name: (identifier) @function))
(generic_function
function: (field_expression
field: (field_identifier) @function.method))
(macro_invocation
macro: (identifier) @function.macro
"!" @function.macro)
; Function definitions
(function_item (identifier) @function)
(function_signature_item (identifier) @function)
; Other identifiers
(type_identifier) @type
(primitive_type) @type.builtin
(field_identifier) @property
(line_comment) @comment
(block_comment) @comment
"(" @punctuation.bracket
")" @punctuation.bracket
"[" @punctuation.bracket
"]" @punctuation.bracket
"{" @punctuation.bracket
"}" @punctuation.bracket
(type_arguments
"<" @punctuation.bracket
">" @punctuation.bracket)
(type_parameters
"<" @punctuation.bracket
">" @punctuation.bracket)
"::" @punctuation.delimiter
":" @punctuation.delimiter
"." @punctuation.delimiter
"," @punctuation.delimiter
";" @punctuation.delimiter
(parameter (identifier) @variable.parameter)
(lifetime (identifier) @label)
"as" @keyword
"async" @keyword
"await" @keyword
"break" @keyword
"const" @keyword
"continue" @keyword
"default" @keyword
"dyn" @keyword
"else" @keyword
"enum" @keyword
"extern" @keyword
"fn" @keyword
"for" @keyword
"if" @keyword
"impl" @keyword
"in" @keyword
"let" @keyword
"loop" @keyword
"macro_rules!" @keyword
"match" @keyword
"mod" @keyword
"move" @keyword
"pub" @keyword
"ref" @keyword
"return" @keyword
"static" @keyword
"struct" @keyword
"trait" @keyword
"type" @keyword
"union" @keyword
"unsafe" @keyword
"use" @keyword
"where" @keyword
"while" @keyword
(crate) @keyword
(mutable_specifier) @keyword
(use_list (self) @keyword)
(scoped_use_list (self) @keyword)
(scoped_identifier (self) @keyword)
(super) @keyword
(self) @variable.builtin
(char_literal) @string
(string_literal) @string
(raw_string_literal) @string
(boolean_literal) @constant.builtin
(integer_literal) @constant.builtin
(float_literal) @constant.builtin
(escape_sequence) @escape
(attribute_item) @attribute
(inner_attribute_item) @attribute
"*" @operator
"&" @operator
"'" @operator

@ -1,9 +0,0 @@
((macro_invocation
(token_tree) @injection.content)
(#set! injection.language "rust")
(#set! injection.include-children))
((macro_rule
(token_tree) @injection.content)
(#set! injection.language "rust")
(#set! injection.include-children))

@ -1,60 +0,0 @@
; ADT definitions
(struct_item
name: (type_identifier) @name) @definition.class
(enum_item
name: (type_identifier) @name) @definition.class
(union_item
name: (type_identifier) @name) @definition.class
; type aliases
(type_item
name: (type_identifier) @name) @definition.class
; method definitions
(declaration_list
(function_item
name: (identifier) @name)) @definition.method
; function definitions
(function_item
name: (identifier) @name) @definition.function
; trait definitions
(trait_item
name: (type_identifier) @name) @definition.interface
; module definitions
(mod_item
name: (identifier) @name) @definition.module
; macro definitions
(macro_definition
name: (identifier) @name) @definition.macro
; references
(call_expression
function: (identifier) @name) @reference.call
(call_expression
function: (field_expression
field: (field_identifier) @name)) @reference.call
(macro_invocation
macro: (identifier) @name) @reference.call
; implementations
(impl_item
trait: (type_identifier) @name) @reference.implementation
(impl_item
type: (type_identifier) @name
!trait) @reference.implementation

@ -1,21 +0,0 @@
#!/bin/bash
set -e
function checkout() {
repo=$1; url=$2; sha=$3
if [ ! -d "$repo" ]; then
git clone "https://github.com/$url" "$repo"
fi
pushd "$repo"
git fetch && git reset --hard "$sha"
popd
}
checkout examples/bitflags rust-lang-nursery/bitflags 7ec3fe2d7cafb7f185c5785006efac94b88f42f0
checkout examples/libc rust-lang/libc 8318a3ec1c1f13aab21d0a74ac9a7cf618bb2261
checkout examples/regex rust-lang/regex.git 991ae1a4c69cd81ecf989119b9205a3204088e83
checkout examples/serde serde-rs/serde.git 4e54aaf7963c3580cc50b56842949b0ce6b3a997
checkout examples/tokio tokio-rs/tokio 0490280d662f000aff674593cc9a4f69a1cd1171

@ -1 +0,0 @@
examples/tokio/examples/connect.rs

@ -1,20 +0,0 @@
#!/bin/bash
set -e
cd "$(dirname "$0")/.."
known_failures="$(cat script/known_failures.txt)"
tree-sitter parse -q \
'examples/**/*.rs' \
$(for file in $known_failures; do echo "!${file}"; done)
example_count=$(find examples -name '*.rs' | wc -l)
failure_count=$(wc -w <<< "$known_failures")
success_count=$(( $example_count - $failure_count ))
success_percent=$(bc -l <<< "100*${success_count}/${example_count}")
printf \
"Successfully parsed %d of %d example files (%.1f%%)\n" \
$success_count $example_count $success_percent

@ -1,3 +0,0 @@
#!/bin/bash
rustc -Z ast-json-noexpand $@ | jq .

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,186 +0,0 @@
#include <tree_sitter/parser.h>
#include <wctype.h>
enum TokenType {
STRING_CONTENT,
RAW_STRING_LITERAL,
FLOAT_LITERAL,
BLOCK_COMMENT,
};
void *tree_sitter_rust_external_scanner_create() { return NULL; }
void tree_sitter_rust_external_scanner_destroy(void *p) {}
void tree_sitter_rust_external_scanner_reset(void *p) {}
unsigned tree_sitter_rust_external_scanner_serialize(void *p, char *buffer) { return 0; }
void tree_sitter_rust_external_scanner_deserialize(void *p, const char *b, unsigned n) {}
static void advance(TSLexer *lexer) {
lexer->advance(lexer, false);
}
static bool is_num_char(int32_t c) {
return c == '_' || iswdigit(c);
}
bool tree_sitter_rust_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
if (valid_symbols[STRING_CONTENT] && !valid_symbols[FLOAT_LITERAL]) {
bool has_content = false;
for (;;) {
if (lexer->lookahead == '\"' || lexer->lookahead == '\\') {
break;
} else if (lexer->lookahead == 0) {
return false;
}
has_content = true;
advance(lexer);
}
lexer->result_symbol = STRING_CONTENT;
return has_content;
}
while (iswspace(lexer->lookahead)) lexer->advance(lexer, true);
if (
valid_symbols[RAW_STRING_LITERAL] &&
(lexer->lookahead == 'r' || lexer->lookahead == 'b')
) {
lexer->result_symbol = RAW_STRING_LITERAL;
if (lexer->lookahead == 'b') advance(lexer);
if (lexer->lookahead != 'r') return false;
advance(lexer);
unsigned opening_hash_count = 0;
while (lexer->lookahead == '#') {
advance(lexer);
opening_hash_count++;
}
if (lexer->lookahead != '"') return false;
advance(lexer);
for (;;) {
if (lexer->lookahead == 0) {
return false;
} else if (lexer->lookahead == '"') {
advance(lexer);
unsigned hash_count = 0;
while (lexer->lookahead == '#' && hash_count < opening_hash_count) {
advance(lexer);
hash_count++;
}
if (hash_count == opening_hash_count) {
return true;
}
} else {
advance(lexer);
}
}
}
if (valid_symbols[FLOAT_LITERAL] && iswdigit(lexer->lookahead)) {
lexer->result_symbol = FLOAT_LITERAL;
advance(lexer);
while (is_num_char(lexer->lookahead)) {
advance(lexer);
}
bool has_fraction = false, has_exponent = false;
if (lexer->lookahead == '.') {
has_fraction = true;
advance(lexer);
if (iswalpha(lexer->lookahead)) {
// The dot is followed by a letter: 1.max(2) => not a float but an integer
return false;
}
if (lexer->lookahead == '.') {
return false;
}
while (is_num_char(lexer->lookahead)) {
advance(lexer);
}
}
lexer->mark_end(lexer);
if (lexer->lookahead == 'e' || lexer->lookahead == 'E') {
has_exponent = true;
advance(lexer);
if (lexer->lookahead == '+' || lexer->lookahead == '-') {
advance(lexer);
}
if (!is_num_char(lexer->lookahead)) {
return true;
}
advance(lexer);
while (is_num_char(lexer->lookahead)) {
advance(lexer);
}
lexer->mark_end(lexer);
}
if (!has_exponent && !has_fraction) return false;
if (lexer->lookahead != 'u' && lexer->lookahead != 'i' && lexer->lookahead != 'f') {
return true;
}
advance(lexer);
if (!iswdigit(lexer->lookahead)) {
return true;
}
while (iswdigit(lexer->lookahead)) {
advance(lexer);
}
lexer->mark_end(lexer);
return true;
}
if (lexer->lookahead == '/') {
advance(lexer);
if (lexer->lookahead != '*') return false;
advance(lexer);
bool after_star = false;
unsigned nesting_depth = 1;
for (;;) {
switch (lexer->lookahead) {
case '\0':
return false;
case '*':
advance(lexer);
after_star = true;
break;
case '/':
if (after_star) {
advance(lexer);
after_star = false;
nesting_depth--;
if (nesting_depth == 0) {
lexer->result_symbol = BLOCK_COMMENT;
return true;
}
} else {
advance(lexer);
after_star = false;
if (lexer->lookahead == '*') {
nesting_depth++;
advance(lexer);
}
}
break;
default:
advance(lexer);
after_star = false;
break;
}
}
}
return false;
}

@ -1,224 +0,0 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSStateId;
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#define START_LEXER() \
bool result = false; \
bool skip = false; \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead; \
eof = lexer->eof(lexer);
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = (state_value) \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = (state_value), \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

@ -1,88 +0,0 @@
================================================================================
Async function
================================================================================
async fn abc() {}
async fn main() {
let x = futures.await?;
}
--------------------------------------------------------------------------------
(source_file
(function_item
(function_modifiers)
(identifier)
(parameters)
(block))
(function_item
(function_modifiers)
(identifier)
(parameters)
(block
(let_declaration
(identifier)
(try_expression
(await_expression
(identifier)))))))
================================================================================
Await expression
================================================================================
futures.await;
futures.await?;
futures.await?.await?;
futures.await?.function().await?;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(await_expression
(identifier)))
(expression_statement
(try_expression
(await_expression
(identifier))))
(expression_statement
(try_expression
(await_expression
(try_expression
(await_expression
(identifier))))))
(expression_statement
(try_expression
(await_expression
(call_expression
(field_expression
(try_expression
(await_expression
(identifier)))
(field_identifier))
(arguments))))))
================================================================================
Async Block
================================================================================
async {}
async { let x = 10; }
async move {}
--------------------------------------------------------------------------------
(source_file
(expression_statement
(async_block
(block)))
(expression_statement
(async_block
(block
(let_declaration
(identifier)
(integer_literal)))))
(expression_statement
(async_block
(block))))

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,193 +0,0 @@
================================================================================
Integer literals
================================================================================
0;
0___0;
123;
0usize;
123i32;
123u32;
123_u32;
0xff_u8;
0o70_i16;
0b1111_1111_1001_0000_i32;
1u128;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal))
(expression_statement
(integer_literal)))
================================================================================
Floating-point literals
================================================================================
123.123;
2.;
123.0f64;
0.1f64;
0.1f32;
12E+99_f64;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(float_literal))
(expression_statement
(float_literal))
(expression_statement
(float_literal))
(expression_statement
(float_literal))
(expression_statement
(float_literal))
(expression_statement
(float_literal)))
================================================================================
String literals
================================================================================
"";
"abc";
b"foo\nbar";
"foo\
bar";
"\"foo\"";
"/* foo bar */ foo bar";
"foo\x42\x43bar";
"foo \x42 \x43 bar";
--------------------------------------------------------------------------------
(source_file
(expression_statement
(string_literal))
(expression_statement
(string_literal))
(expression_statement
(string_literal
(escape_sequence)))
(expression_statement
(string_literal
(escape_sequence)))
(expression_statement
(string_literal
(escape_sequence)
(escape_sequence)))
(expression_statement
(string_literal))
(expression_statement
(string_literal
(escape_sequence)
(escape_sequence)))
(expression_statement
(string_literal
(escape_sequence)
(escape_sequence))))
================================================================================
Raw string literals
================================================================================
r#"abc"#; r##"ok"##;
r##"foo #"# bar"##;
r###"foo ##"## bar"###;
r######"foo ##### bar"######;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(raw_string_literal))
(expression_statement
(raw_string_literal))
(expression_statement
(raw_string_literal))
(expression_statement
(raw_string_literal))
(expression_statement
(raw_string_literal)))
================================================================================
Raw byte string literals
================================================================================
br#"abc"#;
br##"abc"##;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(raw_string_literal))
(expression_statement
(raw_string_literal)))
================================================================================
Character literals
================================================================================
'a';
'\'';
'\0';
b'x';
'\t';
'\xff';
'\\';
--------------------------------------------------------------------------------
(source_file
(expression_statement
(char_literal))
(expression_statement
(char_literal))
(expression_statement
(char_literal))
(expression_statement
(char_literal))
(expression_statement
(char_literal))
(expression_statement
(char_literal))
(expression_statement
(char_literal)))
================================================================================
Boolean literals
================================================================================
true;
false;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(boolean_literal))
(expression_statement
(boolean_literal)))

@ -1,257 +0,0 @@
================================================================================
Macro invocation - no arguments
================================================================================
a!();
b![];
c!{};
d::e!();
f::g::h!{};
--------------------------------------------------------------------------------
(source_file
(expression_statement
(macro_invocation
(identifier)
(token_tree)))
(expression_statement
(macro_invocation
(identifier)
(token_tree)))
(expression_statement
(macro_invocation
(identifier)
(token_tree)))
(expression_statement
(macro_invocation
(scoped_identifier
(identifier)
(identifier))
(token_tree)))
(expression_statement
(macro_invocation
(scoped_identifier
(scoped_identifier
(identifier)
(identifier))
(identifier))
(token_tree))))
================================================================================
Macro invocation - arbitrary tokens
================================================================================
a!(* a *);
a!(& a &);
a!(- a -);
a!(b + c + +);
a!('a'..='z');
a!('\u{0}'..='\u{2}');
a!('lifetime)
default!(a);
union!(a);
a!($);
a!($());
a!($ a $);
a!(${$([ a ])});
a!($a $a:ident $($a);*);
--------------------------------------------------------------------------------
(source_file
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier)
(identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(char_literal)
(char_literal))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(char_literal)
(char_literal))))
(macro_invocation
(identifier)
(token_tree
(identifier)))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree)))
(expression_statement
(macro_invocation
(identifier)
(token_tree (token_tree))))
(expression_statement
(macro_invocation
(identifier)
(token_tree (identifier))))
(expression_statement
(macro_invocation
(identifier)
(token_tree (token_tree (token_tree (token_tree (identifier)))))))
(expression_statement
(macro_invocation
(identifier)
(token_tree
(identifier)
(identifier)
(identifier)
(token_tree
(identifier))))))
================================================================================
Macro invocation with comments
================================================================================
ok! {
// one
/* two */
}
--------------------------------------------------------------------------------
(source_file
(macro_invocation
(identifier)
(token_tree
(line_comment)
(block_comment))))
================================================================================
Macro definition
================================================================================
macro_rules! say_hello {
() => (
println!("Hello!");
)
}
macro_rules! four {
() => {1 + 3};
}
macro_rules! foo {
(x => $e:expr) => (println!("mode X: {}", $e));
(y => $e:expr) => (println!("mode Y: {}", $e))
}
macro_rules! o_O {
(
$($x:expr; [ $( $y:expr ),* ]);*
) => {
$($($x + $e),*),*
}
}
macro_rules! zero_or_one {
($($e:expr),?) => {
$($e),?
};
}
--------------------------------------------------------------------------------
(source_file
(macro_definition
name: (identifier)
(macro_rule
left: (token_tree_pattern)
right: (token_tree
(identifier)
(token_tree
(string_literal)))))
(macro_definition
name: (identifier)
(macro_rule
left: (token_tree_pattern)
right: (token_tree
(integer_literal)
(integer_literal))))
(macro_definition
name: (identifier)
(macro_rule
left: (token_tree_pattern
(identifier)
(token_binding_pattern
name: (metavariable)
type: (fragment_specifier)))
right: (token_tree
(identifier)
(token_tree
(string_literal)
(metavariable))))
(macro_rule
left: (token_tree_pattern
(identifier)
(token_binding_pattern
name: (metavariable)
type: (fragment_specifier)))
right: (token_tree
(identifier)
(token_tree
(string_literal)
(metavariable)))))
(macro_definition
name: (identifier)
(macro_rule
left: (token_tree_pattern
(token_repetition_pattern
(token_binding_pattern
name: (metavariable)
type: (fragment_specifier))
(token_tree_pattern
(token_repetition_pattern
(token_binding_pattern
name: (metavariable)
type: (fragment_specifier))))))
right: (token_tree
(token_repetition
(token_repetition
(metavariable)
(metavariable))))))
(macro_definition
name: (identifier)
(macro_rule
left: (token_tree_pattern
(token_repetition_pattern
(token_binding_pattern
name: (metavariable)
type: (fragment_specifier))))
right: (token_tree
(token_repetition
(metavariable))))))

@ -1,469 +0,0 @@
================================================================================
Tuple struct patterns
================================================================================
match x {
Some(x) => "some",
std::None() => "none"
}
--------------------------------------------------------------------------------
(source_file
(expression_statement
(match_expression
(identifier)
(match_block
(match_arm
(match_pattern
(tuple_struct_pattern
(identifier)
(identifier)))
(string_literal))
(match_arm
(match_pattern
(tuple_struct_pattern
(scoped_identifier
(identifier)
(identifier))))
(string_literal))))))
================================================================================
Reference patterns
================================================================================
match x {
A(ref x) => x.0,
ref mut y => y,
& mut z => z,
}
--------------------------------------------------------------------------------
(source_file
(expression_statement
(match_expression
(identifier)
(match_block
(match_arm
(match_pattern
(tuple_struct_pattern
(identifier)
(ref_pattern
(identifier))))
(field_expression
(identifier)
(integer_literal)))
(match_arm
(match_pattern
(ref_pattern
(mut_pattern
(mutable_specifier)
(identifier))))
(identifier))
(match_arm
(match_pattern
(reference_pattern
(mutable_specifier)
(identifier)))
(identifier))))))
================================================================================
Struct patterns
================================================================================
match x {
Person{name, age} if age < 5 => ("toddler", name),
Person{name: adult_name, age: _} => ("adult", adult_name),
}
--------------------------------------------------------------------------------
(source_file
(expression_statement
(match_expression
(identifier)
(match_block
(match_arm
(match_pattern
(struct_pattern
(type_identifier)
(field_pattern
(shorthand_field_identifier))
(field_pattern
(shorthand_field_identifier)))
(binary_expression
(identifier)
(integer_literal)))
(tuple_expression
(string_literal)
(identifier)))
(match_arm
(match_pattern
(struct_pattern
(type_identifier)
(field_pattern
(field_identifier)
(identifier))
(field_pattern
(field_identifier))))
(tuple_expression
(string_literal)
(identifier)))))))
================================================================================
Ignored patterns
================================================================================
match x {
(a, ..) => a,
B(..) => c,
D::E{f: g, ..} => g
}
--------------------------------------------------------------------------------
(source_file
(expression_statement
(match_expression
(identifier)
(match_block
(match_arm
(match_pattern
(tuple_pattern
(identifier)
(remaining_field_pattern)))
(identifier))
(match_arm
(match_pattern
(tuple_struct_pattern
(identifier)
(remaining_field_pattern)))
(identifier))
(match_arm
(match_pattern
(struct_pattern
(scoped_type_identifier
(identifier)
(type_identifier))
(field_pattern
(field_identifier)
(identifier))
(remaining_field_pattern)))
(identifier))))))
================================================================================
Captured patterns
================================================================================
match x {
a @ A(_) | b @ B(..) => a,
a @ 1 ... 5 => a,
Some(1 ... 5) => a,
a @ b...c => a,
a @ b..=c => a,
}
--------------------------------------------------------------------------------
(source_file
(expression_statement
(match_expression
value: (identifier)
body: (match_block
(match_arm
pattern: (match_pattern
(or_pattern
(captured_pattern
(identifier)
(tuple_struct_pattern
type: (identifier)))
(captured_pattern
(identifier)
(tuple_struct_pattern
type: (identifier)
(remaining_field_pattern)))))
value: (identifier))
(match_arm
pattern: (match_pattern
(captured_pattern
(identifier)
(range_pattern
(integer_literal)
(integer_literal))))
value: (identifier))
(match_arm
pattern: (match_pattern
(tuple_struct_pattern
type: (identifier)
(range_pattern
(integer_literal)
(integer_literal))))
value: (identifier))
(match_arm
pattern: (match_pattern
(captured_pattern
(identifier)
(range_pattern
(identifier)
(identifier))))
value: (identifier))
(match_arm
pattern: (match_pattern
(captured_pattern
(identifier)
(range_pattern
(identifier)
(identifier))))
value: (identifier))))))
================================================================================
Or patterns
================================================================================
if let A(x) | B(x) = expr {
do_stuff_with(x);
}
while let A(x) | B(x) = expr {
do_stuff_with(x);
}
let Ok(index) | Err(index) = slice.binary_search(&x);
for ref a | b in c {}
let Ok(x) | Err(x) = binary_search(x);
for A | B | C in c {}
|(Ok(x) | Err(x))| expr();
let ref mut x @ (A | B | C);
fn foo((1 | 2 | 3): u8) {}
if let x!() | y!() = () {}
// Discomment after box pattern land on master
// let box (A | B | C);
// Not handled cause devs didn't got into agreement if should be acceptd or not
// |Ok(x) | Err(x)| expr();
--------------------------------------------------------------------------------
(source_file
(expression_statement
(if_expression
condition: (let_condition
pattern: (or_pattern
(tuple_struct_pattern
type: (identifier)
(identifier))
(tuple_struct_pattern
type: (identifier)
(identifier)))
value: (identifier))
consequence: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (arguments
(identifier)))))))
(expression_statement
(while_expression
condition: (let_condition
pattern: (or_pattern
(tuple_struct_pattern
type: (identifier)
(identifier))
(tuple_struct_pattern
type: (identifier)
(identifier)))
value: (identifier))
body: (block
(expression_statement
(call_expression
function: (identifier)
arguments: (arguments
(identifier)))))))
(let_declaration
pattern: (or_pattern
(tuple_struct_pattern
type: (identifier)
(identifier))
(tuple_struct_pattern
type: (identifier)
(identifier)))
value: (call_expression
function: (field_expression
value: (identifier)
field: (field_identifier))
arguments: (arguments
(reference_expression
value: (identifier)))))
(expression_statement
(for_expression
pattern: (or_pattern
(ref_pattern
(identifier))
(identifier))
value: (identifier)
body: (block)))
(let_declaration
pattern: (or_pattern
(tuple_struct_pattern
type: (identifier)
(identifier))
(tuple_struct_pattern
type: (identifier)
(identifier)))
value: (call_expression
function: (identifier)
arguments: (arguments
(identifier))))
(expression_statement
(for_expression
pattern: (or_pattern
(or_pattern
(identifier)
(identifier))
(identifier))
value: (identifier)
body: (block)))
(expression_statement
(closure_expression
parameters: (closure_parameters
(tuple_pattern
(or_pattern
(tuple_struct_pattern
type: (identifier)
(identifier))
(tuple_struct_pattern
type: (identifier)
(identifier)))))
body: (call_expression
function: (identifier)
arguments: (arguments))))
(let_declaration
pattern: (ref_pattern
(mut_pattern
(mutable_specifier)
(captured_pattern
(identifier)
(tuple_pattern
(or_pattern
(or_pattern
(identifier)
(identifier))
(identifier)))))))
(function_item
name: (identifier)
parameters: (parameters
(parameter
pattern: (tuple_pattern
(or_pattern
(or_pattern
(integer_literal)
(integer_literal))
(integer_literal)))
type: (primitive_type)))
body: (block))
(expression_statement
(if_expression
condition: (let_condition
pattern: (or_pattern
(macro_invocation
macro: (identifier)
(token_tree))
(macro_invocation
macro: (identifier)
(token_tree)))
value: (unit_expression))
consequence: (block)))
(line_comment)
(line_comment)
(line_comment)
(line_comment))
================================================================================
Inline const or Const blocks as pattern
================================================================================
fn foo(x: i32) {
const CUBE: i32 = 3.pow(3);
match x {
CUBE => println!("three cubed"),
_ => {}
}
}
fn foo(x: i32) {
match x {
const { 3.pow(3) } => println!("three cubed"),
_ => {}
}
}
--------------------------------------------------------------------------------
(source_file
(function_item
name: (identifier)
parameters: (parameters
(parameter
pattern: (identifier)
type: (primitive_type)))
body: (block
(const_item
name: (identifier)
type: (primitive_type)
value: (call_expression
function: (field_expression
value: (integer_literal)
field: (field_identifier))
arguments: (arguments
(integer_literal))))
(expression_statement
(match_expression
value: (identifier)
body: (match_block
(match_arm
pattern: (match_pattern
(identifier))
value: (macro_invocation
macro: (identifier)
(token_tree
(string_literal))))
(match_arm
pattern: (match_pattern)
value: (block)))))))
(function_item
name: (identifier)
parameters: (parameters
(parameter
pattern: (identifier)
type: (primitive_type)))
body: (block
(expression_statement
(match_expression
value: (identifier)
body: (match_block
(match_arm
pattern: (match_pattern
(const_block
body: (block
(call_expression
function: (field_expression
value: (integer_literal)
field: (field_identifier))
arguments: (arguments
(integer_literal))))))
value: (macro_invocation
macro: (identifier)
(token_tree
(string_literal))))
(match_arm
pattern: (match_pattern)
value: (block))))))))

@ -1,69 +0,0 @@
============================================
Block comments
============================================
/*
* Block comments
*/
/* Comment with asterisks **/
----
(source_file
(block_comment)
(block_comment))
============================================
Nested block comments
============================================
/* /* double nested */ */
// ---
/*/*/* triple nested */*/*/
// ---
/****
/****
nested with extra stars
****/
****/
// ---
----
(source_file
(block_comment)
(line_comment)
(block_comment)
(line_comment)
(block_comment)
(line_comment))
============================================
Line comments
============================================
// Comment
----
(source_file
(line_comment))
=====================================
Greek letters in identifiers
=====================================
const σ1 : Σ = 0;
const ψ_2 : Ψ = 1;
---
(source_file
(const_item (identifier) (type_identifier) (integer_literal))
(const_item (identifier) (type_identifier) (integer_literal)))

@ -1,384 +0,0 @@
================================================================================
The unit type
================================================================================
type A = ();
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(unit_type)))
================================================================================
Tuple types
================================================================================
type A = (i32, String);
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(tuple_type
(primitive_type)
(type_identifier))))
================================================================================
Reference types
================================================================================
type A = &B;
type C = &'a str;
type D = &'a mut str;
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(reference_type
(type_identifier)))
(type_item
(type_identifier)
(reference_type
(lifetime
(identifier))
(primitive_type)))
(type_item
(type_identifier)
(reference_type
(lifetime
(identifier))
(mutable_specifier)
(primitive_type))))
================================================================================
Raw pointer types
================================================================================
type A = *mut B;
type C = *const str;
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(pointer_type
(mutable_specifier)
(type_identifier)))
(type_item
(type_identifier)
(pointer_type
(primitive_type))))
================================================================================
Generic types
================================================================================
type A = B<C>;
type D = E<F, str>;
type G = H<'a, I>;
type J = H<K=L>;
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(type_identifier))))
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(type_identifier)
(primitive_type))))
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(lifetime
(identifier))
(type_identifier))))
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(type_binding
(type_identifier)
(type_identifier))))))
================================================================================
Scoped types
================================================================================
type A = B::C;
type D = E::F::G;
type H = I::J<K>;
type L = M<N>::O;
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(scoped_type_identifier
(identifier)
(type_identifier)))
(type_item
(type_identifier)
(scoped_type_identifier
(scoped_identifier
(identifier)
(identifier))
(type_identifier)))
(type_item
(type_identifier)
(generic_type
(scoped_type_identifier
(identifier)
(type_identifier))
(type_arguments
(type_identifier))))
(type_item
(type_identifier)
(scoped_type_identifier
(generic_type
(type_identifier)
(type_arguments
(type_identifier)))
(type_identifier))))
================================================================================
Array types
================================================================================
type A = [B; 4];
type C = &[D];
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(array_type
(type_identifier)
(integer_literal)))
(type_item
(type_identifier)
(reference_type
(array_type
(type_identifier)))))
================================================================================
Function types
================================================================================
fn high_order1(value: i32, f: fn(i32)) -> i32 {}
fn high_order2(value: i32, f: fn(i32) -> i32) -> i32 {
f(value)
}
fn high_order3(value: i32, f: &FnOnce(i32) -> i32) -> i32 {
f(value)
}
type F = for<'a, 'b> fn(x: &'a A, y: &'a mut B<'i, 't>,) -> C;
--------------------------------------------------------------------------------
(source_file
(function_item
(identifier)
(parameters
(parameter
(identifier)
(primitive_type))
(parameter
(identifier)
(function_type
(parameters
(primitive_type)))))
(primitive_type)
(block))
(function_item
(identifier)
(parameters
(parameter
(identifier)
(primitive_type))
(parameter
(identifier)
(function_type
(parameters
(primitive_type))
(primitive_type))))
(primitive_type)
(block
(call_expression
(identifier)
(arguments
(identifier)))))
(function_item
(identifier)
(parameters
(parameter
(identifier)
(primitive_type))
(parameter
(identifier)
(reference_type
(function_type
(type_identifier)
(parameters
(primitive_type))
(primitive_type)))))
(primitive_type)
(block
(call_expression
(identifier)
(arguments
(identifier)))))
(type_item
(type_identifier)
(function_type
(for_lifetimes
(lifetime
(identifier))
(lifetime
(identifier)))
(parameters
(parameter
(identifier)
(reference_type
(lifetime
(identifier))
(type_identifier)))
(parameter
(identifier)
(reference_type
(lifetime
(identifier))
(mutable_specifier)
(generic_type
(type_identifier)
(type_arguments
(lifetime
(identifier))
(lifetime
(identifier)))))))
(type_identifier))))
================================================================================
Unsafe and extern function types
================================================================================
type a = extern "C" fn(*mut c_void);
type b = unsafe extern "C" fn() -> *mut c_void;
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(function_type
(function_modifiers
(extern_modifier
(string_literal)))
(parameters
(pointer_type
(mutable_specifier)
(type_identifier)))))
(type_item
(type_identifier)
(function_type
(function_modifiers
(extern_modifier
(string_literal)))
(parameters)
(pointer_type
(mutable_specifier)
(type_identifier)))))
================================================================================
Trait objects
================================================================================
type a = Box<Something + 'a>;
type b = Rc<dyn Something>;
type c = A<&dyn Fn(&B) -> C>;
--------------------------------------------------------------------------------
(source_file
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(bounded_type
(type_identifier)
(lifetime
(identifier))))))
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(dynamic_type
(type_identifier)))))
(type_item
(type_identifier)
(generic_type
(type_identifier)
(type_arguments
(reference_type
(dynamic_type
(function_type
(type_identifier)
(parameters
(reference_type
(type_identifier)))
(type_identifier))))))))
================================================================================
Type cast expressions with generics
================================================================================
a as B<C>;
d as *mut E<<F as E>::G>;
--------------------------------------------------------------------------------
(source_file
(expression_statement
(type_cast_expression
(identifier)
(generic_type
(type_identifier)
(type_arguments
(type_identifier)))))
(expression_statement
(type_cast_expression
(identifier)
(pointer_type
(mutable_specifier)
(generic_type
(type_identifier)
(type_arguments
(scoped_type_identifier
(bracketed_type
(qualified_type
(type_identifier)
(type_identifier)))
(type_identifier))))))))