You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: rfcs/0001-syntax-tree-patterns.md
+2-10Lines changed: 2 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,5 @@
1
+
<!--lint disable maximum-line-length-->
2
+
1
3
- Feature Name: syntax-tree-patterns
2
4
- Start Date: 2019-03-12
3
5
- RFC PR: (leave this empty)
@@ -6,13 +8,11 @@
6
8
> Note: This project is part of my Master's Thesis (supervised by [@oli-obk](https://github.com/oli-obk))
7
9
8
10
# Summary
9
-
[summary]: #summary
10
11
11
12
Introduce a domain-specific language (similar to regular expressions) that allows to describe lints using *syntax tree patterns*.
12
13
13
14
14
15
# Motivation
15
-
[motivation]: #motivation
16
16
17
17
18
18
Finding parts of a syntax tree (AST, HIR, ...) that have certain properties (e.g. "*an if that has a block as its condition*") is a major task when writing lints. For non-trivial lints, it often requires nested pattern matching of AST / HIR nodes. For example, testing that an expression is a boolean literal requires the following checks:
@@ -68,7 +68,6 @@ A lot of complexity in writing lints currently seems to come from having to manu
68
68
While regular expressions are very useful when searching for patterns in flat character sequences, they cannot easily be applied to hierarchical data structures like syntax trees. This RFC therefore proposes a pattern matching system that is inspired by regular expressions and designed for hierarchical syntax trees.
This proposal adds a `pattern!` macro that can be used to specify a syntax tree pattern to search for. A simple pattern is shown below:
74
73
@@ -281,7 +280,6 @@ The following table gives an summary of the pattern syntax:
281
280
282
281
283
282
## The result type
284
-
[the-result-type]: #the-result-type
285
283
286
284
A lot of lints require checks that go beyond what the pattern syntax described above can express. For example, a lint might want to check whether a node was created as part of a macro expansion or whether there's no comment above a node. Another example would be a lint that wants to match two nodes that have the same value (as needed by lints like `almost_swapped`). Instead of allowing users to write these checks into the pattern directly (which might make patterns hard to read), the proposed solution allows users to assign names to parts of a pattern expression. When matching a pattern against a syntax tree node, the return value will contain references to all nodes that were matched by these named subpatterns. This is similar to capture groups in regular expressions.
287
285
@@ -372,7 +370,6 @@ As a "real-world" example, I re-implemented the `collapsible_if` lint using patt
Specifying lints using syntax tree patterns has a couple of advantages compared to the current approach of manually writing matching code. First, syntax tree patterns allow users to describe patterns in a simple and expressive way. This makes it easier to write new lints for both novices and experts and also makes reading / modifying existing lints simpler.
577
572
@@ -632,14 +627,12 @@ The issue of users not knowing about the *PatternTree* structure could be solved
632
627
For some simple cases (like the first example above), it might be possible to successfully mix Rust and pattern syntax. This space could be further explored in a future extension.
633
628
634
629
# Prior art
635
-
[prior-art]: #prior-art
636
630
637
631
The pattern syntax is heavily inspired by regular expressions (repetitions, alternatives, sequences, ...).
638
632
639
633
From what I've seen until now, other linters also implement lints that directly work on syntax tree data structures, just like clippy does currently. I would therefore consider the pattern syntax to be *new*, but please correct me if I'm wrong.
640
634
641
635
# Unresolved questions
642
-
[unresolved-questions]: #unresolved-questions
643
636
644
637
#### How to handle multiple matches?
645
638
@@ -657,7 +650,6 @@ This pattern matches arrays that end with at least one literal. Now given the ar
657
650
I haven't looked much into this yet because I don't know how relevant it is for most lints. The current implementation simply returns the first match it finds.
0 commit comments