Skip to content

Commit 463d1cb

Browse files
authored
Fix single-clause-match-to-match-define conflicts (#465)
Closes #464.
1 parent 151ef6e commit 463d1cb

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

default-recommendations/match-shortcuts-test.rkt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,36 @@ test: "single-clause match expressions inside cond can be replaced with match-de
8888
------------------------------
8989

9090

91+
test: "single-clause match not migratable when pattern bindings conflict with surrounding context"
92+
------------------------------
93+
(define (foo x)
94+
(define a 42)
95+
(match x
96+
[(list a b c) a]))
97+
------------------------------
98+
99+
100+
test: "single-clause match not migratable when pattern would bind subject expression"
101+
------------------------------
102+
(define (foo x)
103+
(match x
104+
[(list x) x]))
105+
------------------------------
106+
107+
108+
test: "single-clause match still migratable when pattern bindings shadow surrounding context"
109+
------------------------------
110+
(define (foo x a)
111+
(match x
112+
[(list a b c) a]))
113+
------------------------------
114+
------------------------------
115+
(define (foo x a)
116+
(match-define (list a b c) x)
117+
a)
118+
------------------------------
119+
120+
91121
test: "match patterns using ? with a lambda can be simplified with #:when clauses"
92122
------------------------------
93123
(define (foo x)

default-recommendations/match-shortcuts.rkt

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
(require racket/list
1313
racket/match
1414
racket/set
15-
racket/stream
1615
resyntax/base
1716
resyntax/default-recommendations/private/lambda-by-any-name
1817
resyntax/default-recommendations/private/syntax-identifier-sets
1918
resyntax/private/syntax-traversal
20-
resyntax/private/logger
21-
syntax/parse)
19+
syntax/parse
20+
syntax/strip-context)
2221

2322

2423
(module+ test
@@ -31,7 +30,7 @@
3130

3231
(define-syntax-class single-clause-match
3332
#:literals (match)
34-
#:attributes (match-pattern [as-definition-context-body 1])
33+
#:attributes (match-pattern subject [body 1] [as-definition-context-body 1])
3534

3635
(pattern (match subject [match-pattern body ...])
3736
#:with definition #'(match-define match-pattern subject)
@@ -43,12 +42,26 @@
4342
#:description "This `match` expression can be simplified using `match-define`."
4443
#:literals (match)
4544
(~seq body-before ... match-expression:single-clause-match)
46-
#:when (set-empty? (set-intersect (syntax-bound-identifiers #'(body-before ...))
47-
(syntax-bound-identifiers #'match-expression.match-pattern)))
48-
#:with (new-body ...) (if (empty? (attribute body-before))
49-
(attribute match-expression.as-definition-context-body)
50-
#'(~focus-replacement-on
51-
(match-expression.as-definition-context-body ...)))
45+
46+
#:do
47+
[(define pattern-ids
48+
(syntax-bound-identifiers (attribute match-expression.match-pattern)))
49+
(define pattern-ids-in-surrounding-context
50+
(syntax-bound-identifiers
51+
(replace-context (attribute match-expression) (attribute match-expression.match-pattern))))
52+
(define body-ids (syntax-bound-identifiers #'(body-before ... match-expression.subject)))
53+
(define subject-ids-in-body-context
54+
(syntax-bound-identifiers
55+
(replace-context
56+
(first (attribute match-expression.body)) (attribute match-expression.subject))))]
57+
#:when (set-empty? (set-intersect pattern-ids-in-surrounding-context body-ids))
58+
#:when (set-empty? (set-intersect pattern-ids subject-ids-in-body-context))
59+
#:with (new-body ...)
60+
(if (empty? (attribute body-before))
61+
(attribute match-expression.as-definition-context-body)
62+
#'(~focus-replacement-on
63+
(match-expression.as-definition-context-body ...)))
64+
5265
(body-before ... new-body ...))
5366

5467

@@ -144,5 +157,5 @@
144157

145158

146159
(define-refactoring-suite match-shortcuts
147-
#:rules (predicate-pattern-with-lambda-to-when
148-
single-clause-match-to-match-define))
160+
#:rules (predicate-pattern-with-lambda-to-when
161+
single-clause-match-to-match-define))

0 commit comments

Comments
 (0)