diff mbox series

[bug#60225,v2,2/2] tests: records: Add a failing test for match-record.

Message ID 20221222021455.18632-2-attila@lendvai.name
State New
Headers show
Series [bug#60225,v2,1/2] records: match-record supports specifying a different variable name. | expand

Commit Message

Attila Lendvai Dec. 22, 2022, 2:14 a.m. UTC
* tests/records.scm ("match-record, syntactic interference"): New failing test.
---

i'm not sure what's going on here, but it looks like a bug to me.

i've experienced this in real code, and the error message was
not very helpful.

 tests/records.scm | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Comments

Ludovic Courtès Dec. 27, 2022, 10:53 p.m. UTC | #1
Attila Lendvai <attila@lendvai.name> skribis:

> * tests/records.scm ("match-record, syntactic interference"): New failing test.
> ---
>
> i'm not sure what's going on here, but it looks like a bug to me.

[...]

> +           (let (,@bindings)            ; but here it does interfere
> +             (match-record (foo (second 2)) <foo>
> +               (first second)
> +               (list first second))))))

This has to do with how macro “literals” are matched (info "(guile)
Syntax Rules"):

     A literal matches an input expression if the input expression is an
  identifier with the same name as the literal, and both are unbound(1).

     Although literals can be unbound, usually they are bound to allow
  them to be imported, exported, and renamed.  *Note Modules::, for more
  information on imports and exports.  In Guile there are a few standard
  auxiliary syntax definitions, as specified by R6RS and R7RS:

In the example above, the ‘let’ binding for ‘second’ was shadowing the
other ‘second’.

(I think this was recently discussed on guix-devel or something.)

Ludo’.
diff mbox series

Patch

diff --git a/tests/records.scm b/tests/records.scm
index b1203dfeb7..8a48e2fd07 100644
--- a/tests/records.scm
+++ b/tests/records.scm
@@ -561,4 +561,27 @@  (define-record-type* <foo> foo make-foo
             (make-fresh-user-module)))
     (lambda (key . args) key)))
 
+(test-expect-fail 1)
+(test-equal "match-record, syntactic interference"
+  '(1 2)
+  (begin
+    (define* (make-form #:optional (bindings '()))
+      `(begin
+         (use-modules (guix records))
+
+         (let ((first 42))              ; here it does not interfere
+           (define-record-type* <foo> foo make-foo
+             foo?
+             (first  foo-first (default 1))
+             (second foo-second))
+
+           (let (,@bindings)            ; but here it does interfere
+             (match-record (foo (second 2)) <foo>
+               (first second)
+               (list first second))))))
+    ;; This works fine.
+    (eval (make-form) (make-fresh-user-module))
+    ;; But this fails, although I think it shouldn't.
+    (eval (make-form '((second 43))) (make-fresh-user-module))))
+
 (test-end)